#!/usr/bin/perl # http://perlmonks.org/?node_id=1207332 use strict; use warnings; my @grid = ( [ qw( a a b a c ) ], [ qw( a a a c f ) ], [ qw( a f c 1 b ) ], [ qw( a w x c z ) ], [ qw( a q q q c ) ], ); $_ = join '', map join('', @$_) . "\n", @grid; # convert to string print; recognize( pattern => 'horizontal', min => 3 ); recognize( pattern => 'vertical', min => 5 ); recognize( pattern => 'diagonal', min => 2 ); sub recognize { my %args = @_; my ( $direction, $min) = @args{ qw( pattern min ) }; $min // die "min not defined"; my $reps = $min - 1; my $linesize = /\n/ && $+[0]; my $gapref = { horizontal => [0], vertical => [$linesize - 1], diagonal => [$linesize - 2, $linesize]}->{$direction} // die "invalid direction $direction"; for my $gap ( @$gapref ) { print "\n"; print "$direction @{[ 1 + length($2) / ($gap + 1) ]} '$1' at ", $-[1] % $linesize, ' ', int $-[1] / $linesize, "\n" while /(\w)(?=((?:.{$gap}\1){$reps,}))/gs; } }