Advertisement
Guest User

Untitled

a guest
Apr 29th, 2017
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.55 KB | None | 0 0
  1. import Data.List
  2. import Data.List.Split (chunksOf)
  3. import Data.Char
  4.  
  5. data Suit = Club | Heart | Diamond | Spade deriving (Show, Read, Eq)
  6. data Sex = Out | In deriving (Show, Read, Eq)
  7. data Side = Side { suit :: Suit , sex :: Sex} deriving (Show, Read)
  8. instance Eq Side where x == y = (suit x == suit y) && (sex x /= sex y)
  9. data Piece = Piece { north :: Side , east :: Side
  10. , south :: Side , west :: Side } deriving (Show, Read, Eq)
  11.  
  12. parsePiece [n,e,s,w] = Piece { north = parseSide n, east = parseSide e
  13. , south = parseSide s, west = parseSide w }
  14. where parseSide c = Side { suit = parseSuit c, sex = parseSex c }
  15. parseSuit c | toLower c == 'c' = Club
  16. | toLower c == 'd' = Diamond
  17. | toLower c == 's' = Spade
  18. | otherwise = Heart
  19. parseSex c = if isLower c then In else Out
  20.  
  21. explore :: ([Piece], [Piece]) -> [([Piece], [Piece])]
  22. explore (list, pool) = concatMap pluck [0..(length pool - 1)]
  23. where pluck i = [ (list ++ [c], excise i pool)
  24. | c <- take 4 $ iterate rotate (pool!!i)
  25. ]
  26. excise i xs = take i xs ++ drop (i+1) xs
  27. rotate piece = Piece { north = east piece, east = south piece
  28. , south = west piece, west = north piece }
  29.  
  30. validate :: Int -> [Piece] -> Bool --validates position n, indexed at zero
  31. validate n xs = (not hasAbove || matchAbove) && (not hasLeft || matchLeft)
  32. where hasLeft = n `mod` 3 /= 0
  33. hasAbove = n >= 3
  34. matchLeft = west (xs!!n) == east (xs!!(n-1))
  35. matchAbove = north (xs!!n) == south (xs!!(n-3))
  36.  
  37. step 0 xs = explore ([], xs)
  38. step n xs = filter (\(xs,_) -> validate n xs) $ concatMap explore $ step (pred n) xs
  39.  
  40. renderGrid :: [Piece] -> [String]
  41. renderGrid = intercalate ["----|-----|----"] . map renderRow . chunksOf 3
  42. where renderRow xs = [ intercalate " | " $ map (\x -> renderSq x!!n) xs | n <- [0..2] ]
  43. renderSq p = [ "." ++ [unParse $ north p] ++ "."
  44. , [unParse $ west p] ++ " " ++ [unParse $ east p]
  45. , "." ++ [unParse $ south p] ++ "."
  46. ]
  47. unParse s
  48. | suit s == Club = f 'c'
  49. | suit s == Spade = f 's'
  50. | suit s == Diamond = f 'd'
  51. | otherwise = f 'h'
  52. where f = if sex s == Out then toUpper else id
  53.  
  54. main = do
  55. let allPieces = map parsePiece $ [ "HDdh", "CHsh", "DCcd", "SDsh", "SDhd", "SShc", "CHdc", "HDcc", "HSsc" ]
  56. let sol = fst $ head $ step 8 allPieces
  57. mapM_ putStrLn $ renderGrid sol
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement