Skip to content

Instantly share code, notes, and snippets.

@mscha
Last active December 8, 2024 14:53
Show Gist options
  • Save mscha/c1d8632c514799e422d69f2f4498b8f7 to your computer and use it in GitHub Desktop.
Save mscha/c1d8632c514799e422d69f2f4498b8f7 to your computer and use it in GitHub Desktop.
Advent of Code 2024 day 8
#!/usr/bin/env raku
use v6.d;
$*OUT.out-buffer = False; # Autoflush
# Advent of Code 2024 day 8 -- https://adventofcode.com/2024/day/8
class Position
{
has Int $.x;
has Int $.y;
method xy { $!x, $!y }
method Str { "($!x,$!y)" }
method gist { self.Str }
method WHICH { ValueObjAt.new("Position|$!x|$!y") }
}
multi sub pos(Int() $x, Int() $y) { Position.new(:$x, :$y) }
multi sub pos(@xy) { pos(@xy[0], @xy[1]) }
multi sub infix:<*>(Numeric $n, Position $p) { pos($n «*« $p.xy) }
multi sub infix:<+>(Position $p, Position $q) { pos($p.xy »+« $q.xy) }
multi sub infix:<->(Position $p, Position $q) { pos($p.xy »-« $q.xy) }
class AntennaMap
{
has @.grid;
has $.harmonics = False;
has $.verbose = False;
has $!height = @!grid.elems;
has $!width = @!grid[0].elems;
has %.antenna-pos;
has %.antinode-pos;
submethod TWEAK
{
# Detect antenna positions
for (^$!width X ^$!height) -> ($x,$y) {
my $antenna = @!grid[$y;$x];
next if $antenna eq '.';
say "Antenna $antenna at ($x,$y)" if $!verbose;
%!antenna-pos{$antenna}.append(pos($x,$y));
}
# Detect antinodes
for %!antenna-pos.kv -> $antenna, @pos {
for @pos.combinations(2) -> ($p1, $p2) {
for self.antinodes($p1, $p2) -> $p {
say "Antinode for $antenna [$p1-$p2] at $p" if $!verbose;
%!antinode-pos{$p}.append($antenna);
}
}
}
}
multi method within-bounds($x,$y) { 0$x < $!width && 0$y < $!height }
multi method within-bounds($pos) { self.within-bounds($pos.x, $pos.y) }
method antinodes(Position $p1, Position $p2)
{
gather {
if !$!harmonics {
for 2*$p1 - $p2, 2*$p2 - $p1 -> $p {
take $p if self.within-bounds($p);
}
}
else {
# Find starting position
my $dp = $p1 - $p2;
my $p = $p1;
while self.within-bounds($p - $dp) {
$p -= $dp;
}
# Find all antinodes
while self.within-bounds($p) {
take $p;
$p += $dp;
}
}
}
}
}
sub MAIN(IO() $inputfile where *.f = 'aoc08.input', Bool :v(:$verbose) = False)
{
my @grid = $inputfile.lines».comb;
my $map1 = AntennaMap.new(:@grid, :$verbose);
say "Part 1: $map1.antinode-pos.elems() positions contain an antinode.";
my $map2 = AntennaMap.new(:@grid, :harmonics, :$verbose);
say "Part 2: $map2.antinode-pos.elems() positions contain an antinode.";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment