solve day 9 :)

This commit is contained in:
ryan 2023-10-05 15:56:02 -07:00
parent 5e1c30637e
commit 1ee3a5a3c5
3 changed files with 2070 additions and 1 deletions

View File

@ -8,5 +8,6 @@ let () =
Day5.print ();
Day6.print ();
Day7.print ();
Day8.print ()
Day8.print ();
Day9.print ()
;;

2000
inputs/day9.tt Normal file

File diff suppressed because it is too large Load Diff

68
src/day9.ml Normal file
View File

@ -0,0 +1,68 @@
open Containers
let parse_input () =
Utils.lines_of_input 9
|> List.concat_map (fun line ->
match String.split ~by:" " line with
| [ dir; count ] ->
let count = int_of_string count in
let dir =
match dir with
| "U" -> Vec2.up
| "D" -> Vec2.down
| "L" -> Vec2.left
| "R" -> Vec2.right
| _ -> failwith "failed to parse instructions"
in
List.init count (fun _ -> dir)
| _ -> failwith "failed to parse instructions")
;;
let next_pos head tail =
let dx, dy = Vec2.(to_tuple @@ (tail - head)) in
if abs dx <= 1 && abs dy <= 1
then tail
else (
let x_dir = if dx > 0 then Vec2.right else Vec2.left in
let y_dir = if dy > 0 then Vec2.up else Vec2.down in
let dir =
if abs dx = abs dy
then Vec2.(x_dir + y_dir)
else if abs dx > abs dy
then x_dir
else y_dir
in
Vec2.(head + dir))
;;
let solve length =
let moves = parse_input () in
let start = Vec2.of_tuple (0, 0) in
let tail = List.init (length - 1) (fun _ -> start) in
let _, _, last_knot_hist =
List.fold_left
(fun (head, tail, last_knot_hist) dir ->
let new_head = Vec2.(head + dir) in
let last_knot, new_tail =
List.fold_map
(fun head knot ->
let new_knot = next_pos head knot in
new_knot, new_knot)
new_head
tail
in
new_head, new_tail, last_knot :: last_knot_hist)
(start, tail, [ start ])
moves
in
last_knot_hist |> List.uniq ~eq:Vec2.( = ) |> List.length
;;
let part1 () = solve 2
let part2 () = solve 10
let print () =
Printf.(
printf "Day 9.1: %d\n" @@ part1 ();
printf "Day 9.2: %d\n" @@ part2 ())
;;