-
Notifications
You must be signed in to change notification settings - Fork 0
/
colorMap.hs
99 lines (78 loc) · 3.56 KB
/
colorMap.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
module Main where
import Data.List
import Maybe
import Control.Monad
import Control.Monad.Trans
import Control.Applicative
import System.Console.ANSI
import System.Environment
-- Types
data Country = Finland | Sweden | Norway | Russia | Estonia |
Latvia | Lithuania | Kaliningrad | Belarus | Ukraine |
Poland deriving (Eq, Show, Read)
-- colorsPermitted: [] means any color is allowed
data Node = Node {nameOf::Country,
colorOf::Color,
neighborsOf::[Country],
colorsPermitted::[Color] } deriving (Show)
instance Eq Color where -- Needed for notElem
Black == Black = True
Red == Red = True
Green == Green = True
Yellow == Yellow = True
Blue == Blue = True
Magenta == Magenta = True
Cyan == Cyan = True
White == White = True
_ == _ = False
nameEq :: Country -> Node -> Bool
nameEq name node = name == (nameOf node)
getNeighbors :: [Node] -> Node -> [Node]
getNeighbors graph node = [x | Just x <- map (getNode graph) (neighborsOf node)]
getNode :: [Node] -> Country -> Maybe Node
getNode graph name = find (nameEq name) graph
-- The program
doColors :: Node -> [Color]
doColors node@(Node _ _ _ []) = take 4 [Black .. ]
doColors node@(Node _ _ _ colors) = colors
colorMap :: [Node] -> [[Node]]
colorMap [] = [[]]
colorMap (node:restNodes) = [ node {colorOf = color}:theMap | theMap <- colorMap restNodes
, let colorHood = (map colorOf (getNeighbors theMap node)),
color <- doColors node,
color `notElem` colorHood ]
-- Map data
mapData :: [(Country, [Country], [Color])]
mapData =[(Finland, [Sweden, Norway, Russia], []),
(Sweden, [Finland, Norway], []),
(Norway, [Finland, Sweden, Russia], []),
(Russia, [Estonia, Finland, Latvia, Lithuania, Belarus,
Ukraine, Norway], []),
(Estonia, [Russia, Latvia], []),
(Latvia, [Russia, Estonia, Lithuania, Belarus], []),
(Lithuania, [Latvia, Belarus, Poland, Kaliningrad], []),
(Kaliningrad, [Lithuania, Poland], []),
(Belarus, [Poland, Lithuania, Latvia, Russia, Ukraine], []),
(Ukraine, [Poland, Belarus, Russia], []),
(Poland, [Kaliningrad, Lithuania, Belarus, Ukraine], [])]
theMap :: [Node]
theMap = do (name, neighbors, colors) <- mapData
return (Node name Black neighbors colors)
printNode :: (Show a, Show a1) => a -> a1 -> IO ()
printNode name color = putStrLn $ (show name) ++ ": " ++ (show color)
printWithColor :: Node -> IO ()
printWithColor (Node name color _ _) = do setSGR [SetColor Foreground Vivid color]
printNode name color
printWithoutColor :: Node -> IO ()
printWithoutColor (Node name color _ _) = printNode name color
printMap :: (a -> IO b) -> [a] -> IO ()
printMap printer map = do mapM_ printer map
putStrLn ""
dispatch :: [[Char]] -> (Node -> IO ())
dispatch [] = printWithoutColor
dispatch (arg:xs) =
let (Just printer) = mplus (lookup arg [("color", printWithColor)])
(Just printWithoutColor) in
printer
main = do printer <- dispatch <$> getArgs
forM_ (colorMap theMap) (printMap printer)