-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay3.hs
53 lines (42 loc) · 1.33 KB
/
Day3.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
module Day3
( part1
, part2
) where
import Data.List (group, sort, transpose)
import Debug.Trace
import Helpers.Parsers (alphaNum)
type Bin = [Bool]
toDec :: Bin -> Int
toDec =
foldl
(\b a ->
(if a
then 1
else 0) +
2 * b)
0
filterOxygen :: [Bin] -> Int -> Bin
filterOxygen list index
| length list == 1 = head list
| 2 * length (filter (!! index) list) >= length list =
filterOxygen (filter (!! index) list) (index + 1)
| otherwise = filterOxygen (filter (\x -> not $ x !! index) list) (index + 1)
filterCO2 :: [Bin] -> Int -> Bin
filterCO2 list index
| length list == 1 = head list
| 2 * length (filter (!! index) list) >= length list =
filterCO2 (filter (\x -> not $ x !! index) list) (index + 1)
| otherwise = filterCO2 (filter (!! index) list) (index + 1)
rate2 :: [Bin] -> Int
rate2 bin = (toDec . filterOxygen bin $ 0) * (toDec . filterCO2 bin $ 0)
toRate1 :: Bin -> Int
toRate1 bin = toDec bin * toDec (map not bin)
rate1 :: [Bin] -> Int
rate1 =
toRate1 . map ((\(a:b:_) -> length b > length a) . group . sort) . transpose
readBin :: String -> [Bin]
readBin = map (map (== '1') . concat) . alphaNum
part1 :: Bool -> String -> String
part1 _ = show . rate1 . readBin
part2 :: Bool -> String -> String
part2 _ = show . rate2 . readBin