Created
February 13, 2019 04:04
-
-
Save sgoguen/9c2386328b410435f2977947e5fe369c to your computer and use it in GitHub Desktop.
Wheel of Fortune Solver
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// First, clone the word list project here: https://github.com/dwyl/english-words.git | |
// Then save this file in the same folder and run! | |
open System.IO | |
// Ok... Here's how it works... | |
// First, we load all the words from the Moby text fil | |
let allTheWords = File.ReadAllLines("words.txt") | |
// Next, we need a function that extracts a char *set* from | |
// a word. | |
let wordToSet(word:string) = | |
// Let's remove the _ chars and pipe the char array to Set.ofArray | |
word.Replace("_", "").ToCharArray() |> Set.ofArray | |
// Here we turn a list of words into a char set | |
let getAllUsedLetters words = | |
words | |
|> Array.map wordToSet | |
// We use the fold operator to turn the set list | |
// into a single set. Set.union merges two sets | |
// We need to seed our fold with Set.empty | |
|> Array.fold Set.union Set.empty | |
// We need to know all the letters available | |
let allLetters = "qwertyuiopasdfghjklzxcvbnm" |> wordToSet | |
// Now the magic. Given any word, and a set of unused letters, | |
// we want to create a regex that lets us look for words | |
// that might match our word. | |
let partialWordToRegex (unusedLetters:Set<char>) (word:string) = | |
// Give me a list of letters | |
let letters = [ for l in Set.toSeq(unusedLetters) -> l ] | |
// Turn it into a regex fragment [abeksuf] | |
let emptyChar = "[" + System.String.Concat(letters) + "]" | |
// Replace every _ in the word with our regex pattern | |
System.Text.RegularExpressions.Regex("^" + word.Replace("_", emptyChar) + "$") | |
// Given a list of words, give us a list of regexes to find | |
// words in our dictionary. | |
let makeRegex (words:string[]) = | |
// Create a set of all the used letters so far | |
let usedLetters = getAllUsedLetters words | |
// Now, get us a set of unused letters using Set.difference | |
let unusedLetters = usedLetters |> Set.difference allLetters | |
// Then return our regex list | |
[| for word in words do | |
yield word |> partialWordToRegex unusedLetters |] | |
// Finally, we do a simple search. | |
let find (inWords:string) = | |
// Get our words | |
let inWords = inWords.ToLower().Split(' ') | |
for i in 0..inWords.Length - 1 do | |
let word = inWords.[i] | |
let r = (inWords |> makeRegex).[i] | |
// Find each word | |
let found = allTheWords | |
|> Array.filter (fun w -> r.IsMatch(w.ToLower())) | |
|> Array.sortDescending | |
// And print. | |
printfn "%i - %s (%i) %A" i word (found.Length) found | |
// Voila!!! | |
// I wrote up some F# functions to help my wife play | |
// Wheel of Fortune when she gets stuck, and she's stuck | |
// on this particular puzzle. | |
// I think I nearly have it. This program basically looks through | |
// the Moby word list and search for words that match these patterns. | |
// I'll show you how it works... | |
find "so_t_er_ fr_e_ fs_ar_ ca__ fo_ s_ea_ers wxgb" | |
// Southern Fried FSharp Call for Speakers! | |
/// I solved it! | |
/// | |
/// Also, you have until Friday to submit your talk for | |
/// Southern Fried F# --- April 13 - Raleigh, NC | |
/// | |
/// See you there!!!! | |
// The words below are the suggestions |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment