diff --git a/haskellAoC/inputs/2015/13 b/haskellAoC/inputs/2015/13 new file mode 100644 index 0000000..a6f9c66 --- /dev/null +++ b/haskellAoC/inputs/2015/13 @@ -0,0 +1,56 @@ +Alice would gain 2 happiness units by sitting next to Bob. +Alice would gain 26 happiness units by sitting next to Carol. +Alice would lose 82 happiness units by sitting next to David. +Alice would lose 75 happiness units by sitting next to Eric. +Alice would gain 42 happiness units by sitting next to Frank. +Alice would gain 38 happiness units by sitting next to George. +Alice would gain 39 happiness units by sitting next to Mallory. +Bob would gain 40 happiness units by sitting next to Alice. +Bob would lose 61 happiness units by sitting next to Carol. +Bob would lose 15 happiness units by sitting next to David. +Bob would gain 63 happiness units by sitting next to Eric. +Bob would gain 41 happiness units by sitting next to Frank. +Bob would gain 30 happiness units by sitting next to George. +Bob would gain 87 happiness units by sitting next to Mallory. +Carol would lose 35 happiness units by sitting next to Alice. +Carol would lose 99 happiness units by sitting next to Bob. +Carol would lose 51 happiness units by sitting next to David. +Carol would gain 95 happiness units by sitting next to Eric. +Carol would gain 90 happiness units by sitting next to Frank. +Carol would lose 16 happiness units by sitting next to George. +Carol would gain 94 happiness units by sitting next to Mallory. +David would gain 36 happiness units by sitting next to Alice. +David would lose 18 happiness units by sitting next to Bob. +David would lose 65 happiness units by sitting next to Carol. +David would lose 18 happiness units by sitting next to Eric. +David would lose 22 happiness units by sitting next to Frank. +David would gain 2 happiness units by sitting next to George. +David would gain 42 happiness units by sitting next to Mallory. +Eric would lose 65 happiness units by sitting next to Alice. +Eric would gain 24 happiness units by sitting next to Bob. +Eric would gain 100 happiness units by sitting next to Carol. +Eric would gain 51 happiness units by sitting next to David. +Eric would gain 21 happiness units by sitting next to Frank. +Eric would gain 55 happiness units by sitting next to George. +Eric would lose 44 happiness units by sitting next to Mallory. +Frank would lose 48 happiness units by sitting next to Alice. +Frank would gain 91 happiness units by sitting next to Bob. +Frank would gain 8 happiness units by sitting next to Carol. +Frank would lose 66 happiness units by sitting next to David. +Frank would gain 97 happiness units by sitting next to Eric. +Frank would lose 9 happiness units by sitting next to George. +Frank would lose 92 happiness units by sitting next to Mallory. +George would lose 44 happiness units by sitting next to Alice. +George would lose 25 happiness units by sitting next to Bob. +George would gain 17 happiness units by sitting next to Carol. +George would gain 92 happiness units by sitting next to David. +George would lose 92 happiness units by sitting next to Eric. +George would gain 18 happiness units by sitting next to Frank. +George would gain 97 happiness units by sitting next to Mallory. +Mallory would gain 92 happiness units by sitting next to Alice. +Mallory would lose 96 happiness units by sitting next to Bob. +Mallory would lose 51 happiness units by sitting next to Carol. +Mallory would lose 81 happiness units by sitting next to David. +Mallory would gain 31 happiness units by sitting next to Eric. +Mallory would lose 73 happiness units by sitting next to Frank. +Mallory would lose 89 happiness units by sitting next to George. diff --git a/haskellAoC/src/Y2015/Day13.hs b/haskellAoC/src/Y2015/Day13.hs new file mode 100644 index 0000000..c87cf9d --- /dev/null +++ b/haskellAoC/src/Y2015/Day13.hs @@ -0,0 +1,60 @@ +module Y2015.Day13 (y15day13) where + +import qualified Data.HashMap.Strict as HMap + +import Data.List + +type PeopleHappiness = HMap.HashMap (String, String) Int + +-- Input line -> ((person 1 name, person 2 name), happiness) +parseLine :: String -> ((String, String), Int) +parseLine input = ((p1, p2), signedNb) + where input' = words input + p1 = input' !! 0 + p2 = init $ input' !! 10 + nb = read $ input' !! 3 :: Int + signedNb = case (input' !! 2) of + "gain" -> nb + "lose" -> 0 - nb + w -> error ("invalid word at offset 2: " ++ w) + +uniquePeople :: [((String, String), Int)] -> [String] +uniquePeople ps = nub $ concatMap (\((p1, p2), _) -> [p1, p2]) ps + +-- Sum each couples of people to get an overall happiness score for any query order +combinePeople :: PeopleHappiness -> [((String, String), Int)] -> PeopleHappiness +combinePeople ph [] = ph +combinePeople ph (((p1, p2), h):t) = combinePeople newPH t + where newPH = HMap.insert (p1, p2) newH $ HMap.insert (p2, p1) newH $ ph + newH = case (p1, p2) `HMap.lookup` ph of + Just h' -> h + h' + Nothing -> h + +-- Get the total score of happiness for a given permutation of people +computeDispositionScore :: PeopleHappiness -> [String] -> Int +computeDispositionScore ph ps = endsScore + (fn ps) + where endsScore = ph HMap.! (head ps, last ps) + fn (p1:p2:t) = ph HMap.! (p1, p2) + (fn (p2:t)) + fn _ = 0 + +-- Add happiness mappings for me + each people +happinessWithMe :: [String] -> PeopleHappiness +happinessWithMe [] = HMap.empty +happinessWithMe (p:ps) = HMap.insert (p, "ME") 0 $ HMap.insert ("ME", p) 0 $ happinessWithMe ps + +y15day13 :: [String] -> (String, String) +y15day13 input = (part1, part2) + where part1 = show $ bestCombination + part2 = show $ bestCombinationP2 + + input' = map parseLine input + + -- Naive, "bruteforcing" implementation: we could at the very least avoid permutations that are simply rotations + -- but given the low volume, it works... ¯\_(ツ)_/¯ + people = uniquePeople input' + peopleHappiness = combinePeople HMap.empty input' + bestCombination = maximum $ map (computeDispositionScore peopleHappiness) $ permutations people + + peopleP2 = "ME":people + peopleHappinessP2 = HMap.union peopleHappiness $ happinessWithMe people + bestCombinationP2 = maximum $ map (computeDispositionScore peopleHappinessP2) $ permutations peopleP2 diff --git a/haskellAoC/src/Y2015/Days.hs b/haskellAoC/src/Y2015/Days.hs index dedc15a..a2ab3e6 100644 --- a/haskellAoC/src/Y2015/Days.hs +++ b/haskellAoC/src/Y2015/Days.hs @@ -12,7 +12,7 @@ import Y2015.Day09 import Y2015.Day10 import Y2015.Day11 import Y2015.Day12 - +import Y2015.Day13 year2015 :: String -> [String] -> (String, String) year2015 "01" = y15day01 @@ -27,3 +27,4 @@ year2015 "09" = y15day09 year2015 "10" = y15day10 year2015 "11" = y15day11 year2015 "12" = y15day12 +year2015 "13" = y15day13