no warnings 'misc'; # "Replacement list is longer..." my $tpl = 'abccbccbddb'; my $tpl_fixed = eval qq( \$tpl =~ tr!$tpl!a-z!r ); for ( qw/Mississippi Mossossoppo Panama/ ) { say $tpl_fixed eq eval qq( tr!$_!a-z!r ) ? 'yes' : 'no' } #### 1 0 0 0 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0 1 1 0 0 0 0 1 0 0 1 0 0 1 0 1 #### use strict; use warnings; use feature 'say'; use Data::Dump 'dd'; use Time::HiRes 'time'; use PDL; use List::Util 'reduce'; use constant DICTIONARY => './354984si.ngl'; use constant TEMPLATE => 'neocene'; open my $fh, '<', DICTIONARY; chomp( my @dictionary = <$fh> ); close $fh; my $width = reduce { $a > length $b ? $a : length $b } 0, @dictionary, TEMPLATE; my $height = @dictionary + 1; my $words = zeroes byte, $width, $height; my $data = pack "(A$width)*", @dictionary, TEMPLATE; ${ $words-> get_dataref } = $data; $words-> upd_data; my $t = time; $words-> inplace-> setvaltobad( 32 ); my $table = $words-> dummy( 0, $width ) == $words-> dummy( 1, $width ); $words-> inplace-> setbadtoval( 32 ); $table-> badflag( 0 ); my $mask = ( $table == $table-> slice( '', '', -1 )) -> clump( 2 ) -> bandover -> slice([ 0, -2 ]) -> dummy( 0, $width ); my @found = split ' ', ${ $words-> where( $mask )-> get_dataref }; say time - $t; dd \@found; __END__ 1.04205107688904 ["kaitaka", "lauhala", "metreme", "neocene", "tempete"] #### i.~ 'Mississippi' 0 1 2 2 1 2 2 1 8 8 1 (i.~~.) 'Mississippi' 0 1 2 2 1 2 2 1 3 3 1 #### # words =: 'b' freads 'path_to/354984si.ngl' 354984 template =: 'neocene' ] pattern =: i.~ template 0 1 2 3 1 0 1 find =: dyad def '(#~ (x & -:) @ i.~ @ >) y' pattern find words +-------+-------+-------+-------+-------+ |kaitaka|lauhala|metreme|neocene|tempete| +-------+-------+-------+-------+-------+ 25 (6!:2) 'pattern find words' 0.0499341