December 2021 · 10 minute read

So I have decided to follow Advent-of-Code live this year [I am 10 days behind so it’s hardly live, but I should catch up soon :) ]

Advent of Code is a programming themed fun-little-event that takes place every year on http://adventofcode.com

You can find my solutions (in (Dyalog-)APL) below.

## Day 1

``````q1 ←{ +/ (1↓⍵) > (¯1↓⍵) }
q1pt1 ←{
q1 ⍎⍤1⊢↑ ⊃⎕NGET './q1.txt'1
}
q1pt2 ← {
x ← ⍎⍤1⊢↑ ⊃⎕NGET './q1.txt'1
q1 (2↓x) + (1↓¯1↓x) + (¯2↓x)
}
q1pt1_v2 ←{
+/2</ ⍎⍤1⊢↑ ⊃⎕NGET './q1.txt'1
}
q1pt2_v2 ← {
x ← ⍎⍤1⊢↑ ⊃⎕NGET './q1.txt'1
+/2</3+/x
}``````

I learned about `N op /` a while after solving this for the 1st time. It sure makes it simpler

## Day 2

``````C ← 'forward' 'down' 'up'
M ← (1 0) (0 1) (0 ¯1)
d ← ⊃⎕NGET './q2.txt'1

q2←{
×/↑↑+/{M[C⍳⍵[1]]×(⍎⍤1⊢↑⍵[2])}¨' '(≠⊆⊢)¨d
}

q2pt2←{
f←{
h ← ⍵[1]
a ← ⍵[2]
d ← ⍵[3]
⍵ + ((⍺[1]) (⍺[2]) (a×⍺[1]))
}
⍝ appending (0 0 0) as the initial value of my accumulator for my reduce
x ← ⊖(↓↓0 0 0), {M[C⍳⍵[1]]×(⍎⍤1⊢↑⍵[2])}¨ ' '(≠⊆⊢)¨d_
×/ (1 0 1)/ ↑f/ ↑¨x
}``````

The reduce (`/`) works right to left so I had to ⊖ it then swap ⍵ and ⍺

## Day 3

``````C ← 'forward' 'down' 'up'
M ← (1 0) (0 1) (0 ¯1)
d ← ⊃⎕NGET './q2.txt'1

q2←{
×/↑↑+/{M[C⍳⍵[1]]×(⍎⍤1⊢↑⍵[2])}¨' '(≠⊆⊢)¨d
}

q2pt2←{
f←{
h ← ⍵[1]
a ← ⍵[2]
d ← ⍵[3]
⍵ + ((⍺[1]) (⍺[2]) (a×⍺[1]))
}
x ← ⊖(↓↓0 0 0), {M[C⍳⍵[1]]×(⍎⍤1⊢↑⍵[2])}¨ ' '(≠⊆⊢)¨d_
×/ (1 0 1)/ ↑{}/ ↑¨x
}``````

## Day 4

``````n ←{ ⍎⍤1⊢↑⍵ }

nonempty ←{ ↑,/0≠⍴¨⍵ }
playcards ←{ n↑↑(nonempty⊆⊢)' '∘(≠⊆⊢)¨1↓⍵ }

d ← ⊃⎕nget'q4.txt'1
P ← n','(≠⊆⊢)⊃d ⍝ Pouch
C ← playcards d ⍝ Cards
WT ← {⍵⍳1}¨ ↓⍉↑ ↑∨/¨{∨/5∊¨⍵}¨¨{(+/[1]⍵) (+/[2]⍵)}¨∨\C∘=¨P ⍝ Winning Turns
score ←{ P(⊢⌷⊣)WT(⊢⌷⊣)⍵ × +/ (↑,/,/⍵⌷C) ~ (1+⍵⌷WT)↑P }

q4pt1 ← score WT⍳⌊/WT
q4pt2 ← score WT⍳⌈/WT``````

