Created
August 25, 2020 06:45
-
-
Save occipita/c899478b913b678316ada31085494e87 to your computer and use it in GitHub Desktop.
Scrabble solver in Haskell (cf https://github.com/hyper-blade/scrabble-solvers)
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
Scrabble solver using equivalent algorithms to those at https://github.com/hyper-blade/scrabble-solvers | |
On my system, performance is about 20% slower than C++ and 20% faster than Java. Code length is 1314 characters, sitting between Ruby and PHP in the original list ordered by length (although this has since been removed). |
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
module Main where | |
import System.IO | |
import Data.List | |
import qualified Data.Map.Strict as Map | |
countIn :: Eq a => [a] -> a -> Int | |
countIn l v = length $ filter (== v) l | |
generateWords :: [String] -> String -> [String] | |
generateWords dictionary letters = filter wordMatches dictionary | |
where | |
wordMatches :: String -> Bool | |
wordMatches word = all (letterCountMatches word) word | |
letterCountMatches word letter = letter == '\r' || countIn word letter <= countIn letters letter | |
scores :: Map.Map Char Int | |
scores = Map.fromAscList $ zip ['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] | |
totalScore :: String -> Int | |
totalScore word = sum (map score word) | |
score :: Char -> Int | |
score letter = maybe 0 id (Map.lookup letter scores) | |
sortByScore :: [String] -> [String] | |
sortByScore = sortOn totalScore | |
countDownFrom :: Int -> [Int] | |
countDownFrom 0 = [] | |
countDownFrom n = n : (countDownFrom $ n - 1) | |
showResults :: [String] -> IO () | |
showResults words = putStr $ concatMap showWord (zip words (countDownFrom $length words)) | |
where | |
showWord (word, num) = (show num) ++ ". " ++ word ++ "\n" | |
main :: IO () | |
main = do | |
putStr "Letters: " | |
hFlush stdout | |
letters <- getLine | |
dictionary <- readFile "dictionary.txt" | |
showResults $ sortByScore $ generateWords (lines dictionary) letters |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment