2745c1e53864fe066a1f6a63d60b1f234f40720d
[aoc20.git] / 11 / one.icl
1 module one
2
3 import StdEnv
4 import Data.Func
5
6 import Text
7
8 read :: *File -> [String]
9 read f
10 # (l, f) = freadline f
11 | l.[size l - 1] <> '\n' = []
12 = [l % (0, size l - 2):read f]
13
14 Start w
15 # (io, w) = stdio w
16 # ls = read io
17 # ls = {l\\l<-ls}
18 = one ls
19
20 instance == {#String} where
21 (==) l r = and [l==r\\l<-:l & r<-:r]
22
23 one :: {#String} -> Int
24 one ls = length [()\\r<-:cell ls, c<-:r | c == '#']
25
26 cell :: !{#String} -> {#String}
27 cell ls = let ls` = step ls in if (ls` == ls) ls (cell ls`)
28
29 step :: !{#String} -> {#String}
30 step ls = {{step` x y\\x<-[0..size ls.[0] - 1]}\\y<-[0..size ls - 1]}
31 where
32 step` :: Int Int -> Char
33 step` x y = case ls.[y,x] of
34 '.' = '.'
35 'L' = if (occupied == 0) '#' 'L'
36 '#' = if (occupied >= 4) 'L' '#'
37 where
38 occupied = length [()\\dx<-[-1..1], dy<-[-1..1] | not (dx == 0 && dy == 0) && not (empty (x+dx) (y+dy))]
39 empty :: Int Int -> Bool
40 empty x y
41 | x < 0 || x >= size ls.[0] || y < 0 || y >= size ls = True
42 = ls.[y,x] <> '#'