aboutsummaryrefslogtreecommitdiff
path: root/challenge-076/bob-lied
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
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')
-rwxr-xr-xchallenge-076/bob-lied/perl/ch-2.pl43
-rw-r--r--challenge-076/bob-lied/perl/lib/WordSearch.pm165
-rw-r--r--challenge-076/bob-lied/perl/t/WordSearch.t15
-rw-r--r--challenge-076/bob-lied/perl/t/searchgrid.txt19
-rw-r--r--challenge-076/bob-lied/perl/t/wordlist.txt54
5 files changed, 281 insertions, 15 deletions
diff --git a/challenge-076/bob-lied/perl/ch-2.pl b/challenge-076/bob-lied/perl/ch-2.pl
index c71a430fe1..3f9acd09bd 100755
--- a/challenge-076/bob-lied/perl/ch-2.pl
+++ b/challenge-076/bob-lied/perl/ch-2.pl
@@ -6,26 +6,51 @@
# Copyright (c) 2020, Bob Lied
#=============================================================================
# Perl Weekly Challenge 076 Task #2 > Word Search
+# Write a script that takes two file names. The first file would contain word
+# search grid as shown below. The second file contains list of words, one
+# word per line. You could even use local dictionary file.
+#
+# Print out a list of all words seen on the grid, looking both orthogonally
+# and diagonally, backwards as well as forwards.
#=============================================================================
use strict;
use warnings;
use v5.30;
-us feature qw/ signatures /;
+use feature qw/ signatures /;
no warnings qw/ experimental::signatures /;
+use Getopt::Long;
+
use lib "lib";
use WordSearch;
-sub Usage { "Usage: $0 args" };
+sub Usage { "Usage: $0 [-l min-length] grid-file wordlist-file" };
+
+my $MinLength = 5;
+my $Verbose = 0;
+GetOptions('length=i' => \$MinLength, "verbose!" => \$Verbose);
+
+my $gridFile = shift;
+my $wordlistFile = shift;
+
+die Usage() unless $gridFile && $wordlistFile;
+die ( Usage(). " $!" ) unless -r $gridFile;
+die ( Usage(). " $!" ) unless -r $wordlistFile;
+
+die Usage() unless ( $MinLength > 0 && $MinLength < 50 );
-my $arg = shift;
-my @list = @ARGV;
+my $wordsearch = WordSearch->new();
+$wordsearch->loadGrid($gridFile);
+$wordsearch->loadWordlist($wordlistFile, $MinLength);
-die Usage() unless $arg;
-die Usage() unless @list;
+my $result = $wordsearch->run();
-my $task = WordSearch->new();
-my $result = WordSearch->run();
-say $result;
+my $count = $wordsearch->numFound();
+my $foundList = $wordsearch->foundList();
+say "Found $count words of length $MinLength or longer";
+if ( $Verbose )
+{
+ say "[" . ($_+1) ."] $foundList->[$_]" for 0 .. $count-1;
+}
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;
diff --git a/challenge-076/bob-lied/perl/t/WordSearch.t b/challenge-076/bob-lied/perl/t/WordSearch.t
index de3e308ed6..7e1320a7ae 100644
--- a/challenge-076/bob-lied/perl/t/WordSearch.t
+++ b/challenge-076/bob-lied/perl/t/WordSearch.t
@@ -11,4 +11,19 @@ use v5.30;
use Test2::V0;
+use WordSearch;
+
+my $ws = WordSearch->new();
+isa_ok($ws, "WordSearch");
+
+$ws->loadWordlist("t/wordlist.txt", 5);
+is( scalar(@{$ws->{_wordlist}}), 54, "loadWordlist size");
+is($ws->{_wordlist}->[0], "aimed", "loadWordlist first word");
+is($ws->{_wordlist}->[53], "wigged", "loadWordlist last word");
+
+$ws->loadGrid("t/searchgrid.txt");
+my $g = $ws->{_grid};
+is ( scalar(@$g), 19, "loadGrid rows");
+is ( scalar(@{$g->[0]}), 16, "loadGrid cols");
+
done_testing();
diff --git a/challenge-076/bob-lied/perl/t/searchgrid.txt b/challenge-076/bob-lied/perl/t/searchgrid.txt
new file mode 100644
index 0000000000..31cf2e0fd8
--- /dev/null
+++ b/challenge-076/bob-lied/perl/t/searchgrid.txt
@@ -0,0 +1,19 @@
+B I D E M I A T S U C C O R S T
+L D E G G I W Q H O D E E H D P
+U S E I R U B U T E A S L A G U
+N G N I Z I L A I C O S C N U D
+T G M I D S T S A R A R E I F G
+S R E N M D C H A S I V E E L I
+S C S H A E U E B R O A D M T E
+H W O V L P E D D L A I U L S S
+R Y O N L A S F C S T A O G O T
+I G U S S R R U G O V A R Y O C
+N R G P A T N A N G I L A M O O
+E I H A C E I V I R U S E S E D
+S E T S U D T T G A R L I C N H
+H V R M X L W I U M S N S O T B
+A E A O F I L C H T O D C A E U
+Z S C D F E C A A I I R L N R F
+A R I I A N Y U T O O O U T P F
+R S E C I S N A B O S C N E R A
+D R S M P C U U N E L T E S I L
diff --git a/challenge-076/bob-lied/perl/t/wordlist.txt b/challenge-076/bob-lied/perl/t/wordlist.txt
new file mode 100644
index 0000000000..e3209b2265
--- /dev/null
+++ b/challenge-076/bob-lied/perl/t/wordlist.txt
@@ -0,0 +1,54 @@
+aimed
+align
+antes
+argos
+arose
+ashed
+blunt
+blunts
+broad
+buries
+clove
+cloven
+constitution
+constitutions
+croon
+depart
+departed
+enter
+filch
+garlic
+goats
+grieve
+grieves
+hazard
+liens
+malign
+malignant
+malls
+margo
+midst
+ought
+ovary
+parted
+patna
+pudgiest
+quash
+quashed
+raped
+ruses
+shrine
+shrines
+social
+socializing
+spasm
+spasmodic
+succor
+succors
+theorem
+theorems
+traci
+tracie
+virus
+viruses
+wigged