Skip to content

Instantly share code, notes, and snippets.

@olligobber
Created January 24, 2018 06:58
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 olligobber/f75f73ea863a10f032b0e594cf6b123d to your computer and use it in GitHub Desktop.
Save olligobber/f75f73ea863a10f032b0e594cf6b123d to your computer and use it in GitHub Desktop.
Determines which set of 5 cards can be used such that the sum of every size 2 and size 3 subset is unique
type Subset = [Int]
-- choose n xs is a list of all ways of choosing n things from xs
choose :: Int -> [a] -> [[a]]
choose 0 _ = [[]] -- one way to choose nothing
choose _ [] = [] -- no way to choose non-zero number of things from nothing
choose n (x:xs)
| n < 0 = undefined -- no way to choose negative number of things
| otherwise = with ++ without where
with = (x:) <$> choose (n-1) xs -- choices including x
without = choose n xs -- choices ignoring x
-- getsum i xs uses the indices in i to pick a subset of xs and adds them
sumsubset :: Num a => Subset -> [a] -> a
sumsubset [] _ = 0 -- empty sum
sumsubset (i:is) xs = xs!!i + sumsubset is xs
-- duplicates xs is true iff xs contains two identical elements
duplicates :: Eq a => [a] -> Bool
duplicates [] = False
duplicates (x:xs)
| duplicates xs = True -- the tail of the list contains duplicates
| otherwise = x `elem` xs
-- every pair and triple from 5 elements
subsets :: [Subset]
subsets = choose 2 [0..4] ++ choose 3 [0..4]
-- determines if the sum of every pair and triple of xs is unique
condition :: [Int] -> Bool
condition xs = not . duplicates $ sumsubset <$> subsets <*> [xs]
-- Pack of cards
cards :: [Int]
cards = [1..13]
main :: IO ()
main = print $ filter condition (choose 5 cards)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment