1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
import Data.Ord
import Data.List
data Peg = Red | Green | Blue | White | Yellow | Orange
deriving (Eq, Ord, Show)
data Code = Code [Peg] deriving Show
data Response = Respond (Int, Int) deriving Eq
intersect x y = intersect' (sort x) (sort y)
intersect' [] _ = []
intersect' _ [] = []
intersect' (x:xs) (y:ys)
| (x == y) = x : (intersect' xs ys)
| (x < y) = intersect' xs (y:ys)
| (x > y) = intersect' ys (x:xs)
diff (Code x) (Code y) = Respond (reds, whites)
where reds = length [t | t <- zip x y, fst t == snd t]
whites = (length $ Main.intersect x y) - reds
code_space = [Code [a,b,c,d] | a <- ps, b <- ps, c <- ps, d <- ps]
where ps = [Red, Green, Blue, White, Yellow, Orange]
space `when` [] = space
space `when` ((code, response):rest) =
[c | c <- space, diff c code == response] `when` rest
space `pivot_on` code =
[space `when` [(code, response)] | response <- all_responses]
where all_responses = [Respond (r, w) | r <- [0..4], w <- [0..4]]
choose_from space =
fst $ minimumBy (comparing snd)
[(code, maximum $ map (length) (space `pivot_on` code)) | code <- space]
solve_with clues = do
putStrLn ("It looks like there are "
++ (show $ length code_space') ++ " possible codes left, "
++ "after " ++ (show $ length clues) ++ " clues. Hmm.")
putStrLn ("I'll guess " ++ (show best_guess) ++ ".")
putStrLn "How many colors are in the correct location?"
reds <- getLine
if (read reds) == 4 then putStrLn "Woohoo!"
else do
putStrLn "How many colors are in incorrect locations?"
whites <- getLine
solve_with ((best_guess, Respond (read reds, read whites)):clues)
where code_space' = code_space `when` clues
best_guess = choose_from code_space'
main = solve_with []
|