Skip to content

Instantly share code, notes, and snippets.

@xpqz
Last active March 20, 2022 04:36
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xpqz/d406eb493fd2a875ae463cce009463af to your computer and use it in GitHub Desktop.
Save xpqz/d406eb493fd2a875ae463cce009463af to your computer and use it in GitHub Desktop.
AoC 21, Dyalog APL
⎕FR ⎕PP ⎕IO←1287 34 0
'iotag' 'cmat' 'foldl'⎕CY'dfns'
⍝ https://adventofcode.com/2021/day/1
1⊥2<⌿d←⍎¨⊃⎕NGET'../d/1'1⋄(¯3↓d)+.<3↓d ⍝ Note: a+b+c<b+c+d is equivalent to a<d
⍝ https://adventofcode.com/2021/day/2
d←↑' '(≠⊆⊢)¨⊃⎕NGET'../d/2'1
(fw dn up)←+/m←('forward' 'down' 'up'∘.≡⊣/d)×⍤1⍎¨⊢/d
fw×dn-up
aim←-⌿+\1↓m
(+/aim×0⌷m)×+/0⌷m
⍝ https://adventofcode.com/2021/day/3
×/2⊥¨(~v) (v←500>+⌿d←↑⍎¨¨⊃⎕NGET'../d/3'1)
fn←{mcb←(+⌿⍵[;⍺])≥2÷⍨≢⍵⋄⍵[⍸mcb ⍺⍺ ⍵[;⍺];]}
b←¯1⋄o2←{b+←1⋄b =fn ⍵}⍣{1=≢⍺}d
b←¯1⋄co2←{b+←1⋄b ≠fn ⍵}⍣{1=≢⍺}d
(2⊥0⌷o2)×(2⊥0⌷co2)
⍝ https://adventofcode.com/2021/day/4
d←⊃⎕NGET'../d/4'1
day4←{
(n r)←⍺ ⍬
0 {
⍺=≢n:{⍺×+/(∊⍵)[⍸0<∊⍵]}/¨r⌿⍨{≢⊃1⌷⍵}¨r
call←⍺⊃n
w←{5∊(+⌿b),+/b←0>⍵}⍤2⊢play←-@{⍵=call}⊢⍵
r,←⊂call(play[⍸w;;])
(⍺+1)∇play⌿⍨~w
} ⍵
}
(⊃r)(⊃⊖r←(⍎0⊃d) day4 (↑{↑⍎¨1↓⍵}¨(0=≢¨d)⊂d))
⍝ https://adventofcode.com/2021/day/5
d←↑⍎¨'[^\d]+'⎕R' '⊢⊃⎕NGET'../d/5'1
day5←{dd←⍵⋄+/∊1<⊃+/{1∘+@⍵⊢(1+⌈⌿2 2⍴⌈⌿dd)⍴0}¨⊃↓{⊃,¨/iotag⌿2 2⍴⍵}¨↓dd}
day5 d⌿⍨{+⌿=⌿2 2⍴⍵}⍤1⊢d⋄day5 d
⍝ https://adventofcode.com/2021/day/6
d←{⍺ (≢⍵)}⌸∊⎕CSV(⊃⎕NGET'../d/6'1)''4
day6←{s←9⍴0⋄s[6 8]←⍵[0]⋄s[⍳8]+←⍵[1+⍳8]⋄s}
+/day6⍣80⊢school←d[;1]@(d[;0])⊢9⍴0
+/day6⍣256⊢school
⍝ https://adventofcode.com/2021/day/7
d←∊⎕CSV(⊃⎕NGET'../d/7'1)''4
⌊/+/t←(⍳⌈/d)(|-)⍤0 1⊢d⋄⌊/+/{2÷⍨⍵×⍵+1}t ⍝ p2: Gauss sum; thanks to @rak1507 for pointing this out
⍝ https://adventofcode.com/2021/day/8
d←⊃⎕NGET'../d/8'1
data←' '(≠⊆⊢)¨⍤1⊢(⎕CSV⍠'Separator' '|')(d)''4
+/∊2 3 4 7 8∘.=≢¨↑data[;1] ⍝ part 1
seg←{ ⍝ find segment mapping from ⍺ and decode ⍵
frq←{≢⍵}⌸{⍵[⍋⍵]}∊obl←⍺[⍋≢¨⍺]
a←'abcdefg'
s←7⍴''
s[0]←⊃(1⊃obl)~0⊃obl
s[1 4 5]←a[frq⍳6 4 9]
s[2]←a[⍸8=frq]~s[0]
s[3]←⊃(2⊃obl)∩a[⍸7=frq]
s[6]←⊃a~s
10⊥s∘decode¨⍵
}
decode←{
enc←(0 1 2 4 5 6)(2 5)(0 2 3 4 6)(0 2 3 5 6)(1 2 3 5)(0 1 3 5 6)(0 1 3 4 5 6)(0 2 5)(0 1 2 3 4 5 6)(0 1 2 3 5 6)
⊃⍸({⍵[⍋⍵]}⍺⍳⍵)∘≡¨enc
}
+/seg/⍤1⊢data ⍝ part 2
⍝ https://adventofcode.com/2021/day/9
data←↑⍎¨¨⊃⎕NGET'../d/9'1
all←{∧/⍵[1;1]<∊⍵+3 3⍴9 0 9 0 9 0 9 0 9}
op←{n←⍵ ⋄ (⍺[0]↑n)←9 ⋄ (⍺[1]↑⍉n)←9 ⋄ ⍺⍺ n}
sinks←(all op)⌺3 3⊢data
n4←{valid∩(⊂⍵)+(¯1 0)(1 0)(0 ¯1)(0 1)}
valid←,⍳⍴data
seen←⍬
∇ r←ff p;point ⍝ Don't judge me.
⍝ Flood fill
r←,⊂p
seen,←⊂p
:for point :in n4 p
:if (seen∊⍨⊂point) ∨ data[⊂point]≥9
:continue
:endif
r,←ff point
:endfor
{×/3↑{⍵[⍒⍵]}≢¨ff¨⍵} ⍸sinks ⍝ part2
⍝ https://adventofcode.com/2021/day/10
d←⊃⎕NGET'../d/10'1
strip←'[]' '()' '{}' '<>'⎕R''⍠'Regex'0⍣≡d ⍝ Repeatedly remove directly adjacent matching pairs until stable.
bad←{(4≠v)/v←')]}>'⍳⍵}¨strip ⍝ pick lines containing bad matches
+/3 57 1197 25137[⊃¨(0≠≢¨bad)/bad] ⍝ part 1: pick the first bad match of each, map to scores
incmpl←(0=≢¨bad)/strip
s←{⍵[⍋⍵]}{{⍺+5×⍵}/⊖1 2 3 4[⊖'([{<'⍳⍵]}¨incmpl
s[⌊2÷⍨≢s] ⍝ part2: pick the middle score
⍝ https://adventofcode.com/2021/day/11
d←⍎¨↑⊃⎕NGET'../d/11'1
update←{
(octp state)←⍵
flashers←state∧9<octp
newoctp←octp+{+/∊⍵}⌺3 3⊢flashers
(newoctp)(state∧~flashers)
}
p1←{
(count octp)←⍵
(next state)←update⍣≡(1+octp)(10 10⍴1)
flashed←+/~∊state
(count+flashed)(state×next)
}
p2←{
(next state)←update⍣≡(1+⍵)(10 10⍴1)
~∨/∊state:⍺
(1+⍺)∇state×next
}
⊃p1⍣100⊢0 (d) ⍝ part 1
1 p2 d ⍝ part 2
⍝ https://adventofcode.com/2021/day/12
⍝⍝⍝ PYTHON
⍝ https://adventofcode.com/2021/day/13
⍝⍝⍝ PYTHON
⍝ https://adventofcode.com/2021/day/14
⍝ port of Python solution; hideous. Fast, but hideous.
d←⊃⎕NGET'../d/14'1
rules←28 28⍴''⋄rules[⎕A∘⍳¨0⌷r]←1⌷r←⍉↑{(~⍵∊' -> ')⊆⍵}¨2↓d
pairs←28 28⍴0⋄pairs[⎕A∘⍳¨⊃¨0⌷nc]←1⌷nc←⍉{⍺ (≢⍵)}⌸2,/⊃d
letters←28/0⋄letters[⎕A∘⍳¨0⌷cf]←1⌷cf←⍉{⍺ (≢⍵)}⌸⊃d
day14←{
letters[⎕A⍳c←⊃rules[⊂⍵]]+←⍺[⊂⍵]
pairs[⊂⍵]-←⍺[⊂⍵]⋄pairs[(⎕A⍳c@1⊢p)(⎕A⍳c@0⊢p←⎕A[⍵])]+←⍺[⊂⍵]⋄⍬
}
{_←pairs∘day14¨⍸×pairs⋄⍬}⍣40⊢⍬
(⌈⌿-⌊⌿)letters/⍨0≠letters
⍝ https://adventofcode.com/2021/day/15
⍝ wpath from dfns does it all, but slow -- it builds the whole spanning tree. ~30s
'wpath'⎕cy'dfns'
d←↑⍎¨¨⊃⎕NGET'../d/15'1
shifts←{(⍺,2⊣/⍵)(2⊢/⍵,⍺)(2⊢⌿⍵⍪⍺)(⍺⍪2⊣⌿⍵)}
day15←{
nnnn←{⍵~¯1}¨,↓2 0 1⍉↑¯1shifts(⍴⍵)⍴(⍳×/⍴⍵)
flat←∊⍵
values←{flat[⍵]}¨nnnn
graph←↑(nnnn)(values)
path←graph wpath 0 (¯1+≢flat)
+/1↓flat[path]
}
day15 d
merge←{((⍴×⍴∘⊃)⍴0 2 1 3⍉↑)⍵}
day15 9@(⍸0=9|mddd)⊢9|mddd←merge (5 5⍴⊂d)+∘.+⍨⍳5
⍝ https://adventofcode.com/2021/day/16
data←{∊⍉2 2 2 2⊤(⎕D,'ABCDEF')⍳⍵}⊃⊃⎕NGET'../d/16'1
c←0
nbits←{b←data[c+⍳⍵]⋄c+←⍵⋄b}
literal←{d←0⋄2⊥{nb←nbits 5⋄~⊃nb:⍵,1↓nb⊣d⊢←1⋄⍵,1↓nb}⍣{d}⊢⍬}
op0←{end←c+len←2⊥nbits 15⋄{⍵,packet⍬}⍣{c≥end}⊢⍬}
op1←{⊃¨packet¨⍳2⊥nbits 11}
operator←{0=⊃nbits 1:op0⍬⋄op1⍬}
packet←{
h←2 3⍴nbits 6⋄ver←2⊥0⌷h⋄pid←2⊥1⌷h
4=pid:⊆ ⊂(ver pid) (literal⍬)
⊆ ⊂(ver pid) (operator⍬)
}
run←{
hd←⊃⍵⋄t←1⊃hd
0=t:+/∇¨1⊃⍵⋄1=t:×/∇¨1⊃⍵⋄2=t:⌊/∇¨1⊃⍵⋄3=t:⌈/∇¨1⊃⍵
4=t:1⊃⍵⋄5=t:>/∇¨1⊃⍵⋄6=t:</∇¨1⊃⍵⋄=/∇¨1⊃⍵
}
⊃+⌿↑(2=≢¨f)/f←{⊃,/,⊆¨⍵}⍣≡ d←packet⍬ ⍝ part 1
run ⊃d ⍝ part 2
⍝ https://adventofcode.com/2021/day/17
(minx maxx miny maxy)←253 280 ¯73 ¯46
0.5×miny×miny+1 ⍝ part 1
shoot←{
⍺←0 0⋄(x y)←pos←⍺
(x>maxx)∨y<miny:0⋄(minx≤x)∧y≤maxy:1
pos+←⍵⋄(dx dy)←⍵⋄pos∇((dx-dx(×-)0),dy-1)
}
startx←{⍵+1}⍣{minx≤0.5×⍺×⍺+1}⊢1
yr←miny iotag -miny+1
xr←startx iotag maxx
+/shoot⍤1⊢↑,xr∘.,yr ⍝ part 2
⍝ https://adventofcode.com/2021/day/18
parse←{n←⍎¨(m←∨⌿⎕D∘.=⍵)⊆⍵⋄n+¯11○⊃¨m⊆'[]'{+\-⌿⍺∘.=⍵}⍵} ⍝ string to complex number snailfish
data←parse¨⊃⎕NGET'../d/18'1
∇ r←idx expl d;left;right
r←d
(left right)←r[idx (idx+1)]
:if 0≠idx
r[idx-1]+←9○left
:endif
:if (idx+2)<≢r
r[idx+2]+←9○right
:endif
r←idx{⍵/⍨0@⍺⊢1⍨¨⍵}r ⍝ remove pair
r[idx]←0+¯11○¯1+11○left
split←{
im←1+11○⍵[⍺]
re←2÷⍨9○⍵[⍺]
s←⍵/⍨2@⍺⊢1/⍨≢⍵ ⍝ grow vector at ⍺
s[⍺+1]←(⌈re)+¯11○im
s[⍺]←(⌊re)+¯11○im
s
}
expall←{e←5≤11○⍵⋄0=+/e:⍵⋄(⊃⍸e)expl ⍵}⍣≡
add←{{{s←10≤9○⍵⋄0=+/s:⍵⋄(⊃⍸s)split ⍵} expall ⍵}⍣≡0J1+⍺,⍵} ⍝ Add two snailfish numbers
mag←{
maxd←⌈/11○⍵
0=maxd:⊃9○⍵
idx←⊃⍸maxd=11○⍵
m←((2×9○⍵[idx+1])+3×9○idx⊃⍵)+¯11○¯1+11○idx⊃⍵
∇(1+idx){⍵/⍨0@⍺⊢1⍨¨⍵}m@idx⊢⍵
}
mag ((⊃data) add 1⊃data) add foldl 2↓data ⍝ Part 1. APL's reduce is foldr. Sadly.
sums←{add/data[⍵]}⍤¯1⊢2 cmat ≢data
⌈/mag¨sums ⍝ part2
⍝ https://adventofcode.com/2021/day/19
⍝ TBD
⍝ https://adventofcode.com/2021/day/20
(iea img)←{'#'=(⊃⍵)(↑2↓⍵)}⊃⎕NGET'../d/20'1
pad←{0,0,⍨0⍪0⍪⍨⍵}⋄u←{(⍺ ⍺)↓(-⍺ ⍺)↓⍵}
day20←{+/∊⍺u{{iea[2⊥∊⍵]}⌺3 3⊢⍵}⍣⍺⊢pad⍣(2×⍺)⊢⍵}
2 50 day20⍤0 2⊢img
⍝ https://adventofcode.com/2021/day/21
⍝⍝⍝ PYTHON
⍝ https://adventofcode.com/2021/day/22
c←↑⍎¨¨'-?\d+'⎕S'&'¨d←⊃⎕NGET'../d/22'1
val←{'n'=1⊃⍵}¨d
x←{⍵[⍋⍵]}∪∊c[;0],1+c[;1]
y←{⍵[⍋⍵]}∪∊c[;2],1+c[;3]
z←{⍵[⍋⍵]}∪∊c[;4],1+c[;5]
state←(¯1+≢x)(¯1+≢y)(¯1+≢z)⍴0
ff←{
(x1 x2)←x⍸⍵[1 2]
(y1 y2)←y⍸⍵[3 4]
(z1 z2)←z⍸⍵[5 6]
state[x1 iotag x2;y1 iotag y2;z1 iotag z2]←⊃⍵
}
_←ff⍤1⊢(⍪val),c
yz←(¯2-⌿y)∘.×(¯2-⌿z)
+/{(+/∊yz×state[⍵;;])×x[⍵+1]-x[⍵]}¨⍳¯1+≢x ⍝ part2
@kimmolinna
Copy link

{(⍵≠' ')⊆¨⍵} is a bit faster than ' '(≠⊆⊢)¨
I had to test it because tacit and trains are a bit stanger for me. ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment