|
1 | 1 | open Utils |
2 | 2 |
|
3 | | -let day08 input = |
4 | | - ("TODO", "TODO") |
| 3 | +let parse input = |
| 4 | + trim_end_nl input |
| 5 | + |> String.split_on_char '\n' |
| 6 | + |> List.map (fun l -> |
| 7 | + let a, b = string_split_once "," l in |
| 8 | + let b, c = string_split_once "," b in |
| 9 | + tmap3 int_of_string (a, b, c)) |
| 10 | + |> Array.of_list |
| 11 | + |
| 12 | +let sq_dist (ax, ay, az) (bx, by, bz) = |
| 13 | + let dx, dy, dz = ax - bx, ay - by, az - bz in |
| 14 | + dx * dx + dy * dy + dz * dz |
| 15 | + |
| 16 | +let prep verts = |
| 17 | + let n = Array.length verts in |
| 18 | + let arr = Array.make (n * (n - 1) / 2) (0, 0, 0) in |
| 19 | + |
| 20 | + let rec populate a b i = if a < n - 1 then begin |
| 21 | + if b >= n then populate (a + 1) (a + 2) i |
| 22 | + else begin |
| 23 | + arr.(i) <- (sq_dist verts.(a) verts.(b), a, b); |
| 24 | + populate a (b + 1) (i + 1) |
| 25 | + end |
| 26 | + end in |
| 27 | + |
| 28 | + populate 0 1 0; |
| 29 | + Array.fast_sort (fun (a, _, _) (b, _, _) -> Int.compare a b) arr; |
| 30 | + |
| 31 | + Array.to_list arr |
5 | 32 |
|
| 33 | +let solve_part1 verts pairs = |
| 34 | + let n = Array.length verts in |
| 35 | + let sets = UnionFind.make n in |
6 | 36 |
|
| 37 | + List.take 1000 pairs |
| 38 | + |> List.iter (fun (_, a, b) -> UnionFind.union a b sets); |
| 39 | + |
| 40 | + UnionFind.sizes sets |
| 41 | + |> List.sort (fun a b -> Int.compare b a) |
| 42 | + |> List.take 3 |
| 43 | + |> List.fold_left ( * ) 1 |
| 44 | + |
| 45 | +let solve_part2 verts pairs = |
| 46 | + let n = Array.length verts in |
| 47 | + let sets = UnionFind.make n in |
| 48 | + |
| 49 | + let rec aux (ax, _, _) (bx, _, _) = function |
| 50 | + | _ when UnionFind.components sets = 1 -> ax * bx |
| 51 | + | (_, a, b) :: r -> (UnionFind.union a b sets; aux verts.(a) verts.(b) r) |
| 52 | + | [] -> failwith "Made every connection without connecting everything, interesting." |
| 53 | + in |
| 54 | + aux (0, 0, 0) (0, 0, 0) pairs |
| 55 | + |
| 56 | +let day08 input = |
| 57 | + let verts = parse input in |
| 58 | + let pairs = prep verts in |
| 59 | + let part1 = solve_part1 verts pairs in |
| 60 | + let part2 = solve_part2 verts pairs in |
| 61 | + (string_of_int part1, string_of_int part2) |
0 commit comments