<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>
<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>
<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>
--- /dev/null
+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
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 ()
| 22 -> day22 ()
| 23 -> day23 ()
| 24 -> day24 ()
+ | 25 -> day25 ()
| _ -> raise <| NotImplementedException ()
printfn "Result of day %i: %s (time : %i ms)" n result sw.ElapsedMilliseconds
--- /dev/null
+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
<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>