From 76e962969d521a02d1281ec0c2442e0267f2176d Mon Sep 17 00:00:00 2001 From: Kees van Kempen Date: Tue, 9 Dec 2025 19:46:36 +0100 Subject: [PATCH] 2025(08): I misread the assignment, I think --- 2025/08/README.md | 59 ++++++++++++++++++++++++++++++++ 2025/08/part1.py | 87 +++++++++++++++++++++++++++++++++++++++++++++++ 2025/08/testinput | 20 +++++++++++ 3 files changed, 166 insertions(+) create mode 100644 2025/08/README.md create mode 100644 2025/08/part1.py create mode 100644 2025/08/testinput diff --git a/2025/08/README.md b/2025/08/README.md new file mode 100644 index 0000000..1a21ec0 --- /dev/null +++ b/2025/08/README.md @@ -0,0 +1,59 @@ +# Day 8: Playground + +[https://adventofcode.com/2025/day/8](https://adventofcode.com/2025/day/8) + +## Description + +### Part One + +Equipped with a new understanding of teleporter maintenance, you confidently step onto the repaired teleporter pad. + +You rematerialize on an unfamiliar teleporter pad and find yourself in a vast underground space which contains a giant playground! + +Across the playground, a group of Elves are working on setting up an ambitious Christmas decoration project. Through careful rigging, they have suspended a large number of small electrical [junction boxes](https://en.wikipedia.org/wiki/Junction_box). + +Their plan is to connect the junction boxes with long strings of lights. Most of the junction boxes don't provide electricity; however, when two junction boxes are connected by a string of lights, electricity can pass between those two junction boxes. + +The Elves are trying to figure out _which junction boxes to connect_ so that electricity can reach _every_ junction box. They even have a list of all of the junction boxes' positions in 3D space (your puzzle input). + +For example: + + 162,817,812 + 57,618,57 + 906,360,560 + 592,479,940 + 352,342,300 + 466,668,158 + 542,29,236 + 431,825,988 + 739,650,466 + 52,470,668 + 216,146,977 + 819,987,18 + 117,168,530 + 805,96,715 + 346,949,466 + 970,615,88 + 941,993,340 + 862,61,35 + 984,92,344 + 425,690,689 + + +This list describes the position of 20 junction boxes, one per line. Each position is given as `X,Y,Z` coordinates. So, the first junction box in the list is at `X=162`, `Y=817`, `Z=812`. + +To save on string lights, the Elves would like to focus on connecting pairs of junction boxes that are _as close together as possible_ according to [straight-line distance](https://en.wikipedia.org/wiki/Euclidean_distance). In this example, the two junction boxes which are closest together are `162,817,812` and `425,690,689`. + +By connecting these two junction boxes together, because electricity can flow between them, they become part of the same _circuit_. After connecting them, there is a single circuit which contains two junction boxes, and the remaining 18 junction boxes remain in their own individual circuits. + +Now, the two junction boxes which are closest together but aren't already directly connected are `162,817,812` and `431,825,988`. After connecting them, since `162,817,812` is already connected to another junction box, there is now a single circuit which contains _three_ junction boxes and an additional 17 circuits which contain one junction box each. + +The next two junction boxes to connect are `906,360,560` and `805,96,715`. After connecting them, there is a circuit containing 3 junction boxes, a circuit containing 2 junction boxes, and 15 circuits which contain one junction box each. + +The next two junction boxes are `431,825,988` and `425,690,689`. Because these two junction boxes were _already in the same circuit_, nothing happens! + +This process continues for a while, and the Elves are concerned that they don't have enough extension cables for all these circuits. They would like to know how big the circuits will be. + +After making the ten shortest connections, there are 11 circuits: one circuit which contains _5_ junction boxes, one circuit which contains _4_ junction boxes, two circuits which contain _2_ junction boxes each, and seven circuits which each contain a single junction box. Multiplying together the sizes of the three largest circuits (5, 4, and one of the circuits of size 2) produces _`40`_. + +Your list contains many junction boxes; connect together the _1000_ pairs of junction boxes which are closest together. Afterward, _what do you get if you multiply together the sizes of the three largest circuits?_ diff --git a/2025/08/part1.py b/2025/08/part1.py new file mode 100644 index 0000000..dfbd5e9 --- /dev/null +++ b/2025/08/part1.py @@ -0,0 +1,87 @@ +import numpy as np + + +debug = False + +def load_junctions(filename: str): + """ + Load junction file into memory. + """ + data = np.loadtxt(filename, dtype=int, delimiter=",") + + return data + +def distances(junctions, sorted=True): + """ + Use the upper triangle to calculate distances so we don't do it twice per + pair. + + NOTE: The upper triangle includes the pairs of each junction with itself. + """ + jlen = len(junctions) + X, Y = np.triu_indices(jlen) + + # Ignore distances if x == y. + non_self_identities = X != Y + X = X[non_self_identities] + Y = Y[non_self_identities] + + # NOTE: I do note use np.zeros_like as I want the dtype to be the default (float). + dists = np.zeros(X.shape) + + # For each pair, calculate the distance. + for i in range(len(X)): + x, y = X[i], Y[i] + dists[i] = np.linalg.norm(junctions[x] - junctions[y]) + + # Sort the distances, X, and Y from shortest to longest distance. + if sorted: + sorted_indices = np.argsort(dists) + X = X[sorted_indices] + Y = Y[sorted_indices] + dists = dists[sorted_indices] + + return X, Y, dists + +def num_of_combinations(length): + return length*(length - 1)//2 + +def is_connected(x, connections): + for connection in connections: + if x in connection: + return True + return False + +def get_circuits(junctions, connections): + """ + Convert connections into circuits. + + Start by adding all junction indices as circuits, then iterating over + connection to make disjunct sets. + """ + # circuits = [[x] for x in range(len(junctions))] + circuits = [list(x) for x in connections] + changed = True + while changed: + changed = False + for i in range(len(circuits)): + for j in range(i + 1, len(circuits)): + for x in circuits[i]: + if x in circuits[j]: + # NOTE: Elements might appear multiple times per circuit. + circuits[i] += circuits.pop[j] + changed = True + return circuits + + +if __name__ == "__main__": + test_junctions = load_junctions("testinput") + X, Y, dists = distances(test_junctions) + connections = [] + # unconnected = list(range(len(test_junctions))) + + for i in range(len(X)): + x, y = X[i], Y[i] + if not is_connected(x, connections) and not is_connected(y, connections): + connections.append((x, y)) + print(len(connections)) \ No newline at end of file diff --git a/2025/08/testinput b/2025/08/testinput new file mode 100644 index 0000000..e98a3b6 --- /dev/null +++ b/2025/08/testinput @@ -0,0 +1,20 @@ +162,817,812 +57,618,57 +906,360,560 +592,479,940 +352,342,300 +466,668,158 +542,29,236 +431,825,988 +739,650,466 +52,470,668 +216,146,977 +819,987,18 +117,168,530 +805,96,715 +346,949,466 +970,615,88 +941,993,340 +862,61,35 +984,92,344 +425,690,689