diff --git a/bin/day2408.ml b/bin/day2408.ml index d378503..0ee79c2 100644 --- a/bin/day2408.ml +++ b/bin/day2408.ml @@ -11,13 +11,10 @@ let map_length map = String.length map.map let map_get_by_idx map idx = map.map.[idx] let map_pos_of_idx map idx = (idx mod map.width, idx / map.width) let map_idx_of_pos map (x, y) = x + (y * map.width) -(*let map_get_pos map pos = map_get_by_idx map (map_idx_of_pos map pos)*) let map_is_valid_pos map (x, y) = x >= 0 && x < map.width && y >= 0 && y < map.height -(*let map_is_valid_idx map idx = idx >= 0 && idx < map_length map*) - let get_station_indices map = let arr = Array.make 256 [] in let rec impl idx = @@ -30,46 +27,51 @@ let get_station_indices map = in impl 0 -let get_antinodes map station_idxs = - let rec impl2 acc (px, py) = function - | [] -> acc - | h :: t -> - let hx, hy = map_pos_of_idx map h in - let dx = hx - px in - let dy = hy - py in - impl2 ((px - dx, py - dy) :: (hx + dx, hy + dy) :: acc) (px, py) t - in - let rec impl acc = function - | [] -> acc - | h :: t -> impl (impl2 acc (map_pos_of_idx map h) t) t - in - let lst = impl [] station_idxs |> List.filter (map_is_valid_pos map) in - let lst2 = lst |> List.map (map_idx_of_pos map) in - lst2 +let rec get_antinodes1 acc map p = + let px, py = map_pos_of_idx map p in + function + | [] -> acc + | h :: t -> + let hx, hy = map_pos_of_idx map h in + let dx = hx - px in + let dy = hy - py in + get_antinodes1 ((px - dx, py - dy) :: (hx + dx, hy + dy) :: acc) map p t -let process_stations map stations = Array.map (get_antinodes map) stations +let rec add_antinodes lst map (x, y) (dx, dy) = + if map_is_valid_pos map (x, y) then + add_antinodes ((x, y) :: lst) map (x + dx, y + dy) (dx, dy) + else lst -let string_replace str pos c = - assert (pos < String.length str); - String.sub str 0 pos ^ String.make 1 c - ^ String.sub str (pos + 1) (String.length str - pos - 1) +let rec get_antinodes2 acc map p = + let px, py = map_pos_of_idx map p in + function + | [] -> acc + | h :: t -> + let hx, hy = map_pos_of_idx map h in + let dx = hx - px in + let dy = hy - py in + let acc' = add_antinodes acc map (px, py) (dx, dy) in + let acc'' = add_antinodes acc' map (px, py) (-dx, -dy) in + get_antinodes2 acc'' map p t -let map_print map = - let rec impl off = if off < map_length map then impl (off + map.width) in - impl 0 +let process_stations map fn stations = + let rec impl acc = function [] -> acc | h :: t -> impl (fn acc map h t) t in + Array.map + (fun x -> + impl [] x + |> List.filter (map_is_valid_pos map) + |> List.map (map_idx_of_pos map)) + stations -let rec add_stations map = function - | [] -> map - | h :: t -> add_stations { map with map = string_replace map.map h '#' } t +let part antifn map = + get_station_indices map + |> process_stations map antifn + |> Array.fold_left List.append [] + |> List.sort_uniq Stdlib.compare + |> List.length -let part1 map = - let lst = - get_station_indices map |> process_stations map - |> Array.fold_left List.append [] - |> List.sort_uniq Stdlib.compare - in - let map' = add_stations map lst in - map_print map'; - List.length lst - -let _ = Aoc.main map_of_file [ (string_of_int, part1) ] +let _ = + Aoc.main map_of_file + [ + (string_of_int, part get_antinodes1); (string_of_int, part get_antinodes2); + ]