Skip to content

Instantly share code, notes, and snippets.

@gcmurphy
Last active August 29, 2015 14:07
Show Gist options
  • Save gcmurphy/2ce934eb08f59cb2aa77 to your computer and use it in GitHub Desktop.
Save gcmurphy/2ce934eb08f59cb2aa77 to your computer and use it in GitHub Desktop.
CS194 Homework week 2 (most of it)
module HW02 where
import Words
import Data.List
-- Though a Scrabble hand is the same Haskell type as a Scrabble word, they
-- have different properties. Specifically, a hand is unordered whereas a word
-- is ordered. We denote this distinction by using a type synonym to talk
-- about hands, even though we could just say `String`.
type Hand = [Char]
-- A `Template` is like a word, but it has '?' characters in some places as
-- placeholders for letters from a player's hand. Because real words do not
-- have '?' characters, we use another type synonym to track this distinction.
type Template = String
-- A 'STemplate' is like a template, but it has markers to indicate four kinds
-- of special board locations: double-letter noted with 'D', triple-letter
-- noted with 'T', double-word noted with '2', and triple-word noted with '3'.
-- For matching, these behave just like '?' does -- they can be filled in with
-- any letter. But, when scoring, any letter played on a 'D' gets double its
-- value, and any letter played on a 'T' gets triple its value. If any square
-- in the template is a '2', the whole word's value is doubled; if any square
-- in the template is a '3', the whole word's score is tripled. If multiple of
-- these special squares are in the same word, the effects multiply.
type STemplate = Template
-- Write your code below:
useLetter :: Hand -> Int -> Hand
useLetter [] _ = []
useLetter xs n = ys ++ tail zs
where (ys,zs) = splitAt n xs
-- | Returns true when word can be formed by hand
-- >>> formableBy "fun" ['x','n','i','f','u','e','l']
-- True
-- >>> formableBy "haskell" ['k', 'l', 'e', 'h', 'a', 'y', 's']
-- False
formableBy :: String -> Hand -> Bool
formableBy [] _ = True
formableBy word [] = False
formableBy (x:xs) letters = case elemIndex x letters of
Just n -> formableBy xs (useLetter letters n)
Nothing -> False
-- | Returns number words from the supplied letters
-- >>> wordsFrom ['h','e', 'l', 'l', 'o']
-- ["eh","el","ell","he","hell","hello","helo","ho","hoe","hole","lo","oe","oh","ole"]
wordsFrom :: Hand -> [String]
wordsFrom hand = filter (`formableBy` hand) allWords
-- | Returns true if word can be made by hand + template
-- >>> wordFitsTemplate "??r?" ['c', 'x', 'e', 'a', 'b', 'c', 'l'] "care"
-- True
-- >>> wordFitsTemplate "??r?" ['c', 'x', 'e', 'a', 'b', 'c', 'l'] "car"
-- False
-- >>> wordFitsTemplate "let" ['c', 'x', 'e', 'a', 'b', 'c', 'l'] "let"
-- True
wordFitsTemplate :: Template -> Hand -> String -> Bool
wordFitsTemplate [] _ [] = True
wordFitsTemplate (a:_) _ [] = False
wordFitsTemplate [] _ (a:_) = False
wordFitsTemplate (x:xs) letters (y:ys)
| x == y = wordFitsTemplate xs letters ys
| x == '?' = case elemIndex y letters of
Just n -> wordFitsTemplate xs (useLetter letters n) ys
Nothing -> False
| otherwise = False
-- | Will return true if word matches template
-- >>> wordsFittingTemplate "??r?" ['c', 'x', 'e', 'a', 'b', 'c', 'l']
-- ["acre","bare","carb","care","carl","earl"]
wordsFittingTemplate :: Template -> Hand -> [String]
wordsFittingTemplate template letters = filter fn allWords
where fn = (\word -> wordFitsTemplate template letters word)
-- | Compute the scrabble value of a word
-- >>> scrabbleValueWord "care"
-- 6
-- >>> scrabbleValueWord "quiz"
-- 22
scrabbleValueWord :: String -> Int
scrabbleValueWord word = sum $ map scrabbleValue word
-- | Take only the best words
-- >>> bestWords (wordsFittingTemplate "??r?" ['c', 'x', 'e', 'a', 'b', 'c', 'l'])
-- ["carb"]
-- >>> bestWords ["cat", "rat", "bat"]
-- ["bat", "cat"]
-- >>> bestWords []
-- []
bestWords :: [String] -> [String]
bestWords ws = let scores = map scrabbleValueWord ws
scored = zip ws scores
highest = maximum( scores ) in
fst $ unzip $ filter (\(w, s) -> s >= highest ) scored
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment