Skip to content

Instantly share code, notes, and snippets.

@etrepum
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save etrepum/5bfedc8bbe576f89fe09 to your computer and use it in GitHub Desktop.
Save etrepum/5bfedc8bbe576f89fe09 to your computer and use it in GitHub Desktop.
-- version 3
import qualified Data.Set as S
import Data.List (partition)
import System.Environment (getArgs)
data LWG = LWG { _lion, _wolf, _goat :: {-# UNPACK #-} !Int }
deriving (Show, Ord, Eq)
lionEatGoat, lionEatWolf, wolfEatGoat :: LWG -> LWG
lionEatGoat (LWG l w g) = LWG (l - 1) (w + 1) (g - 1)
lionEatWolf (LWG l w g) = LWG (l - 1) (w - 1) (g + 1)
wolfEatGoat (LWG l w g) = LWG (l + 1) (w - 1) (g - 1)
stableState :: LWG -> Bool
stableState (LWG l w g) = length (filter (==0) [l, w, g]) >= 2
validState :: LWG -> Bool
validState (LWG l w g) = all (>=0) [l, w, g]
possibleMeals :: LWG -> [LWG]
possibleMeals state =
filter validState .
map ($ state) $ [lionEatGoat, lionEatWolf, wolfEatGoat]
ordNub :: Ord a => [a] -> [a]
ordNub = S.toList . S.fromList
endStates :: [LWG] -> [LWG]
endStates states
| not (null stable) = stable
| not (null unstable) = endStates (concatMap possibleMeals unstable)
| otherwise = []
where (stable, unstable) = partition stableState (ordNub states)
main :: IO ()
main = do
[l, w, g] <- map read `fmap` getArgs
mapM_ print . endStates $ [LWG l w g]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment