Skip to content

Instantly share code, notes, and snippets.

@mscha
Last active December 2, 2025 23:04
Show Gist options
  • Select an option

  • Save mscha/91320baf7a9b7ae5abeb530de7785f3d to your computer and use it in GitHub Desktop.

Select an option

Save mscha/91320baf7a9b7ae5abeb530de7785f3d to your computer and use it in GitHub Desktop.
Advent of Code 2025 day 2
#!/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