aboutsummaryrefslogtreecommitdiff
path: root/challenge-076/bob-lied/perl/lib
diff options
context:
space:
mode:
authorboblied <boblied@gmail.com>2020-09-10 15:49:10 -0500
committerboblied <boblied@gmail.com>2020-09-10 15:49:10 -0500
commit23b6e830d7ce0ceebb087bb382f37e09de2ae334 (patch)
treebfa87eb0f21f4033d1744a3cb40fc181128b60d3 /challenge-076/bob-lied/perl/lib
parent1269c8b9daf7a7375d1e47722aac587e381bcf2b (diff)
downloadperlweeklychallenge-club-23b6e830d7ce0ceebb087bb382f37e09de2ae334.tar.gz
perlweeklychallenge-club-23b6e830d7ce0ceebb087bb382f37e09de2ae334.tar.bz2
perlweeklychallenge-club-23b6e830d7ce0ceebb087bb382f37e09de2ae334.zip
Solution for 076 Task 2, Word Search
Diffstat (limited to 'challenge-076/bob-lied/perl/lib')
-rw-r--r--challenge-076/bob-lied/perl/lib/WordSearch.pm165
1 files changed, 159 insertions, 6 deletions
diff --git a/challenge-076/bob-lied/perl/lib/WordSearch.pm b/challenge-076/bob-lied/perl/lib/WordSearch.pm
index 16e8dff435..7d03abdfca 100644
--- a/challenge-076/bob-lied/perl/lib/WordSearch.pm
+++ b/challenge-076/bob-lied/perl/lib/WordSearch.pm
@@ -11,27 +11,180 @@ package WordSearch;
use strict;
use warnings;
+use v5.30;
+
+use feature qw/ signatures /;
+no warnings qw/ experimental::signatures /;
+
+use File::Slurper qw / read_lines /;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw();
our @EXPORT_OK = qw();
-sub new
+sub new($class)
{
- my $class = shift;
$class = ref($class) || $class;
my $self = {
- _name1 => $_[0],
+ _grid => [],
+ _wordlist => [],
+ _lastRow => 0,
+ _lastCol => 0,
+
+ _numFound => 0,
+ _foundList => [],
};
bless $self, $class;
return $self;
}
-sub run
+sub loadGrid($self, $gridFile)
+{
+ my @g = read_lines($gridFile);
+ for my $row ( 0 .. $#g )
+ {
+ (my @chars) = split(" ", $g[$row]);
+ for my $col ( 0 .. $#chars )
+ {
+ $self->{_grid}->[$row][$col] = lc($chars[$col]);
+ }
+ }
+ $self->{_lastRow} = scalar( @{$self->{_grid}} ) - 1;
+ $self->{_lastCol} = scalar( @{$self->{_grid}->[0]} ) - 1;
+ return $self;
+}
+
+sub loadWordlist($self, $wordlistFile, $minLength)
+{
+ my @wl = map { lc } grep { length($_) >= $minLength } read_lines($wordlistFile);
+ $self->{_wordlist} = \@wl;
+ return $self;
+}
+
+sub numFound($self)
+{
+ return $self->{_numFound};
+}
+
+sub foundList($self)
+{
+ return $self->{_foundList}
+}
+
+sub _horizontal($self)
+{
+ my @list;
+ my $g = $self->{_grid};
+
+ for my $row ( 0 .. $self->{_lastRow} )
+ {
+ my $s = join('', @{$g->[$row]});
+ push @list, $s, scalar(reverse($s));
+ }
+ return \@list;
+}
+
+sub _vertical($self)
+{
+ my @list;
+ my $g = $self->{_grid};
+
+ for my $col ( 0 .. $self->{_lastCol} )
+ {
+ my @column = map { $g->[$_][$col] } 0 .. $self->{_lastRow};
+ my $s = join('', @column);
+ push @list, $s, scalar(reverse($s));
+ }
+ return \@list;
+}
+
+sub _diagonal($self)
{
- my $self = shift;
- return undef;
+ my @list;
+ my $g = $self->{_grid};
+ my $lastRow = $self->{_lastRow};
+ my $lastCol = $self->{_lastCol};
+
+ # Top left to bottom right along the left edge
+ for my $row ( 0 .. $lastRow )
+ {
+ my $s;
+ my ($r, $c);
+ for ( $r = $row, $c = 0; $r <= $lastRow && $c <= $lastCol ; $r++, $c++ )
+ {
+ $s .= $g->[$r][$c];
+ }
+ push @list, $s, scalar(reverse($s));
+ }
+
+ # Top left to bottom right along the top edge
+ for my $col ( 1 .. $self->{_lastCol} ) #
+ {
+ my $s;
+ my ($r, $c);
+ for ( $r = 0, $c = $col; $r <= $lastRow && $c <= $lastCol ; $r++, $c++ )
+ {
+ $s .= $g->[$r][$c];
+ }
+ push @list, $s, scalar(reverse($s));
+ }
+
+ # Bottom left to top right along left edge
+ for ( my $row = $lastRow; $row >= 0; $row-- )
+ {
+ my $s;
+ my ($r, $c);
+ for ( $r = $row, $c = 0; $r >= 0 && $c <= $lastCol; $r--, $c++ )
+ {
+ $s .= $g->[$r][$c];
+ }
+ push @list, $s, scalar(reverse($s));
+ }
+
+ # Bottom left to top right along the bottom edge
+ for my $col ( 1 .. $lastCol )
+ {
+ my $s;
+ my ($r, $c);
+ for ( $r = $lastRow, $c = $col; $r >= 0 && $c <= $lastCol ; $r--, $c++ )
+ {
+ $s .= $g->[$r][$c];
+ }
+ push @list, $s, scalar(reverse($s));
+ }
+ return \@list;
+}
+
+sub _find($self, $str)
+{
+ my $count = 0;
+ my @found;
+ for my $word ( @{$self->{_wordlist}} )
+ {
+ # Is RE faster than index?
+ if ( index($str, $word) != -1 )
+ {
+ $count++;
+ push @found, $word;
+ }
+ }
+ $self->{_foundList} = \@found;
+
+ return $self->{_numFound} = $count;
+}
+
+
+sub run($self)
+{
+ my $h = $self->_horizontal();
+ my $v = $self->_vertical();
+ my $d = $self->_diagonal();
+
+ # Combine all the strings with a non-word character to separate
+ # them so that we need only one search per word.
+ my $all = join('.', @$h, @$v, @$d);
+ return $self->_find($all);
}
1;