use 5.36.0; package AoC::Grid; use Math::Vector::Real; use Moo; has grid => ( is => 'lazy', default => sub($self) { return [ map { [ split '' ] } split "\n", $self->string ] }); has string => ( is => 'ro' ); has dimensions => is => 'lazy', default => sub ($self) { return [ 0 + $self->grid->@*, 0 + $self->grid->[0]->@* ]; }; sub get($self,$i,$j) { return unless $self->is_inside($i,$j); return $self->grid->[$i][$j]; } sub foreach($self,$sub) { for my $l ( 0..$self->dimensions->[0]-1) { for my $c ( 0..$self->dimensions->[1]-1) { $sub->($l,$c,$self->get($l,$c)); } } } sub is_inside($self,$i,$j) { return 0 if $i < 0 or $j < 0; return 0 if $i >= $self->dimensions->[0]; return 0 if $j >= $self->dimensions->[1]; return 1; } sub as_string($self) { my $o = ''; for my $l ( $self->grid->@* ) { $o .= join( '', @$l)."\n"; } return $o; } sub ortho_neighbors($self,$x,$y) { return grep { $self->is_inside(@$_) } map { V($x,$y)+V(@$_) } [1,0],[0,1],[-1,0],[0,-1]; } 1;