-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathday10.hs
More file actions
50 lines (39 loc) · 1.52 KB
/
Copy pathday10.hs
File metadata and controls
50 lines (39 loc) · 1.52 KB
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
#!/usr/bin/env runghc
{-# LANGUAGE LambdaCase #-}
module Main where
import Data.Bifunctor (bimap)
import Data.Bits (Bits (bit, shiftL, shiftR, xor, (.&.), (.|.)))
import Data.List (foldl', uncons, zipWith)
import Data.Maybe (mapMaybe)
import Data.Sequence (Seq (..), (><))
import Data.Sequence qualified as Seq
import Data.Set qualified as S
data Machine = Machine
{presses :: Int, lights :: [Int], buttons :: Seq [Int], jotages :: [Int]}
deriving (Show, Eq, Ord)
main = interact (unlines . sequence [part1, part2] . parse)
part1 :: [Machine] -> String
part1 = ("Part 1: " ++) . show . sum . map (presses . runMachine)
part2 = ("Part 2: " ++) . show
runMachine :: Machine -> Machine
runMachine im@Machine {buttons} = press ((im,) <$> buttons) S.empty
where
press ((m, b) :<| next) seen
| (lights m, b) `S.member` seen = press next seen
| allON (lights m) = m
| otherwise =
press
(next >< ((pressButton m b,) <$> buttons))
((lights m, b) `S.insert` seen)
pressButton m b = m {presses = presses m + 1, lights = toggle b (lights m)}
toggle b = zipWith (\i l -> if i `elem` b then (l + 2) `xor` 1 else l) [0 ..]
allON = all (\v -> (v .&. 1) == 1)
parse = map (\(l, v) -> Machine 0 l (Seq.fromList $ init v) (last v)) . mapMaybe go . lines . concatMap fmt
where
go = (lights `bimap` map read <$>) . uncons . words
lights = map (\case '#' -> 0; '.' -> 1)
fmt = \case
c | c `elem` "[]" -> ""
c | c `elem` "{(" -> "["
c | c `elem` "})" -> "]"
c -> [c]