Last active
December 8, 2025 13:03
-
-
Save mscha/4ffeac6a0faac35e7d24d2afcc39fac3 to your computer and use it in GitHub Desktop.
Advent of Code 2025 day 8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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