diff options
Diffstat (limited to 'solutions')
-rw-r--r-- | solutions/day9.fs | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/solutions/day9.fs b/solutions/day9.fs new file mode 100644 index 0000000..9c1407f --- /dev/null +++ b/solutions/day9.fs @@ -0,0 +1,39 @@ +namespace Solutions + +module Day9 = + open System.IO + open System.Text.RegularExpressions + open FSharpPlus.Operators + + let parseInstruction line = + let groups = Regex.Match(line, "([LRUD]) (\d+)").Groups + |> Seq.map (fun x -> x.Value) + |> Array.ofSeq + match groups[1], groups[2] with + | "L", count -> List.replicate (int count) (-1, 0) + | "R", count -> List.replicate (int count) (1, 0) + | "U", count -> List.replicate (int count) (0, 1) + | "D", count -> List.replicate (int count) (0, -1) + | _ -> failwith "invalid input" + + let headPositions steps = List.scan (fun (x1, y1) (x2, y2) -> (x1 + x2, y1 + y2)) (0, 0) steps + let instructions = File.ReadLines("inputs/day9.txt") |> Seq.map parseInstruction |> Seq.concat |> List.ofSeq |> headPositions + + let rec followPath (rope: list<int * int>) (tailSet: Set<int*int>) (heads: list<int*int>) = + let touches pointA pointB = abs (fst pointA - fst pointB) <= 1 && abs (snd pointA - snd pointB) <= 1 + let moveTowards head tail = (fst tail + signum (fst head - fst tail), snd tail + signum (snd head - snd tail)) + + if List.length heads = 0 then Set.count tailSet + else + let newHead = List.head heads + let newRope = List.scan (fun head tail -> if touches head tail then tail else moveTowards head tail) newHead (List.tail rope) + followPath newRope (Set.add (List.last newRope) tailSet) (List.tail heads) + + let solution ropeSize = + followPath (List.replicate ropeSize (0, 0)) Set.empty + + let part1 () = instructions + |> solution 2 + + let part2 () = instructions + |> solution 10 \ No newline at end of file |