Skip to content

Instantly share code, notes, and snippets.

@andrewthad
Created April 21, 2017 17:19
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andrewthad/129968be7936addfd4de8b8a4706f778 to your computer and use it in GitHub Desktop.
Save andrewthad/129968be7936addfd4de8b8a4706f778 to your computer and use it in GitHub Desktop.
Age Riddle
-- This is a riddle about people's ages that I made up. Below, we solve it
-- using the monadic interface to lists. Here it is:
--
-- * Jordan is either 13 years old or 16 years old
-- * Shen is between 3 and 5 years older than Jordan (inclusive bounds)
-- * Claudia is between 6 and 9 years younger than Jordan's age plus Shen's age.
-- * I am as old as the three aforementioned people combined.
--
-- Given the provided information, I could have many possible ages. The monad
-- instance for list models this kind of nondeterminism well. Run the example
-- to figure out how old I may be.
--
-- Notice that the two provided solution do not produce a list with my
-- possible ages in the same order. This is because of the delta for Claudia,
-- which is considered in a different order in the two solutions.
--
-- The astute reader may notice that this problem is more accurately modeled
-- by sets than by lists. Sadly, sets in haskell do not admit a monadic
-- interface. You can use google to learn more about this problem, but don't
-- get to caught up in it. In the grand scheme of things, it doesn't matter
-- that much.
import Data.List (sort)
main :: IO ()
main = do
putStrLn "Clear Solution:"
print ageRiddle
putStrLn "Terse Solution:"
print ageRiddleTerse
putStrLn "Do the solutions agree:"
if sort ageRiddle == sort ageRiddleTerse
then putStrLn "Yes"
else putStrLn "No"
ageRiddle :: [Int]
ageRiddle = do
jordan <- [13,16]
deltaShen <- [3..5]
shen <- [jordan + deltaShen]
deltaClaudia <- [6..9]
claudia <- [jordan + shen - deltaClaudia]
[jordan + shen + claudia]
ageRiddleTerse :: [Int]
ageRiddleTerse = do
jordan <- [13,16]
shen <- map (\x -> x + jordan) [3..5]
claudia <- map (\x -> x + jordan + shen) [(-9)..(-6)]
[jordan + shen + claudia]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment