#!/usr/bin/perl use warnings; use strict; use DBI; #### configure for your game here my $min = 3; my @letters = map { $_ eq 'q' ? 'qu' : $_ } map lc, split '', 'abcdefghijklmnop'; my $muddled = 0; my $common = 0; my $safe = 0 ; #### my(%found, %all, %limits); my $file = '/Users/pudge/Downloads/words.sql'; my $dbh = DBI->connect("dbi:SQLite:dbname=$file"); my %seen; for my $l (@letters) { next if $seen{$l}++; my $st = "SELECT * FROM ${l}_words"; my @arr = $dbh->selectall_arrayref($st); for my $a (@arr) { for my $w (@$a) { next if $common && !$w->[2]; next if $safe && $w->[3]; my $word = $l . $w->[0]; $all{$word} = 1; limit($word); if ($w->[1]){ $all{$word . 's'} = 1; $limits{$word . 's'} = 1; } } } } printf "\nFetched %d words from dictionary. Finding all $min+ words that match:\n\n", scalar keys(%all); # sure there is a good algorithm for this ... but this was easier my %matrix = ( 1 => [2,5,6], 2 => [1,3,5,6,7], 3 => [2,4,6,7,8], 4 => [3,7,8], 5 => [1,2,6,9,10], 6 => [1,2,3,5,7,9,10,11], 7 => [2,3,4,6,8,10,11,12], 8 => [3,4,7,11,12], 9 => [5,6,10,13,14], 10 => [5,6,7,9,11,13,14,15], 11 => [6,7,8,10,12,14,15,16], 12 => [7,8,11,15,16], 13 => [9,10,14], 14 => [9,10,11,13,15], 15 => [10,11,12,14,16], 16 => [11,12,15] ); # use same algo for muddled, just make every letter adjacent to every other if ($muddled) { %matrix = (); my @foo = 1 .. scalar(@letters); $matrix{$_} = \@foo for @foo; } getnext($letters[$_-1], $_) for (1..16); print " * $_\n" for sort keys %found; printf "\nDone. %d words found.\n\n", scalar keys(%found); sub getnext { my($pword, $num, %used) = @_; $used{$num} = 1; for my $n (@{ $matrix{$num} }) { next if $used{$n}; my $nword = $pword; $nword .= $letters[$n-1]; next unless length($nword) < $min || $limits{$nword}; $found{$nword} = 1 if length($nword) >= $min && $all{$nword}; getnext($nword, $n, %used); } } sub limit { my($word) = @_; for my $i (reverse($min .. length($word))) { my $w = substr($word, 0, $i); last if $limits{$w}; $limits{$w} = 1; } } __END__