module one import StdEnv import Data.Func import Text read :: *File -> [String] read f # (l, f) = freadline f | l.[size l - 1] <> '\n' = [] = [l % (0, size l - 2):read f] Start w # (io, w) = stdio w # ls = read io # ls = {l\\l<-ls} = (one ls, two ls) one = numOccupied o cell isOccupied ((==)0) ((<=)4) two = numOccupied o cell seeOccupied ((==)0) ((<=)5) isOccupied :: Int Int Int Int {#String} -> Bool isOccupied x y dx dy ls = seat (x+dx) (y+dy) ls == '#' seeOccupied :: Int Int Int Int {#String} -> Bool seeOccupied x y dx dy ls = case seat (x+dx) (y+dy) ls of '#' = True 'L' = False '-' = False '.' = seeOccupied (x+dx) (y+dy) dx dy ls numOccupied :: {#String} -> Int numOccupied ls = length [()\\r<-:ls, c<-:r | c == '#'] cell :: (Int Int Int Int {#String} -> Bool) (Int -> Bool) (Int -> Bool) {#String} -> {#String} cell lookfun live die ls # ls` = {{step x y\\x<-[0..size ls.[y] - 1]}\\y<-[0..size ls - 1]} = if (and [l==r\\l<-:ls` & r<-:ls]) ls (cell lookfun live die ls`) where step x y = case ls.[y,x] of '.' = '.' 'L' = if (live numOccupied) '#' 'L' '#' = if (die numOccupied) 'L' '#' where numOccupied = length [()\\dx<-[-1..1], dy<-[-1..1] | not (dx == 0 && dy == 0) && lookfun x y dx dy ls] seat :: Int Int {#String} -> Char seat x y ls | y < 0 || y >= size ls || x < 0 || x >= size ls.[y] = '-' = ls.[y,x]