I had need to browse, repeatedly for different numbers, a list of words and phrases whose Scrabble scores[1] were that number. So I wrote this little script. It's not much but perhaps can help someone. And obviously if anyone has any corrections or suggestions, I'm all ears.

use strict; use warnings; use Unicode::Normalize; use List::Util 'sum0'; my %values; @values{'A'..'Z'} = @values{'a'..'z'} = (1, 3, 3, 2, 1, 4, 2, 4, 1, 8, + 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10); print 'What score? '; my $score = <>; $score =~ s/^(0|\s)+//; $score =~ s/\s+$//; die "um, a positive integer$/" unless $score =~ /^[0-9]+$/; print 'What length, at least? (or blank for 1) '; my $min = <>; $min =~ s/^(0|\s)+//; $min =~ s/\s+$//; $min = 1 unless $min =~ /^[0-9]+$/; print 'What length, at most? (or blank for no max) '; my $max = <>; $max =~ s/^(0|\s)+//; $max =~ s/\s+$//; $max = 0 unless $max =~ /^[0-9]+$/; print 'What regex? (no slashes; or blank for any) '; my $re = <>; chomp $re; $re = '.*' if $re eq ''; $re = qr/$re/i; my %good; my %dicts = ( # a hash of pairs like: '/path/to/wordlist' => 'nickname_for_the_w +ordlist' ); for my $file (keys %dicts) { open my $fh, '<', $file or next; while (<$fh>) { next if /\d/; s/\W|_//g; $_ = NFKD $_; s/\pM//g; next unless $min <= length; next unless $max == 0 or $max >= length; next unless $score == sum0 map $values{$_}, split //; next unless m/$re/; undef $good{lc$_}{$dicts{$file}} } } $, = v9; $\ = $/; print $_, join ',', sort keys %{$good{$_}} for sort keys %good

[1] theoretical Scrabble scores… not necessarily are all such words valid in Scrabble

$_="msh210";$"=$\;@_=@{[split//,uc]}[2,0];$_="@_$\1";$\=$/;++$_[0]for$...1;print lc substr crypt($_,"@_"),1,6