diff --git a/README.md b/README.md index 6e16a5c..e81ac0c 100644 --- a/README.md +++ b/README.md @@ -11,4 +11,4 @@ | 5 | Cafeteria | ⭐ | ⭐ | | 6 | Trash Compactor | ⭐ | ⭐ | | 7 | Laboratories | ⭐ | | -| 8 | Playground | | | +| 8 | Playground | ⭐ | ⭐ | diff --git a/src/__tests__/day_8_test.ts b/src/__tests__/day_8_test.ts index 046a492..22cdd09 100644 --- a/src/__tests__/day_8_test.ts +++ b/src/__tests__/day_8_test.ts @@ -1,5 +1,6 @@ import { assertEquals } from "@std/assert"; import { + get_last_pairing_mul, get_three_largest_pairings_mul, read_junction_box_3d_positions, } from "../exercises/day_8.ts"; @@ -11,3 +12,11 @@ Deno.test("Day 8 - A", async () => { const result = get_three_largest_pairings_mul(junction_boxes_coords, 10); assertEquals(result, 40); }); + +Deno.test("Day 8 - B", async () => { + const junction_boxes_coords = await read_junction_box_3d_positions( + "src/exercises/assets/day_8_test_input.txt", + ); + const result = get_last_pairing_mul(junction_boxes_coords); + assertEquals(result, 25272); +}); diff --git a/src/exercises/day_8.ts b/src/exercises/day_8.ts index a66c25f..adc2f4b 100644 --- a/src/exercises/day_8.ts +++ b/src/exercises/day_8.ts @@ -12,6 +12,10 @@ export default async function Playground() { ">> Three largest pairings mul: ", get_three_largest_pairings_mul(junction_boxes_coords, 1000), ); + console.log( + ">> Last pairing mul: ", + get_last_pairing_mul(junction_boxes_coords), + ); } export function get_three_largest_pairings_mul( @@ -28,11 +32,26 @@ export function get_three_largest_pairings_mul( return total; } +export function get_last_pairing_mul(box_list: Coordinate[]): number { + const last_pairing = get_last_pairing_circuit(box_list); + if (last_pairing) { + return box_list[last_pairing.a].x * box_list[last_pairing.b].x; + } + return 0; +} + +interface DistancePairing { + a: number; + b: number; + distance: number; +} + function generate_n_shortest_distances( box_list: Coordinate[], n: number, -): { a: number; b: number; distance: number }[] { - const distances: { a: number; b: number; distance: number }[] = []; + initial_distances?: DistancePairing[], +): DistancePairing[] { + const distances: DistancePairing[] = initial_distances ?? []; for (let i = 0; i < n; i++) { const shortest_distance: { distance: number; pair_index: number[] } = { distance: Infinity, // Dirty, but it's late @@ -86,73 +105,52 @@ function generate_n_shortest_pairings( return circuits; } -function _generate_n_shortest_pairings( +function get_last_pairing_circuit( box_list: Coordinate[], - max_pairings: number, -): number[][] { - const circuits: number[][] = []; - const pairings: number[][] = []; +): DistancePairing | undefined { + const INCREMENT = 10; // NOTE: to adjust computation cost, since the solution is inefficient + const circuits: number[][] = box_list.map((_, i) => [i]); - // Pair generation - for (let i = 0; i < max_pairings; i++) { - const shortest_distance: { distance: number; pair_index: number[] } = { - distance: Infinity, // Dirty, but it's late - pair_index: [], - }; - - // Pair boxes - box_list.forEach((box, box_index) => { - for (let next_i = box_index + 1; next_i < box_list.length; next_i++) { - const next_box = box_list[next_i]; - const next_distance = calc_distance(box, next_box); - if ( - next_distance < shortest_distance.distance && - !pairings.some((pairing) => - pairing.includes(box_index) && pairing.includes(next_i) - ) - ) { - shortest_distance.distance = next_distance; - shortest_distance.pair_index = [box_index, next_i]; + const is_done = (c: number[][]): boolean => { + return c.reduce((prev, current) => { + if (current.length > 0) { + return prev + 1; } + return prev; + }, 0) > 1 + ? false + : true; + }; + + let last_pairing: DistancePairing | undefined; + + let distance_list = generate_n_shortest_distances(box_list, INCREMENT); + while (!is_done(circuits)) { + distance_list = generate_n_shortest_distances( + box_list, + INCREMENT, + distance_list, + ); + distance_list.forEach((distance) => { + const a = circuits.find((c) => c.includes(distance.a)); + const b = circuits.find((c) => c.includes(distance.b)); + + if (a?.length && b?.length && a !== b) { + last_pairing = { + a: distance.a, + b: distance.b, + distance: distance.distance, + }; + const to_empty_index = circuits.findIndex((c) => + c.includes(distance.b) + ); + b.forEach((x) => a.push(x)); + circuits[to_empty_index] = []; } }); - // Update paring list - pairings.push(shortest_distance.pair_index); - // Check shortest pairings and then push - const a_circiut = circuits.find((c) => - c.includes(shortest_distance.pair_index[0]) - ); - const b_circiut = circuits.find((c) => - c.includes(shortest_distance.pair_index[1]) - ); - - if ( - a_circiut && b_circiut - ) { - const n_index = circuits.findIndex((p) => - p.includes(shortest_distance.pair_index[1]) - ); - b_circiut.forEach((b) => { - circuits.find((p) => p.includes(shortest_distance.pair_index[0])) - ?.push(b); - }); - circuits[n_index] = []; - } else if ( - a_circiut - ) { - circuits.find((p) => p.includes(shortest_distance.pair_index[0])) - ?.push(shortest_distance.pair_index[1]); - } else if ( - b_circiut - ) { - circuits.find((p) => p.includes(shortest_distance.pair_index[1])) - ?.push(shortest_distance.pair_index[0]); - } else { - circuits.push(shortest_distance.pair_index); - } } - return circuits; + return last_pairing; } function calc_distance(a: Coordinate, b: Coordinate): number { diff --git a/src/exercises/day_9.ts b/src/exercises/day_9.ts new file mode 100644 index 0000000..e69de29