-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path6.hs
48 lines (37 loc) · 1.59 KB
/
6.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
import qualified Data.Vector as V
import Data.List.Split
import Data.Array.IArray
import Data.List
import Data.Matrix
data Action = Action (Bool -> Bool)
data Point = Point Int Int
data Range = Range Point Point
data Instruction = Instruction Action Range
main = do
contents <- readFile "input"
print $
sum $
map (length . filter (\i -> i)) $
compose
(map executeInstruction $ map readInstruction $ map words $ lines $ contents)
(replicate 1000 $ replicate 1000 False)
executeInstruction :: Instruction -> [[Bool]] -> [[Bool]]
executeInstruction (Instruction (Action action) (Range (Point sx sy) (Point ex ey))) matrix =
[ if y < sy || y > ey then row else
[ if x < sx || x > ex then el else action el | (el, x) <- zip row [0..]]
| (row, y) <- zip matrix [0..]]
readInstruction :: [String] -> Instruction
readInstruction ("toggle" : range) = Instruction (Action (\x -> not x)) (readRange range)
readInstruction ("turn" : "on" : range) = Instruction (Action (\x -> True)) (readRange range)
readInstruction ("turn" : "off" : range) = Instruction (Action (\x -> False)) (readRange range)
readInstruction _ = error "Unknown instruction"
readRange :: [String] -> Range
readRange (from : "through" : to : _) = Range (readPoint from) (readPoint to)
readPoint :: String -> Point
readPoint point = makePoint $ map readInt $ splitOn "," point
makePoint :: [Int] -> Point
makePoint (a : b : _) = Point a b
readInt :: String -> Int
readInt = read
compose :: [a -> a] -> a -> a
compose fs v = foldl (flip (.)) id fs $ v