Day 10
authorGreg Burri <greg.burri@gmail.com>
Sun, 10 Dec 2017 20:40:31 +0000 (21:40 +0100)
committerGreg Burri <greg.burri@gmail.com>
Sun, 10 Dec 2017 20:40:31 +0000 (21:40 +0100)
AdventOfCode2017/AdventOfCode2017.fsproj
AdventOfCode2017/Day10.fs [new file with mode: 0644]
AdventOfCode2017/Day9.fs
AdventOfCode2017/Program.fs
Tests/Day10 tests.fs [new file with mode: 0644]
Tests/Tests.fsproj

index d8c9d47..6aa72c3 100644 (file)
@@ -25,7 +25,7 @@
     <PlatformTarget>AnyCPU</PlatformTarget>
     <DocumentationFile>bin\$(Configuration)\$(AssemblyName).XML</DocumentationFile>
     <Prefer32Bit>true</Prefer32Bit>
-    <StartArguments>9</StartArguments>
+    <StartArguments>10</StartArguments>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>pdbonly</DebugType>
@@ -65,6 +65,7 @@
     <Compile Include="Day7.fs" />
     <Compile Include="Day8.fs" />
     <Compile Include="Day9.fs" />
+    <Compile Include="Day10.fs" />
     <Compile Include="Program.fs" />
     <None Include="App.config" />
     <None Include="Data\day1.input">
@@ -91,6 +92,9 @@
     <None Include="Data\day9.input">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </None>
+    <None Include="Data\day10.input">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
     <Content Include="packages.config" />
   </ItemGroup>
   <ItemGroup>
diff --git a/AdventOfCode2017/Day10.fs b/AdventOfCode2017/Day10.fs
new file mode 100644 (file)
index 0000000..2383dee
--- /dev/null
@@ -0,0 +1,25 @@
+module AdventOfCode2017.Day10
+
+let knotHash (nbRounds : int) (reduce : int[] -> string) (lengths : int list) (size : int) =
+    let state = Array.init size id
+    let mutable current, skipSize = 0, 0
+
+    let swap i j =
+        let tmp = state.[i]
+        state.[i] <- state.[j]
+        state.[j] <- tmp
+
+    for _r = 1 to nbRounds do
+        for l in lengths do
+            for i = current to current + l / 2 - 1 do
+                swap (i % state.Length) ((2 * current + l - 1 - i) % state.Length)
+            current <- current + l + skipSize
+            skipSize <- skipSize + 1
+
+    reduce state
+
+let knotHash1 (str : string) =
+    knotHash 1 (fun s -> s.[0] * s.[1] |> string) (str.Split ',' |> List.ofArray |> List.map int)
+
+let knotHash2 (str : string) =
+    knotHash 64 (fun s -> s |> Array.chunkBySize 16 |> Array.map (Array.reduce (^^^) >> sprintf "%02x") |> Array.reduce (+)) (List.append (str |> List.ofSeq |> List.map int) [ 17; 31; 73; 47; 23 ]) 256
\ No newline at end of file
index eba06af..0931607 100644 (file)
@@ -8,6 +8,6 @@ let score (input : string) =
         | '<' :: tail when not gb -> next l lSum true gbSize tail
         | '!' :: _ :: tail when gb -> next l lSum gb gbSize tail
         | '>' :: tail when gb -> next l lSum false gbSize tail
-        | a :: tail -> next l lSum gb (gbSize + if gb then 1 else 0) tail
+        | _ :: tail -> next l lSum gb (gbSize + if gb then 1 else 0) tail
         | [] -> lSum, gbSize
     List.ofSeq input |> next 1 0 false 0
\ No newline at end of file
index a3d56fb..f26861b 100644 (file)
@@ -43,6 +43,10 @@ let day9 () =
     let part1, part2 = Day9.score input
     sprintf "part1 = %A, part2 = %A" part1 part2
 
+let day10 () =
+    let input = "83,0,193,1,254,237,187,40,88,27,2,255,149,29,42,100"
+    sprintf "part1 = %A, part2 = %A" (Day10.knotHash1 input 256) (Day10.knotHash2 input)
+
 let doDay (n : int) =
     let sw = Diagnostics.Stopwatch ()
     sw.Start ()
@@ -57,6 +61,7 @@ let doDay (n : int) =
         | 7 -> day7 ()
         | 8 -> day8 ()
         | 9 -> day9 ()
+        | 10 -> day10 ()
         | _ -> raise <| NotImplementedException ()
     printfn "Result of day %i: %s (time : %i ms)" n result sw.ElapsedMilliseconds
 
diff --git a/Tests/Day10 tests.fs b/Tests/Day10 tests.fs
new file mode 100644 (file)
index 0000000..c14d8a6
--- /dev/null
@@ -0,0 +1,21 @@
+namespace AdventOfCode2017.Tests
+
+open Xunit
+open Xunit.Abstractions
+open Swensen.Unquote
+
+open AdventOfCode2017
+
+type ``Day10 tests`` (output : ITestOutputHelper) =
+
+    [<Fact>]
+    let ``(Part1) From web page`` () =
+        let input = "3,4,1,5"
+        Day10.knotHash1 input 5 =! "12"
+
+    [<Fact>]
+    let ``(Part2) From web page`` () =
+        Day10.knotHash2 "" =! "a2582a3a0e66e6e86e3812dcb672a272"
+        Day10.knotHash2 "AoC 2017" =! "33efeb34ea91902bb2f59c9920caa6cd"
+        Day10.knotHash2 "1,2,3" =! "3efbe78a8d82f29979031a4aa0b16a9d"
+        Day10.knotHash2 "1,2,4" =! "63960835bcdc130f0b66d7ff4f6a5a8e"
\ No newline at end of file
index 0bbea9f..aec44f8 100644 (file)
@@ -64,6 +64,7 @@
     <Compile Include="Day7 tests.fs" />
     <Compile Include="Day8 tests.fs" />
     <Compile Include="Day9 tests.fs" />
+    <Compile Include="Day10 tests.fs" />
     <Content Include="packages.config" />
     <Content Include="App.config" />
   </ItemGroup>