Skip to content

Instantly share code, notes, and snippets.

@tobyink
Last active October 31, 2020 19:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tobyink/92b2b072a058c27d9f114cb4c8f9e1ac to your computer and use it in GitHub Desktop.
Save tobyink/92b2b072a058c27d9f114cb4c8f9e1ac to your computer and use it in GitHub Desktop.
Finding squares in a matrix
use strict;
use warnings;
package Weekly84 {
use Zydeco;
class Matrix {
# public required attribute
has cells! ( type => ArrayRef[ArrayRef[Bool, 1], 1] );
# lazy attributes
has n, m ( is => lazy, isa => PositiveInt, init_arg => undef );
method _build_m = scalar @{ $self->cells };
method _build_n = scalar @{ $self->cells->[0] };
# private method which acts as helper for factories
method $process ( $text ) {
[ map [ /([01])/g ], grep /[01]/, split /\n/, $text ]
}
# factories to make a new Matrix object from an ArrayRef or Str
multi factory new_matrix ( ArrayRef $cells )
= $class->new( cells => $cells );
multi factory new_matrix ( Str $text )
= $class->new( cells => $class->$process($text) );
# method to fetch a cell
method cell ( PositiveInt $x, PositiveInt $y ) {
confess 'Out of range' if $x > $self->m;
confess 'Out of range' if $y > $self->n;
$self->cells->[$x-1][$y-1];
}
# detect a square with size $size and top left corner at $x, $y
method has_square ( Int $x, Int $y, PositiveInt $size ) {
$self->cell( $x, $y ) and
$self->cell( $x+$size, $y ) and
$self->cell( $x+$size, $y+$size ) and
$self->cell( $x, $y+$size );
}
# find all squares within the matrix
method find_squares ( Bool $verbose = false ) {
my $smallest_axis = ( $self->m < $self->n ) ? 'm' : 'n';
my $max_size = $self->$smallest_axis();
my @found;
X: for my $x ( 1 .. $self->m ) {
Y: for my $y ( 1 .. $self->n ) {
SIZE: for my $size ( 1 .. $max_size ) {
next Y if $size + $x > $self->m;
next Y if $size + $y > $self->n;
if ( $self->has_square( $x, $y, $size ) ) {
say "Found size $size square at $x, $y." if $verbose;
push @found, [ $x, $y, $size ];
}
}
}
}
say "Found ", scalar( @found ), " squares." if $verbose;
return @found;
}
}
}
'Weekly84'->new_matrix( <<'MATRIX' )->find_squares(1);
[ 0 1 0 1 0 1 0 0 1 ]
[ 1 0 1 0 0 0 0 0 0 ]
[ 1 1 0 1 0 0 0 0 0 ]
[ 1 1 1 1 0 1 0 0 1 ]
MATRIX
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment