blob: b6812664169e70eb137fdeae314a0c524337f251 (
plain) (
tree)
|
|
module Solutions.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
|