Files
ocaml-aoc/bin/day2414.ml

87 lines
2.3 KiB
OCaml

module IntMap = Map.Make (Int)
let parse_robot s =
let re =
Str.regexp {|p=\(-?[0-9]+\),\(-?[0-9]+\) v=\(-?[0-9]+\),\(-?[0-9]+\)|}
in
let _ = Str.search_forward re s 0 in
( ( int_of_string (Str.matched_group 1 s),
int_of_string (Str.matched_group 2 s) ),
( int_of_string (Str.matched_group 3 s),
int_of_string (Str.matched_group 4 s) ) )
let parse_robots = List.map parse_robot
let robots_of_file fname = Aoc.strings_of_file fname |> parse_robots
let width = 101
let height = 103
let secs = 100
let normalize_velocity (p, (dx, dy)) =
(p, ((dx + width) mod width, (dy + height) mod height))
let calc_pos_after secs ((x, y), (dx, dy)) =
let x' = (x + (secs * dx)) mod width in
let y' = (y + (secs * dy)) mod height in
(x', y')
let in_a_quadrant (x, y) = x <> width / 2 && y <> height / 2
let update_count = function None -> Some 1 | Some x -> Some (x + 1)
let get_quadrant (x, y) =
if x < width / 2 && y < height / 2 then 1
else if x > width / 2 && y < height / 2 then 2
else if x < width / 2 && y > height / 2 then 4
else if x > width / 2 && y > height / 2 then 3
else failwith "get_quadrant"
let loc_counts map p =
let idx = get_quadrant p in
IntMap.update idx update_count map
let print_locs lst =
let a = Array.make_matrix height width '.' in
let rec impl = function
| [] -> ()
| (x, y) :: t ->
if a.(y).(x) = '.' then a.(y).(x) <- '1'
else a.(y).(x) <- char_of_int (1 + int_of_char a.(y).(x));
impl t
in
impl lst;
Array.iter
(fun r ->
Array.iter print_char r;
print_newline ())
a
let part1 robots =
let counts =
robots
|> List.map normalize_velocity
|> List.map (calc_pos_after secs)
|> List.filter in_a_quadrant
|> List.fold_left loc_counts IntMap.empty
in
IntMap.fold (fun _ v acc -> acc * v) counts 1
let find_tree max_n lst =
let num_robots = List.length lst in
let rec impl n =
if n > max_n then failwith "None found"
else
let poses = List.map (calc_pos_after n) lst in
if List.length (List.sort_uniq Aoc.IntPair.compare poses) = num_robots
then (
print_locs poses;
n)
else impl (n + 1)
in
impl 0
let part2 robots =
let robots = List.map normalize_velocity robots in
find_tree 100000 robots
let _ =
Aoc.main robots_of_file [ (string_of_int, part1); (string_of_int, part2) ]