Last active
March 20, 2022 04:36
-
-
Save xpqz/d406eb493fd2a875ae463cce009463af to your computer and use it in GitHub Desktop.
AoC 21, Dyalog APL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
⎕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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
{(⍵≠' ')⊆¨⍵}
is a bit faster than' '(≠⊆⊢)¨
I had to test it because tacit and trains are a bit stanger for me. ;)