Day 3 (bis)
authorGreg Burri <greg.burri@gmail.com>
Sun, 3 Dec 2017 14:31:42 +0000 (15:31 +0100)
committerGreg Burri <greg.burri@gmail.com>
Sun, 3 Dec 2017 14:31:42 +0000 (15:31 +0100)
AdventOfCode2017/Day3.fs [new file with mode: 0644]

diff --git a/AdventOfCode2017/Day3.fs b/AdventOfCode2017/Day3.fs
new file mode 100644 (file)
index 0000000..a48ad7c
--- /dev/null
@@ -0,0 +1,46 @@
+module AdventOfCode2017.Day3
+
+type Direction = Right | Up | Left | Down
+
+let nextDirection = function Right -> Up | Up -> Left | Left -> Down | Down -> Right
+
+let move (pos : int * int) (d : Direction) =
+    let x, y = pos
+    match d with Right -> x + 1, y | Up -> x, y + 1 | Left -> x - 1, y | Down -> x, y - 1
+
+let rec next (pos : int * int) (l : int) (d : Direction) : (int * int) seq =
+    let directions = Seq.unfold (fun d -> Some (d, nextDirection d)) d |> Seq.take 3 |> List.ofSeq
+
+    let mutable pos' = pos
+
+    seq {
+        for d in directions |> List.take 2 do
+            for _j = 1 to l do
+                pos' <- move pos' d
+                yield pos'
+        yield! next pos' (l + 1) (List.last directions)
+    }
+
+let spiralManhattanDistanceSum (n : int) =
+    let x, y = next (0, 0) 1 Right |> Seq.item (n - 2)
+    abs x + abs y
+
+let spiralAdjacentSumBiggerThan (n : int) =
+    let neighborsSum (dic : Map<int * int, int>) (pos : int * int) =
+        let x, y = pos
+        [ x + 1, y; x + 1, y + 1; x, y + 1; x - 1, y + 1; x - 1, y; x - 1, y - 1; x, y - 1; x + 1, y - 1]
+        |> List.map (
+            fun (x, y) ->
+                match dic |> Map.tryFind (x, y) with
+                | Some v -> v
+                | None -> 0
+        )
+        |> List.sum
+
+    next (0, 0) 1 Right
+    |> Seq.scan (
+        fun (_sum, dic) pos ->
+            let sum = neighborsSum dic pos
+            sum, dic |> Map.add pos sum
+    ) (1, Map.empty |> Map.add (0, 0) 1)
+    |> Seq.pick (fun (sum, _) -> if sum > n then Some sum else None)
\ No newline at end of file