my Str @words = "sowpods.txt".IO.words; #my Str @words = "/usr/share/dict/words".IO.words; #Could also use Unix words file my Str $alphabet = "abcdefghijklmnopqrstuvwxyz"; my Str @vowels = "a", "e", "i", "o", "u", "y"; my Str @vowels2 = "a", "e", "i", "o", "u"; my Int %letterFrequencies = "a" => 9, "b" => 2, "c" => 2, "d" => 4, "e" => 12, "f" => 2, "g" => 3, "h" => 4, "i" => 9, "j" => 1, "k" => 1, "l" => 4, "m" => 2, "n" => 6, "o" => 8, "p" => 2, "q" => 1, "r" => 6, "s" => 6, "t" => 6, "u" => 4, "v" => 2, "w" => 2, "x" => 1, "y" => 2, "z" => 1; sub letters(Str $word --> Seq) { return $word.comb; } sub isVowel(Str $s --> Bool) { for @vowels -> $v { if ($v eq $s) { return True; } } return False; } sub beginsAndEndsWithVowels(Str $word --> Bool) { my Str @letters = letters($word); my $first = @letters.head; my $last = @letters.tail; return (isVowel($first) and isVowel($last)); } sub atLeastHalfVowels(Str $word --> Bool) { my Str @letters = letters($word); my Int $numVowels = 0; for @letters -> $letter { if isVowel($letter) { $numVowels++; } } return $numVowels >= (@letters.elems/2); } sub containsOnlyOneVowel(Str $word --> Bool) { my Str @letters = letters($word); my Int $numVowels = 0; for @letters -> $letter { if $letter (elem) @vowels2 { $numVowels++; } } return $numVowels <= 1; } sub containsQ(Str $word --> Bool) { for letters($word) -> $letter { if ($letter eq "q") { return True; } } return False; } sub usesOneLetterTwice(Str $word --> Bool) { my Str @letters = letters($word); return @letters.unique(:with(&[eq])).elems < @letters.elems; } sub canBeMadeWithLetterCards(Str $w --> Bool) { my Str $word; if (chars($w) > 11) { $word = $w.substr(0, 11); } else { $word = $w; } my Int $totalOverage = 0; my Str @letters = letters($word); for @letters.unique(:with(&[eq])) -> $letter { unless (%letterFrequencies{$letter}:exists) { return False; } my Int $numLetterInWord = 0; for @letters -> $l { if ($letter eq $l) { $numLetterInWord++; } } my Int $numLetterInGame = %letterFrequencies{$letter}; if ($numLetterInWord > $numLetterInGame) { $totalOverage += $numLetterInWord - $numLetterInGame; } } return $totalOverage <= 1; } sub money(Str $word --> Int) { my Int $length = chars($word); given $length { when 3 { return 1 } when 4 { return 2 } when 5 { return 3 } when 6 { return 4 } when 7..* { return 6 } } return 0; } sub stock(Str $word --> Int) { my Int $length = chars($word); given $length { when 6 { return 1 } when 7 { return 1 } when 8..* {return $length - 6 } } return 0; } my Str @elevenLetterWords; for @words -> Str $w { #if (($w ~~ //) or ($w ~~ //) or (any(ords($w)) > 127)) { # say $w; #Locate any bad data points #} if (chars($w) == 11) { @elevenLetterWords.push($w); } } my $elevenLetterWordsSet = @elevenLetterWords.Set; my Str @bestWords; @bestWords.push("Word,Length,Money,Stock,Total"); my Str @bestWordsTable = [ "", "", "", "", "", "", "", "", "", ""]; # Find highest point words for @words -> Str $word { my Int $length = chars($word); if ($length >= 3 and ($length <= 10 or ($length == 11 and usesOneLetterTwice($word)) or ($length == 12 and $word.substr-eq("s", 11) and ($elevenLetterWordsSet (cont) $word.substr(0, 11)) and (usesOneLetterTwice($word.substr(0, 11)))) ) ) { if (canBeMadeWithLetterCards($word)) { my Int $doubles = 0; if (beginsAndEndsWithVowels($word)) { $doubles++; } if (atLeastHalfVowels($word)) { $doubles++; } if (containsQ($word)) { $doubles++; } if (containsOnlyOneVowel($word)) { $doubles++; } if ($doubles >= 3 or ($doubles >= 2 and $length == 12)) { my Int $money = money($word) * 2**$doubles; my Int $stock = stock($word) * 2**$doubles; my Int $total = $money + $stock; my Str $line = "$word,$length,$money,$stock,$total"; @bestWords.push($line); if ($length == 11) { @bestWordsTable.push(""); @bestWordsTable.push(""); @bestWordsTable.push(""); @bestWordsTable.push(""); @bestWordsTable.push(""); @bestWordsTable.push(""); } } } } } @bestWordsTable.push(""); @bestWordsTable.push("
WordMoneyStockTotal
{$word}\${$money}\${$stock}\${$total}
"); spurt "words.txt", @bestWordsTable.join("\n"); spurt "words.csv", @bestWords.join("\n");