Day 25
authorGreg Burri <greg.burri@gmail.com>
Mon, 25 Dec 2017 12:32:37 +0000 (13:32 +0100)
committerGreg Burri <greg.burri@gmail.com>
Mon, 25 Dec 2017 12:32:37 +0000 (13:32 +0100)
AdventOfCode2017/AdventOfCode2017.fsproj
AdventOfCode2017/Day25.fs [new file with mode: 0644]
AdventOfCode2017/Program.fs
Tests/Day25 tests.fs [new file with mode: 0644]
Tests/Tests.fsproj

index e568040..852dc74 100644 (file)
@@ -25,7 +25,7 @@
     <PlatformTarget>AnyCPU</PlatformTarget>
     <DocumentationFile>bin\$(Configuration)\$(AssemblyName).XML</DocumentationFile>
     <Prefer32Bit>true</Prefer32Bit>
-    <StartArguments>24</StartArguments>
+    <StartArguments>25</StartArguments>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>pdbonly</DebugType>
@@ -37,7 +37,7 @@
     <PlatformTarget>AnyCPU</PlatformTarget>
     <DocumentationFile>bin\$(Configuration)\$(AssemblyName).XML</DocumentationFile>
     <Prefer32Bit>true</Prefer32Bit>
-    <StartArguments>24</StartArguments>
+    <StartArguments>25</StartArguments>
   </PropertyGroup>
   <PropertyGroup>
     <MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
@@ -83,6 +83,7 @@
     <Compile Include="Day22.fs" />
     <Compile Include="Day23.fs" />
     <Compile Include="Day24.fs" />
+    <Compile Include="Day25.fs" />
     <Compile Include="Program.fs" />
     <None Include="App.config" />
     <Content Include="Data\day01.input">
     <Content Include="Data\day24.input">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
+    <Content Include="Data\day25.input">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
     <Content Include="packages.config" />
   </ItemGroup>
   <ItemGroup>
diff --git a/AdventOfCode2017/Day25.fs b/AdventOfCode2017/Day25.fs
new file mode 100644 (file)
index 0000000..373265c
--- /dev/null
@@ -0,0 +1,38 @@
+module AdventOfCode2017.Day25
+
+let readMove (str : string) = if str = "right" then 1 else -1
+
+type State =
+    {
+        Values : int[]
+        Moves : int[] // -1: left, +1: right.
+        NextState : char[]
+    }
+
+let split (str : string) (chars : char[]) = str.Split (chars, System.StringSplitOptions.RemoveEmptyEntries)
+
+let parseInput (lines : string[]) : Map<char, State> * char * int =
+    let firstState = (split lines.[0] [| ' '; '.' |]).[3] |> char
+    let nbSteps = lines.[1].Split(' ').[5] |> int
+
+    [
+        for i = 0 to (lines.Length - 2) / 9 - 1 do
+            let lineNum = i * 10 + 3
+            let name = (split lines.[lineNum] [| ' '; ':' |]).[2] |> char
+            let state =
+                {
+                    Values = [| (split lines.[lineNum + 2] [| ' '; '.' |]).[4] |> int; (split lines.[lineNum + 6] [| ' '; '.' |]).[4] |> int |]
+                    Moves = [| (split lines.[lineNum + 3] [| ' '; '.' |]).[6] |> readMove; (split lines.[lineNum + 7] [| ' '; '.' |]).[6] |> readMove |]
+                    NextState = [| (split lines.[lineNum + 4] [| ' '; '.' |]).[4] |> char; (split lines.[lineNum + 8] [| ' '; '.' |]).[4] |> char |]
+                }
+            yield name, state
+    ] |> Map.ofList, firstState, nbSteps
+
+let checksum (states : Map<char, State>, firstState : char, nbSteps : int) : int =
+    let next (tape : Set<int>) (cursor : int) (stateName : char) : Set<int> * int * char =
+        let state = states |> Map.find stateName
+        let v = if tape |> Set.contains cursor then 1 else 0
+        (tape |> if state.Values.[v] = 1 then Set.add cursor else Set.remove cursor), cursor + state.Moves.[v], state.NextState.[v]
+
+    let tape, _, _ = [ 1 .. nbSteps ] |> List.fold (fun (tape, cursor, state) _ -> next tape cursor state) (Set.empty, 0, firstState)
+    tape |> Set.count
\ No newline at end of file
index 65f1fbf..f5c32c3 100644 (file)
@@ -109,6 +109,10 @@ let day24 () =
     let bridges = Day24.bridges input
     sprintf "part1 = %A, part2 = %A" (Day24.maxBridge bridges) (Day24.longestBridge bridges)
 
+let day25 () =
+    let input = File.ReadAllLines "Data/day25.input" |> Day25.parseInput
+    sprintf "part1 = %A, part2 = %A" (Day25.checksum input) ()
+
 let doDay (n : int) =
     let sw = Diagnostics.Stopwatch ()
     sw.Start ()
@@ -138,6 +142,7 @@ let doDay (n : int) =
         | 22 -> day22 ()
         | 23 -> day23 ()
         | 24 -> day24 ()
+        | 25 -> day25 ()
         | _ -> raise <| NotImplementedException ()
     printfn "Result of day %i: %s (time : %i ms)" n result sw.ElapsedMilliseconds
 
diff --git a/Tests/Day25 tests.fs b/Tests/Day25 tests.fs
new file mode 100644 (file)
index 0000000..2cca89a
--- /dev/null
@@ -0,0 +1,43 @@
+namespace AdventOfCode2017.Tests
+
+open System
+open Xunit
+open Xunit.Abstractions
+open Swensen.Unquote
+
+open AdventOfCode2017
+
+type ``Day25 tests`` (output : ITestOutputHelper) =
+
+    [<Fact>]
+    let ``(Part1) From web page`` () =
+        let input =
+            [|
+                "Begin in state A."
+                "Perform a diagnostic checksum after 6 steps."
+                ""
+                "In state A:"
+                "  If the current value is 0:"
+                "    - Write the value 1."
+                "    - Move one slot to the right."
+                "    - Continue with state B."
+                "  If the current value is 1:"
+                "    - Write the value 0."
+                "    - Move one slot to the left."
+                "    - Continue with state B."
+                ""
+                "In state B:"
+                "  If the current value is 0:"
+                "    - Write the value 1."
+                "    - Move one slot to the left."
+                "    - Continue with state A."
+                "  If the current value is 1:"
+                "    - Write the value 1."
+                "    - Move one slot to the right."
+                "    - Continue with state A."
+            |] |> Day25.parseInput
+        Day25.checksum input =! 3
+
+    [<Fact>]
+    let ``(Part2) From web page`` () =
+        ()
\ No newline at end of file
index 31314ef..16f4250 100644 (file)
@@ -78,6 +78,7 @@
     <Compile Include="Day21 tests.fs" />
     <Compile Include="Day22 tests.fs" />
     <Compile Include="Day24 tests.fs" />
+    <Compile Include="Day25 tests.fs" />
     <Content Include="App.config" />
     <Content Include="packages.config" />
   </ItemGroup>