Skip to content

Instantly share code, notes, and snippets.

@mscha
Created December 4, 2024 11:25
Show Gist options
  • Select an option

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

Select an option

Save mscha/c58aaef870e5c5b4498e62b01d93d399 to your computer and use it in GitHub Desktop.
Advent of Code 2024 day 4
#!/usr/bin/env raku
use v6.d;
$*OUT.out-buffer = False; # Autoflush
# Advent of Code 2024 day 4 -- https://adventofcode.com/2024/day/4
class WordFinder
{
has @.grid;
has $!width = @!grid[0].elems;
has $!height = @!grid.elems;
method at($char, $y,$x)
{
return False unless 0 ≤ $y < $!height;
return False unless 0 ≤ $x < $!width;
return $char eq @!grid[$y;$x];
}
method count($word)
{
return ((^$!height) X (^$!width))
.map(-> ($y,$x) { self.count-at($word, $y,$x) })
.sum;
}
method count-at($word, $y, $x)
{
my @letters = $word.comb;
my $count = 0;
DIRECTION:
for (-1..1) X (-1..1) -> ($dy,$dx) {
next DIRECTION if $dy == 0 && $dx == 0;
for @letters.kv -> $i, $l {
next DIRECTION unless self.at($l, $y+$i*$dy, $x+$i*$dx);
}
$count++;
}
return $count;
}
method count-X($word)
{
return ((^$!height) X (^$!width))
.map(-> ($y,$x) { self.count-X-at($word, $y,$x) })
.sum;
}
method count-X-at($word, $y, $x)
{
# Only support 3-letter words for now
return 0 unless $word.chars == 3;
# Can't be on the edge
return 0 unless 1 ≤ $y < $!height-1;
return 0 unless 1 ≤ $x < $!width-1;
my @letters = $word.comb;
my $ends = set(@letters[0,2]);
return 0 unless self.at(@letters[1], $y, $x);
return 0 unless set(@!grid[$y-1;$x-1], @!grid[$y+1;$x+1]) eqv $ends;
return 0 unless set(@!grid[$y-1;$x+1], @!grid[$y+1;$x-1]) eqv $ends;
return 1;
}
}
sub MAIN(IO() $inputfile where *.f = 'aoc04.input')
{
my $wf = WordFinder.new(:grid($inputfile.lines».comb));
say "Part 1: ", $wf.count('XMAS');
say "Part 2: ", $wf.count-X('MAS');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment