This one is just Conway’s Game of Life, so it’s pretty straightforward. Angort’s not the fastest language to do this in, and I’ve written it pretty naively. It runs in around 20 seconds. The grid is a list of lists of 0 or 1, and is actually two grids – like a double-buffered display. Part 2, in which you have to count the cells after a number of generations with the corner lights being hardwired on, was done by turning them on again before and after each generation.
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
`io library drop 100!Max 0 ?Max range !Range -1 2 range !NRange :mkgrid [] ?Range each { [],}; mkgrid !GridCur mkgrid !GridNext :setcell |v,x,y:| ?v ?y ?x ?GridNext get set; :setcellcur |v,x,y:| ?v ?y ?x ?GridCur get set; :getcell |x,y:| ?y ?x ?GridCur get get; :swapgrids ?GridCur ?GridNext !GridCur !GridNext; :init |:y| 0!y "day18in" "r" io$open each { ?Range each { j i 1 substr "#" = i ?y setcell } ?y 1+ !y } swapgrids ; :count |x,y:p,q,t| 0 NRange each { ?x i + !p ?p 0 >= ?p ?Max < and if NRange each { ?y i + !q ?q 0 >= ?q ?Max < and if i j bor if ?p ?q getcell + then then } then } ; :showgrid ?Range each { ?Range each { j i getcell if "#" else "." then p j i count p }nl } ; :gen |:c| ?Range each { ?Range each { i j count !c i j getcell if cases ?c 2 < if 0 case ?c 3 > if 0 case 1 otherwise else ?c 3 = if 1 else 0 then then i j setcell } } ; :countcells 0 ?Range each { ?Range each { i j getcell + } } ; "Part 1". init 0 100 range each {gen swapgrids countcells.} :setfour 1 0 0 setcellcur 1 99 0 setcellcur 1 0 99 setcellcur 1 99 99 setcellcur; "Part 2". init 0 100 range each {setfour gen swapgrids setfour countcells.} |