This is a solution to Advent of Code 2025 day 8, written in Raku.
https://adventofcode.com/2025/day/8
Part One
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?
use Test;
class junction-box {
has Int $.x; has Int $.y; has Int $.z;
has %.connections;
multi method gist {
"{$!x},{$!y},{$!z}"
}
method connected($other, %seen is copy = {}) {
return False if %seen{self};
%seen{self} = True;
%!connections{$other}:exists or any(%!connections.values>>.connected($other, %seen))
}
method connect($other) {
%!connections{$other} = $other;
$other.connections{self} = self;
}
method count(%seen) {
return 0 if %seen{self}:exists;
%seen{self} = True;
1 + [+] %!connections.values>>.count(%seen)
}
}
class distance {
has $.a; has $.z; has $.d;
submethod TWEAK {
$!d = sqrt(
($!z.x - $!a.x) ** 2 + ($!z.y - $!a.y) ** 2 + ($!z.z - $!a.z) ** 2
);
}
}
sub day-eight($input, $n) {
my @boxes = $input.IO.lines.map(
-> $line {
my ($x, $y, $z) = $line.split(',')>>.Int;
junction-box.new(:$x, :$y, :$z)
}
);
my @distances = @boxes.combinations(2).map(
-> ($a, $z) { distance.new(:$a, :$z) }
);
my @to-connect = @distances.sort(*.d)[^$n];
for @to-connect -> $d {
$d.a.connect($d.z) unless $d.a.connected($d.z);
}
my %seen;
[*] @to-connect.map( -> $d { $d.a.count(%seen); }).sort(-*)[^3];
}
is day-eight('8-test.txt', 10), 40, 'test input';
{
say day-eight('8-input.txt', 1000);
say "Took " ~ (now - ENTER now).base(10,2) ~ " seconds";
}ok 1 - test input 80446 Took 8.99 seconds
Part Two
Continue connecting the closest unconnected pairs of junction boxes together until they're all in the same circuit. What do you get if you multiply together the X coordinates of the last two junction boxes you need to connect?
use Test;
class junction-box {
has Int $.x; has Int $.y; has Int $.z;
}
class distance {
has $.a; has $.z; has $.d;
submethod TWEAK {
$!d = sqrt(
($!z.x - $!a.x) ** 2 + ($!z.y - $!a.y) ** 2 + ($!z.z - $!a.z) ** 2
);
}
}
class playground {
has %.parent;
has $.count;
method new(@boxes) {
my %parent = @boxes.map(-> $box { $box => $box });
my $count = +@boxes;
self.bless(:%parent, :$count)
}
method find($box) {
if %!parent{$box} !~~ $box {
%!parent{$box} = self.find(%!parent{$box});
}
%!parent{$box};
}
method unite($b1, $b2) {
my $c1 = self.find($b1);
my $c2 = self.find($b2);
if $c1 !~~ $c2 {
%!parent{$c2} = $c1;
$!count -= 1;
return True if $!count == 1;
}
return False;
}
}
sub day-eight-p2($input) {
my @boxes = $input.IO.lines.map(
-> $line {
my ($x, $y, $z) = $line.split(',')>>.Int;
junction-box.new(:$x, :$y, :$z)
}
);
my $playground = playground.new(@boxes);
my @distances = @boxes.combinations(2).map(
-> ($a, $z) { distance.new(:$a, :$z) }
);
for @distances.sort(*.d) -> $d {
return $d.a.x * $d.z.x if $playground.unite($d.a, $d.z);
}
}
is day-eight-p2('8-test.txt'), 25272, 'test input';
{
say day-eight-p2('8-input.txt');
say "Took " ~ (now - ENTER now).base(10,2) ~ " seconds";
}ok 1 - test input 51294528 Took 8.86 seconds