Last active
December 2, 2025 23:04
-
-
Save mscha/91320baf7a9b7ae5abeb530de7785f3d to your computer and use it in GitHub Desktop.
Advent of Code 2025 day 2
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 2 -- https://adventofcode.com/2025/day/2 | |
| unit sub MAIN(IO() $inputfile where *.f = 'aoc02.input', Bool :v($verbose) = False); | |
| # Find invalid IDs in a list of ranges | |
| multi invalid-ids(Str $ranges, Bool :$simple = False) | |
| { | |
| # Split up the ranges, find start and end of each, and find the invalid IDs | |
| gather for $ranges.split(/\,\s*/) -> $range { | |
| my ($from, $to) = $range.comb(/\d+/)».Int; | |
| say "> $from - $to" if $verbose; | |
| take slip invalid-ids($from, $to, :$simple); | |
| } | |
| } | |
| # Find invalid IDs in a range where the end has more digits than the start | |
| multi invalid-ids(Int $from, Int $to where $to.chars > $from.chars, Bool :$simple = False) | |
| { | |
| # Split up in two tasks: | |
| # - numbers with the same length as $from | |
| # - numbers longer than $from | |
| my $N = 10 ** $from.chars; | |
| return |invalid-ids($from, $N-1, :$simple), |invalid-ids($N, $to, :$simple); | |
| } | |
| # Find invalid IDs in a range where all numbers have the same length | |
| multi invalid-ids(Int $from, Int $to where $to.chars == $from.chars, Bool :$simple = False) | |
| { | |
| # In the simple case, only consider 2 parts. Otherwise, consider any number of parts | |
| my @parts = $simple ?? 2 !! 2 .. $from.chars; | |
| # Check each possible number of parts | |
| my SetHash $invalid .= new; | |
| for @parts -> $p { | |
| # Nothing to do if the length of the numbers isn't divisible by the number of parts | |
| next unless $from.chars %% $p; | |
| say ">> $from - $to [$p parts]" if $verbose; | |
| # Loop through all candidate repeating numbers | |
| my $len = $from.chars div $p; | |
| my $a = $from.substr(0, $len).Int; | |
| my $b = $to.substr(0, $len).Int; | |
| for $a .. $b -> $i { | |
| my $n = ($i x $p).Int; | |
| # Remember the number if it actually falls within the range | |
| if $from ≤ $n ≤ $to { | |
| say ">>> -> $n", $invalid{$n} ?? ' (duplicate)' !! '' if $verbose; | |
| $invalid{$n} = True; | |
| } | |
| } | |
| } | |
| return $invalid.keys; | |
| } | |
| # Find invalid IDs in any other range (i.e. where the end is shorter than the start) | |
| multi invalid-ids(Int $from, Int $to, Bool :$simple = False) | |
| { | |
| # Nothing to find | |
| return Empty; | |
| } | |
| say "Part one: ", invalid-ids($inputfile.slurp, :simple).sum; | |
| say "Part two: ", invalid-ids($inputfile.slurp).sum; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment