-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathDay03.hs
55 lines (44 loc) · 1.2 KB
/
Day03.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
{-# LANGUAGE TypeApplications #-}
import Data.Bifunctor
import Data.Char as C
import Data.List as L
import System.Environment
increaseBit (b0, b1) 0 = (b0 + 1, b1)
increaseBit (b0, b1) 1 = (b0, b1 + 1)
pickBest (b0, b1) = if b1 >= b0 then 1 else 0
mostCommon = fmap (pickBest . L.foldl' increaseBit (0, 0)) . L.transpose
leastCommon = fmap (1 -)
toDec = L.foldl' (\n b -> n * 2 + b) 0
type Bin = [Int]
type BinMat = [[Int]]
solve1 :: BinMat -> Int
solve1 xs = gamma * epsilon
where
t = mostCommon xs
gamma = toDec t
epsilon = toDec $ leastCommon t
{- Part two -}
go :: [(Bin, Bin)] -> (BinMat -> Bin) -> Bin
go [(first, _)] criteria = first
go xs criteria = go nextList criteria
where
nextBit = head . criteria . fmap snd $ xs
nextList = fmap (second tail) . filter ((nextBit ==) . head . snd) $ xs
solve2 :: BinMat -> Int
solve2 xs = oxygen * co2
where
applyCriteria = toDec . go (fmap (\x -> (x, x)) xs)
oxygen = applyCriteria mostCommon
co2 = applyCriteria (leastCommon . mostCommon)
solutions =
[ solve1
, solve2
]
main :: IO ()
main = do
idx <- read . head <$> getArgs
print
. (solutions !! (idx - 1))
. fmap (fmap ((\x -> x - C.ord '0') . C.ord))
. lines
=<< getContents