Skip to content

Instantly share code, notes, and snippets.

@mscha
Last active December 8, 2025 13:03
Show Gist options
  • Select an option

  • Save mscha/4ffeac6a0faac35e7d24d2afcc39fac3 to your computer and use it in GitHub Desktop.

Select an option

Save mscha/4ffeac6a0faac35e7d24d2afcc39fac3 to your computer and use it in GitHub Desktop.
Advent of Code 2025 day 8
#!/usr/bin/env raku
use v6.d;
$*OUT.out-buffer = False; # Autoflush
# Advent of Code 2025 day 8 -- https://adventofcode.com/2025/day/8
unit sub MAIN(IO() $inputfile where *.f = 'aoc08.input', Bool :v(:$verbose) = False);
class ElectricalSystem
{
has @.junctions;
has %.distance = calc-distances(@!junctions);
has @.distance-list = %!distance.sort(*.value);
has @.circuits = Empty;
has $.final-x-product;
# Calculate all the distances between junctions.
# (The square of the distance, actually, for performance reasons.)
sub calc-distances(@junctions)
{
gather for (^@junctions).combinations(2) -> ($i, $j) {
#my $distance = (@junctions[$i;*] Z- @junctions[$j;*]).map(*²).sum;
# The above is nice, but twice as slow as the below...
my $ji = @junctions[$i];
my $jj = @junctions[$j];
my $distance = ($ji[0] - $jj[0])²
+ ($ji[1] - $jj[1])²
+ ($ji[2] - $jj[2])²;
take "$i,$j" => $distance;
}
}
# Find the two junctions that have the closest distance (and which haven't
# been connected yet).
method closest-junctions
{
return @!distance-list.shift.key.split(',')».Int;
}
# Connect the closest junctions, count times.
# (Default: until all junctions are connected in a single circuit.)
method connect-junctions($count = ∞)
{
CONNECTION:
for ^$count {
# Find the closest (unconnected) junctions, and check in which
# circuit they are (if any).
my ($i, $j) = self.closest-junctions;
my $ci = @!circuits.first($i ∈ *, :k);
my $cj = @!circuits.first($j ∈ *, :k);
my $c;
if $ci.defined && $cj.defined {
# Both in a circuit already?
if $ci ≠ $cj {
# Each in a different circuit? Merge them
($ci, $cj) .= sort;
$c = $ci;
@!circuits[$c] ∪= @!circuits[$cj];
@!circuits.splice($cj, 1);
}
else {
# Both in the same circuit? Nothing to do
$c = $ci;
}
}
elsif $ci.defined && !$cj.defined {
# First one in a circuit? Add the second one to it.
$c = $ci;
@!circuits[$c]{$j}++;
}
elsif !$ci.defined && $cj.defined {
# Second one in a circuit? Add the first one to it.
$c = $cj;
@!circuits[$c]{$i}++;
}
elsif !$ci.defined && !$cj.defined {
# Neither in a circuit? Add both to a new one
$c = @!circuits.elems;
@!circuits[$c] = SetHash.new($i, $j);
}
say "# connecting $i and $j: ", @!circuits[$c].keys.sort if $verbose;
# If the circuit contains all junctions, we're done.
if @!circuits[$c].keys == @!junctions.elems {
$!final-x-product = @!junctions[$i;0] * @!junctions[$j;0];
last CONNECTION;
}
}
}
method circuit-score { [*] @!circuits».elems.sort.tail(3) }
}
my @junctions = $inputfile.lines».comb(/\d+/)».Int;
my $system = ElectricalSystem.new(:@junctions);
my $count = $inputfile ~~ /sample/ ?? 10 !! 1000;
$system.connect-junctions($count);
say "Part one: ", $system.circuit-score;
$system.connect-junctions;
say "Part two: ", $system.final-x-product;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment