[Haskell-beginners] Einstein's Problem
Daniel Fischer
daniel.is.fischer at web.de
Wed Dec 23 19:34:52 EST 2009
Am Mittwoch 23 Dezember 2009 20:46:51 schrieb Patrick LeBoutillier:
> Hi all,
>
> I've been working hard at trying to solve Einstein's problem
> (http://www.davar.net/MATH/PROBLEMS/EINSTEIN.HTM) if an efficient
> manner using Haskell.
>
> I have posted my solution here: http://haskell.pastebin.com/m3ff1973a
>
> This exercise has been a real eye opener for me, especially for
> learning to work with the Maybe and List monads.
>
> I'm looking for suggestions for making the "test" function nicer. In
> order to make my solution fast, I generate my test cases
> incrementally,
> thereby elimating most of the cases early on. However the function
> looks funny (deeply nested).
Instead of
if checkStreet s then ... else [], use Control.Monad.guard:
test = do
ds <- drinkPerms
ns <- nationPerms
let s = Street $ makeHouses ds ns [] [] []
guard (checkStreet s)
ss <- smokePerms
...
>
> I'm also open to any comments about making better use of the different
> Haskell idioms.
There is a function permutations in Data.List, you can use that instead of writing your
own (except if you want the permutations in a different order).
xxxPerms = permutationsOf [toEnum 0 .. toEnum 4] :: [[XXX]] isn't particularly nice,
better give the first and last constructor of each type or define
allPerms :: (Enum a, Bounded a) => [[a]]
allPerms = permutationsOf [minBound .. maxBound]
and derive also Bounded for your types.
nationPerms = filter rule1 $ permutationsOf [toEnum 0 .. toEnum 4] :: [[Nation]]
where rule1 ns = (ns !! 0) == Norway
is very inefficient, make that
nationPerms = map (Norway:) $ permutationsOf [England .. Denmark]
(yes, it's not so terrible for only five items, still it made me wince).
Similar for drinkPerms.
checkCond (f,c) h = fmap (== c) (f h)
~>
checkCond (f,c) = fmap (== c) . f
>
>
> Thanks a lot,
>
> Patrick
More information about the Beginners
mailing list