<PlatformTarget>AnyCPU</PlatformTarget>
<DocumentationFile>bin\$(Configuration)\$(AssemblyName).XML</DocumentationFile>
<Prefer32Bit>true</Prefer32Bit>
- <StartArguments>21</StartArguments>
+ <StartArguments>22</StartArguments>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<DocumentationFile>bin\$(Configuration)\$(AssemblyName).XML</DocumentationFile>
<Prefer32Bit>true</Prefer32Bit>
- <StartArguments>21</StartArguments>
+ <StartArguments>22</StartArguments>
</PropertyGroup>
<PropertyGroup>
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
module AdventOfCode2017.Day22
-type M = Set<int * int>
+type CellState = Weakened | Infected | Flagged | Clean
-let parseInput (lines : string[]) : M =
- (*for i = 0 to lines.Length do
- for*)
- Set.empty
+// We dont use a 'Map' because the part 2 is too slow with it: ~1 min instead of 8 s.
+type M = System.Collections.Generic.Dictionary<int * int, CellState>
+let parseInput (lines : string[]) : M =
+ let m = M ()
+ for y = 0 to lines.Length - 1 do
+ for x = 0 to lines.[y].Length - 1 do
+ if lines.[y].[x] = '#' then
+ m.Add ((x - lines.[y].Length / 2, -y + lines.Length / 2), Infected)
+ m
-let infection (m : M) : int =
+let reverse (dx, dy) = -dx, -dy
+let turnRight = function 1, 0 -> 0, -1 | 0, 1 -> 1, 0 | -1, 0 -> 0, 1 | _ -> -1, 0
+let turnLeft = turnRight >> reverse
- let rec burst (i, j) (di, dj) n m =
+let infection (rule : CellState -> CellState * ((int * int) -> (int * int))) (nbIterations : int) (m : M) : int =
+ let rec burst (x, y) d n becomeInfected =
if n = 0 then
- ()
+ becomeInfected
else
- burst (i, j) (di, dj) (n - 1) m
+ let nextState, f = match m.TryGetValue ((x, y)) with true, state -> rule state | _ -> rule Clean
+ let dx, dy = f d
+ if nextState = Clean then
+ m.Remove (x, y) |> ignore
+ else
+ m.[(x, y)] <- nextState
+ burst (x + dx, y + dy) (dx, dy) (n - 1) (if nextState = Infected then becomeInfected + 1 else becomeInfected)
+
+ burst (0, 0) (0, 1) nbIterations 0
- 23
+let infection1 (m : M) =
+ infection (
+ function
+ | Infected -> Clean, turnRight
+ | _ -> Infected, turnLeft
+ ) 10_000 m
+let infection2 (m : M) =
+ infection (
+ function
+ | Weakened -> Infected, id
+ | Infected -> Flagged, turnRight
+ | Flagged -> Clean, reverse
+ | Clean -> Weakened, turnLeft
+ ) 10_000_000 m
\ No newline at end of file