From 6eb34aa6152415e6db96b45456bfaefd242c1b0d Mon Sep 17 00:00:00 2001 From: Brian Chu Date: Tue, 13 Dec 2022 00:34:46 -0800 Subject: solution for day 9 --- solutions/day9.fs | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 solutions/day9.fs (limited to 'solutions') 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) (tailSet: Set) (heads: list) = + 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 -- cgit 1.4.1-2-gfad0