summaryrefslogtreecommitdiff
path: root/2015/day13.hs
blob: 6ffc440190f4dec6a718cc8012dac7aa2e1632fa (plain)
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
import Data.Maybe
import Control.Monad
import qualified Data.Map.Strict as Map
import Data.Map.Strict ((!))

includeSelf :: Bool
includeSelf = True

getnames :: [String] -> Map.Map String Int
getnames [] = Map.empty
getnames (l:ls) = Map.insert (head (words l)) (Map.size n) n
    where n = getnames ls

parse :: [String] -> Map.Map String Int -> Map.Map (Int,Int) Int
parse [] names = Map.empty
parse (l:ls) names = Map.insert (a,b) h $ parse ls names
    where w = words l
          an = head w
          bn = init $ last w
          a = names ! an
          b = names ! bn
          neg = w!!2 == "lose"
          hp = read $ w!!3
          h = if neg then -hp else hp

permutations :: [a] -> [[a]]
permutations [] = []
permutations [v] = [[v]]
permutations a = concat [map ((a!!i):) $ permutations $ take i a ++ drop (i + 1) a | i <- [0..(length a - 1)]]

compute :: [Int] -> Map.Map (Int,Int) Int -> Int
compute [] _ = 0
compute [_] _ = 0
compute l hm = fst $ foldl (\(acc,prev) i -> (acc + hm ! (prev,i) + hm ! (i,prev),i)) (0,last l) l

addSelf :: Int -> Map.Map (Int,Int) Int -> Map.Map (Int,Int) Int
addSelf n m = foldl (\mp i -> Map.insert (0,i) 0 $ Map.insert (i,0) 0 mp) m [1..n]

day13 :: IO ()
day13 = do
    input <- liftM lines $ readFile "day13.txt"
    let names = getnames input
    let hapmap = if includeSelf then addSelf (length names) parsed else parsed where parsed = parse input names
    let perm = permutations [(if includeSelf then 0 else 1)..(length names)]
    print $ maximum [compute p hapmap | p <- perm]

main = day13