I liked how neat `∨\C∘=¨P` was to generate states of each bingo card across multiple turns. I am curious to see how I can use `\` in other problems.

I got a better grasp of tacit programming this time around. I am not sure if `Y(⊢⌷⊣)X` is the best way to do `Y[X]` but at least I am able to create functions like it .

I do a lot of `↑` and `↓` , which also requires me to `¨` . I should figure out how to better handle boxes of values.

## Day 5

``````valid_pt1 ← {(∆x ∆y)←|-/¨⍵ ⋄         (∆x=0)∨(∆y=0)}
valid_pt2 ← {(∆x ∆y)←|-/¨⍵ ⋄ (∆x=∆y)∨(∆x=0)∨(∆y=0)}
applyvent ← {{(⍵⌷M)+←1}¨⍵} ⍝ impure function. modifies M
range ← {d←⍵-⍺ ⋄ s←d÷|d ⋄ ⍺+s×⍳+1+|d} ⍝ 5 range 3 gives 5 4 3

d ← ⊃⎕nget'q5.txt'1
V ← {n¨','∘(≠⊆⊢)¨(1 0 1)/' '(≠⊆⊢)⍵}¨d
D ← 1+⌈/∊V
M ← D D⍴0 ⋄ valid ← valid_pt1 ⋄ applyvent¨0⌷{↑(↑,.(⊂,))/↑range/¨⍵}¨(↑valid¨⊆⊢){↓⍉↑⍵}¨V
q5pt1 ← +/∊M≥2
M ← D D⍴0 ⋄ valid ← valid_pt2 ⋄ applyvent¨0⌷{↑(↑,.(⊂,))/↑range/¨⍵}¨(↑valid¨⊆⊢){↓⍉↑⍵}¨V
q5pt2 ← +/∊M≥2``````

It was fun to solve this problem as I iterated over the map-view. I enjoy this style of interactive programming, doing as I’m seeing. It helps get rid of some hesitancy to approach even a seemingly difficult problem.

I ended relying on a mutable table to solve this and I wonder how I could have done it purely.

## Day 6

``````f ← {s←⍵⋄((1↓s),0)+s[0]×(0 0 0 0 0 0 1 0 1)}
genS ← {x←⍵ ⋄ {+/x=⍵}¨⍳8+1}

d ← ⊃⎕nget'q6.txt'1
N ← n','(≠⊆⊢)d

q6pt1 ← 20⍕ +/↑(⊢f)/(⍳80),↓genS N
q6pt2 ← 20⍕ +/↑(⊢f)/(⍳256),↓genS N``````

Thinking of this problem as arrays of values helped me coming up with a solution.

The first solution I came up relied on keeping a record of each fish (as an integer) and resulted in memory overflow for part-2.

## Day 7

``````d ← ⊃⎕nget'q7.txt'1
N ← n','(≠⊆⊢)⊃d
K ← 1+⌈/∊N
q7pt1 ← ⌊/+/ |(⍉↑K⍴¨N)-(0⌷¨⍳K(≢N))
g ← {0.5×⍵×⍵+1}
q7pt2 ← ⌊/+/g|(⍉↑K⍴¨N)-(0⌷¨⍳K(≢N))``````

Another problem that was represented by a table rather neatly. If I write about APL this could be the problem I solve.

## Day 8

``````A ← 'abcdefg'
MK ← {(∊∘⍵)¨A}
MK_v2 ← A∊
Mb ← ↑MK ¨ ('abcfeg' 'cf' 'acdeg' 'acdfg' 'bcdf' 'abdfg' 'abdefg' 'acf' 'abcdefg' 'abcdfg')

l ← {{((~'|'∊⊢)¨⍵)⊆⍵}' '∘(≠⊆⊢)⍵}
loner ← {x←⍵ ⋄ {⍵/x}1={+/x=⍵}¨x}
len ← {∊(⍺=≢¨⍵)⊆⍵} ⍝ selects items with given length
decode ←{
b←⍺∊⍵
1(⊢⍳⊣)b∘(⊢≡⊣)¨↓Mb
}

solve ← {
x←⍵
S_1←2 len x
S_4←4 len x
S_7←3 len x
S_8←7 len x
S_a←S_7~S_1
S_g←⊃1 len{⍵~S_a,S_4}¨x
S_e←⊃∊{⍵~S_g,S_a,S_4}¨x
S_b←loner 1 len{⍵~S_7,S_e,S_g}¨x
S_d←S_8~S_7,S_b,S_e,S_g
S_c←loner 1 len{⍵~S_a,S_g,S_e,S_b,S_d}¨x
S_f←⊃∊{⍵~S_a,S_c,S_g,S_e,S_b,S_d}¨x
∊(S_a S_b S_c S_d S_e S_f S_g)
}

d ← ⊃⎕nget'q8.txt'1
q8pt2 ← +/{R←solve↑0⌷l ⍵ ⋄ ⊖{⍺+10×⍵}/⊖R∘decode¨↑1⌷l ⍵}¨d``````

OK, this one actually took me a while. Once I was able to decode `S_g` the rest came smoothly.

I want to be able to come up with tacit versions of `len` and `loner`, but not yet :)

## Day 9

``````x←↑n¨¨⊃⎕NGET'q9.txt' 1
d←⍴x

q9_pt1 ← +/{o←4⌷⍵ ⋄ (o+1)×0=+/o>(0 1 0 1 0 1 0 1 0)/⍵}¨∊¨sx

connlabel←{{{⍵[1;0]=0:0 ⋄ ⌊/0~⍨,⍵}¨(⊂⊢)⌺3 1⊢{⍵[0;1]=0:0 ⋄ ⌊/0~⍨,⍵}¨(⊂⊢)⌺1 3⊢⍵}(⍣≡)1+∘⍸@⊢⍵}
m2←connlabel x<9
pt2←×/3↑(⊂∘⍒⌷⊢){+/∊m2=⍵}¨0~⍨∪∊m2``````

I insisted on coming up with an array-based solution to connected-component labeling. It took me a while but I discovered `⍣≡` in the process. I used to write recursive functions that I ran repeatedly until the system stabilized. Well, this does it all by itself.

Also `⌺` would have been very handy in all the 2d filters I have been doing over matrixes.

## Day 10

``````B        ← '>'   '}'  ']' ')' ' ' '(' '[' '{' '<'
Cost_b_1 ← 25137 1197 57  3   0   1   2   3   4
Cost_b_2 ← 25137 1197 57  3   0   0   0   0   0
Cost_b ← Cost_b_1

c←{Cost_b[B⍳⍵] }
cost←{
x ← c⊃(⍵∊'>}])')/⍵
x>0:0
{⍺+⍵×5}/⊖0,⊖c¨⍵
}
f_i←{{(⍵,0)∨(0,⍵)}2=(1↓⍺[1]=⍵)+(¯1↓⍺[0]=⍵)}
f_rm←{∊(⊢⊆∘⍵)↑~∨/(⊢f_i∘⍵)¨'()' '{}' '[]' '<>'}
f_rms←{
w_←f_rm ⍵
(⍴w_)=(⍴⍵):w_
f_rms w_
}
q10← {{⍵[0.5×(⍴⍵)-1]}{(⊂⍋⍵)⌷⍵}∊0(≠⊆⊢)cost¨f_rms¨d}
⍝ pt1
Cost_b ← Cost_b_1
q10 0
⍝ pt2
Cost_b ← Cost_b_2
q10 0``````

## Day 11

``````step←{
x0←↑⍵[1]
d←⍴x0
flash←{
⍝⎕←DISPLAY ⍺ ⍵
x←⍵
F←⍺
F_new←F-⍨x>9
0=+/∊F_new:F x
0=+/{(⍵⌷x)+←1}¨N_diag¨(,F_new)/(,⍳d):F x
(F∨F_new)∇(x)
}
l r←↑¨(d⍴0)flash 1+x0
(+/⍵[0],∊l)({9<⍵:0 ⋄ ⍵}¨r)
}
x←↑n¨¨⊃⎕NGET'q11.txt'1
pt1←0⌷⊃step/⊖(⊂0 x),⍳100
pt2←1+{⍵⍳1}99<|2-/⊃¨{⊃step/⊖(⊂0 x),⍳⍵}¨⍳1000``````

The scan operator goes through the same elements every time, without using the accumulated data. There should be a more performant version of it that doesn’t have O(N!) complexity.

## Day 12

``````A_lower←819⌶⎕A

d←⊃⎕NGET'q12.txt' 1
L←'-'∘(≠⊆⊢)¨d
C←∪↑,/L
C_once←{⍵/C}{⍵∊A_lower}¨⊃¨C
D←⊃↑⍴C
M←D D⍴0⍴D*2
{(⍵⌷M)←1}¨{⍵⍳1}¨¨{(,⍵)∘≡¨C}¨¨,¨¨L ⍝ marks M with 1s

iCity←{1(⊢⍳⊣)(,⍵)∘≡¨C}

f←{
c←⍺
Open←⍵
next←Open∩{⍵/C}(iCity↑c)⌷(M∨⍉M)
c≡'end':1
0=(⍴next):0
Open_←Open~C_once∩(↓,c)
∊{⍵ f Open_}¨next
}

pt1←+/ 'start'f(C~↓,'start')

f2←{
fin←{⍵}
c←↑⍺[0]
path←⍺[1]
Closed←⍵
C_open←{⍵~↓'start'}{⍵/C}(Closed<(2-+/Closed>1))
next←C_open ∩ {⍵/C}(iCity↑c)⌷(M∨⍉M)
c≡'end':(fin 1)
0=(⍴next):0
+/∊{n←↓,⍵ ⋄ (⍵(∊path,'-',⍵)) f2 (Closed+(C∊n)×n∊C_once)}¨next
}

pt2←('start' 'start') f2 ((⍴C)⍴0)``````

the old travelling salesman problem with additional constraints.

## Day 13

``````p←{'.#'[⍵]}¨                                                      ⍝ plot for binary matrix

{a←⍺[0] ⋄ b←⍺[1]>⍳a⌷⍴⍵ ⋄ (b⌿[a]⍵)((0,¯1↓~b)⌿[a]⍵)}                ⍝ cuts ⍵ at ⍺ to 2
⍝   where ⍺[0] is axis
⍝   where ⍺[1] is position at axis
f←{
pt1 pt2←⍺ cut ⍵
pt2_←⍺{⍺[0]=0:⊖⍵ ⋄ ⌽⍵}pt2                                    ⍝ flip horizontally or vertically
sBigger←∊⌈/⍴¨pt1 pt2_
⊃∨/{⊖⌽sBigger↑⌽⊖⍵}¨⊢pt1 pt2_                                 ⍝ pad (in top and left) to match the bigger of the two
}
dat←⊃⎕NGET'proj/apl/q13.txt'1
P←⊖¨n¨,','(≠⊆⊢)¨↑','∘((∊¨)⊆⊢)dat                                  ⍝ points as (i j) tuples
d←∊1+⌈/P                                                          ⍝ dimensions
F←(('yx'∘⍳∊)@0)¨(n@1)¨'='(≠⊆⊢)¨↑2∘⌷¨' '(≠⊆⊢)¨1↓,↑','∘((~∊¨)⊆⊢)dat ⍝ folds (as t
M←(1@P)d⍴0                                                        ⍝ the initial matrix

pt1←q13pt1←+/∊(⊃F) f M
pt2←p↑f/⌽(⊂M),F``````

I added documentation the APL way, as a second column. Looks neat doesn’t it :)

## Day 14

``````fn←{
turns←⍵
dat←⊃⎕NGET'proj/apl/q14.txt' 1
p0←2,/⊃dat                                                  ⍝ initial pairs
Ma←{a b c←⍵ ⋄ (a b)(a c)(c b)}¨(∊(1 0 1)∘/)¨' '(≠⊆⊢)¨2↓dat  ⍝ all movez
Mk←⊃¨Ma                                                     ⍝ keys of moves
Punq←∪↑,/Ma,⊂p0                                             ⍝ all pairs, uniq
M←↑(+/(¯1 1 1)∘×)¨(Punq∊⊂)¨¨Ma                              ⍝ ∆state of moves
Ps←{↑(Mk∊⊂⍵)/M}¨Punq                                        ⍝ ∆state of pairs
s0←⊃+/(Punq∊⊂)¨p0                                           ⍝ initial state
sf←↑{⍵+∊+/Ps×⍵}/⌽(⊂s0),⍳turns                               ⍝ final state
⎕←⊢A←∪∊Punq                                                 ⍝ all letters available
⎕←⊢scr←⌈2÷⍨(+/sf∘×)¨(+/¨Punq∘=)¨A                           ⍝ scores
(⌈/-⌊/)scr
}
pt1←fn 10
pt2←fn 40``````

I had to optimize the solution for pt2 again, keeping counts instead of data. The solution didn’t work at first, though. I thought there could be an error due to the `⌈` operation, and manually subtracted 1 from the result.

## Day 15

``````solv←{
M←⍵
d←⍴M
O←(1@(⊂0 0))d⍴0
V←d⍴0
C←d⍴0
g←⊂d-1
H←+/¨|g-⍳d
f←{
⍝ V  visited
⍝ O  open/available
⍝ H  heuristics (cost to 'g'oal)
⍝ C  costs (cost to start)

o←⍸(O∧0=V)
0=≢o:1                ⍝ no more open slots. finish
x←o⌷⍨{⍵⍳⌊/⍵}C[o]+H[o] ⍝ take the least cost pos
x≡g:1
V[x]←1
n←{(~0∘∊¨⍵≥0)/⍵}{(~0∘∊¨⍵<⊂d)/⍵}(0 ¯1)(¯1 0)(0 1)(1 0)+x      ⍝ neighbours
c←C[x]
C[n]←{⍵⌷O:(⍵⌷C)⌊c+⍵⌷M ⋄ c+⍵⌷M}¨n ⍝ update costs to neighbours
O[n]←1                           ⍝ make available

0
}
{f 0:C[g] ⋄ ∇ 0} 0
}
pt1←{
M←↑n¨¨⊃⎕NGET'tmp.txt' 1
solv M
}
pt2←{
M←↑n¨¨⊃⎕NGET'tmp.txt' 1
S←⊖⌽10 9↑⌽⊖↑{⍵⌽1+⍳9}¨∪,+/¨⍳5 5
solv⍪/(⊃,/)¨↓{S∘(⌷⍨)¨⍵∘(,⍨)¨M}¨+/¨⍳5 5
}``````

## Day 16, 17

I didn’t do as good a bookkeeping for questions beyond this point. The interface I am using (Ride) was crashing at an increased frequency, perhaps due to the amount of data. I actually gave up on solving some of the questions after a few of those crashes.

## Day 18

``````mag←{
⍝⎕←↑⍵
x←⍵
n d←x
2>≢n:⊃n
i j←0 2+(⊢⍳⌈/)d
l←1⌷⍴↑x
a←↑i↑¨x
c←↑j↓¨x
m←+/3 2×⌷∘n¨(i(i+1))
n←1-⍨i⌷d
∇↓(a,(2 1⍴m n),c)
}
itr←{
s x←(9 4)<⌈/¨⍵
x:∇ xpl ⍵
s:∇ spl ⍵
⍝⎕←↑⍵
⍵
}
par←{
x←⍵
b←↑x∘=¨'[],'
n←⍎¨(~∨⌿b)⊆x
d←⊃¨(~∨⌿b)⊆(-⌿+\2↑b)
n d
}

## Day 19

``````'pmat' 'det'⎕CY'dfns'
RA←{⍵/⍨1=det¨⍵},(↓pmat 3)∘.{⍵@(⍺,¨⍳3)⊢3 3⍴0},1-2×⍳2 2 2
dat←getdata ⍬
D←≢dat
snsA←(∘.⊣)⍨dat

⍝ find matching sensors
matches←(∘.{cmn←⊃∩/∊¨⍺ ⍵ ⋄ 12=+⌿⍺∊cmn})⍨{(∘.far)⍨↓⍵}¨dat
snsM←↑¨(⍴snsA)⍴↑(,matches),.{⊂⍺/↓⍵}(,snsA)

fnd←(,⍨⍴dat)⍴⊃(,snsM),.(⊂relpos)(,⍉snsM)
⍝ found matches. fnd[i;j] ≡ r x y z,
⍝   `r` is ∆rot of "j" wrt "i"
⍝   `x y z` is ∆pos of "j" wrt "i"
fndr←⊃¨fnd    ⍝ found rotations
fndp←(1∘↓)¨fnd ⍝ found positions
I←⍸25>fndr    ⍝ indexes of matches in "fnd"

⍝{(⍵⌷xp)←⊂0 0 0 ⋄ (⍵⌷xr)←0}¨{(=/¨⍵)/⍵},⍳D D

open←(≢∪∊I)⍴0
imap←(⊃¨I){⊂(1∘⌷¨⍵)}⌸I
myi←(≢imap)⍴10+≢imap
0{myi[⍺]<⍵:⍵ ⋄ myi[⍺]←⍵ ⋄ ⍵>30:⍵ ⋄ ∇/(⊃imap[⍺]),⍵+1}0
Icand←⊃,/(((⊃¨I){⊂⍵}⌸I)@myi)27⍴9999
Idup←{i j←⍵ ⋄ open[i]←1 ⋄ open[j]}¨Icand
I_←(~Idup)/Icand
0≡≢∊~/∊¨I I_ ⍝ ensure nothing missing

P R←fill I_ ⍝ absolute positions and rotations
part1←≢∪⊃⍪/{↑(⊃P[⍵])∘+¨R[⍵]∘roti¨↓⊃dat[⍵]}¨⍳D
part2←{⌈/∊P(∘.{+/⍺-⍵})P}``````

## Day 20

``````m x0←readdata ⍬

pad←{k←⍺ ⋄ r c←(2 0)+⍴⍵ ⋄ (r⍴k){⍺,⍵,⍺}(c⍴k){⍺⍪⍵⍪⍺}⍵}

⊢part1←+/∊({s←⊃⍵ ⋄ a←⊃1⌷⍵ ⋄ (m⌷⍨2⊥9⍴s),⊂({m⌷⍨2⊥∊{(s 0 1)[⍵]}¨⍵}⌺3 3)1+s pad a}⍣2)(0,(⊂x0))
⊢part2←+/∊({s←⊃⍵ ⋄ a←⊃1⌷⍵ ⋄ (m⌷⍨2⊥9⍴s),⊂({m⌷⍨2⊥∊{(s 0 1)[⍵]}¨⍵}⌺3 3)1+s pad a}⍣50)(0,(⊂x0))``````

## Day 21

``````part1←{
⍝ both 'pad' and '⌺' uses 0 as fill-character
⍝  so I used 1 2 in place of 0 1 in the img matrix
n←0
scr←0 0
pos←1-⍨4 1
{i nr←⍵ ⋄ ⌈/scr≥1000:⍵ ⋄ nr_ ∆x←r nr ⋄ pos[i]←10|∆x+i⌷pos ⋄ scr[i]+←1+pos[i] ⋄ ∇(2|i+1)nr_}(0 0)
(⌊/scr)×n×3
}
part2←{
initpos←4 8
N←21+10+1
I←⍳N N
IW←⍸¨⊂[1 2]21<(0 1)∘.⌷I ⍝ win indexes
p←↓(initpos-1)(∘.=)⍳10 ⋄ s←(1@(⊂0 0))N N⍴0 ⋄ wins←0 0 ⋄ f 0
(⊂p)(⊂s)
}``````

todo

todo

## Day 24

``````K←⎕.v>
s0←'w0' 'x0' 'y0' 'z0'
doop←{ ⍝ do op at left to state at right
k←⊃⍺
v←1↓⍺
k=INP:v inp ⍵
k=MUL:v mul ⍵
k=DIV:v div ⍵
k=EQL:v eql ⍵
k=MOD:v mod ⍵
⎕←'unknown op: ',k
⍵ ⍝noop
}
pt1←{doop/(⌽⊃,/8↑digiops),⊂s0}
pt2←{inpi←0 ⋄ ↑{⊃doop/(⌽⊃,/⍵⌷digiops),⊂'w0' 'x0' 'y0' 'z0'}¨⍳14}

⍝ the above didn't actually help solve the problem, but they explained the state of it.

P←(12 1 1)  (13 1 9)  (12 1 11)  (¯13 26 6)  (11 1 6)  (15 1 13)  (¯14 26 13)  (12 1 5)  (¯8 26 7)  (14 1 2)  (¯9 26 10)  (¯11 26 14)  (¯6 26 7)  (¯5 26 1)
itr←{
i z←⍵
a b c←i⊃P
d←i⊃⍺
k←d≠a+26|z
0≠b∧k:1
k=0:(i+1)z÷b
(i+1)c+d+26×z÷b
}
soln←{{0=⊃(⊖⍵)(itr⍣14)0 0:⍵ ⋄ ∇ dc ⍵}14⍴9}``````

neither did this solve the problem, but it became more eligible that we are manipulating a number as if it’s a stack of integers that are <26.

I ended up solving it afterwards with pen and paper.

## Day 25

``````K←⎕.v>
plt←{K∘(⌷⍨)¨⍵}
upd←{(mvS FF)(mvE FF)⍵}
mvS←{
n _ s _ c←⍵[I]
(c s)≡S O:O
(n c)≡S O:S
c
}
mvE←{
_ e _ w c←⍵[I]
(c e)≡E O:O
(w c)≡E O:E
c
}
pt1←{
K←'⋄.v>'
F O S E←⍳4
I←(0 1)(1 2)(2 1)(1 0)(1 1) ⍝ neighbour indexes
plt←{K∘(⌷⍨)¨⍵}
X←dat←↑K∘⍳¨⊃⎕NGET'tmp.txt' 1
⍝⎕←plt¨{(upd⍣⍵)X}¨⍳⍵
1↓({x n←⍵ ⋄ x_←(upd⊃⍵) ⋄ x_(n+1)}⍣{(⊃⍺)≡(⊃⍵)})(X 0)
}``````