-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday3.bqn
93 lines (78 loc) · 2.91 KB
/
day3.bqn
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
#!/usr/bin/env cbqn
# Written after day 4, because of a logical error with the first attempt.
input ← ⟨
"467..114.."
"...*......"
"..35..633."
"......#..."
"617*......"
".....+.58."
"..592....."
"......755."
"...$.*...."
".664.598.."
⟩
input ↩ •FLines "inputs/day3.txt"
# From BQNcrate: Pad with a layer of fill elements on all sides
Pad ← (⊢↑˝·≍⟜¬2+≢)
GetSymbols ← {¬".0123456789"∊˜𝕩}⊸/⍷∘∾
symbols ← Pad (GetSymbols input) ∊˜ >input
IsDigit ← {('0'≤𝕩)∧(𝕩≤'9')}
digits ← { (⊑𝕩∊'0'+↕10) ? (𝕩) ; (' ') }¨ Pad >input
# We need to pad these because Grow wraps the grid
parsed ← symbols ⋈¨ digits
# Adapted from BQNcrate GoL to just sum the neighbours to 1 step propogate
# symbols
Grow ← {0<⊑+˝⥊⌽⟜𝕩¨⋈⌜˜¯1‿0‿1}
# Cull symbols where digits is 0, padding is always culled
Cull ← {
s‿d ← 𝕩
{d=' '?0;s}‿d
}
# Spread symbols left and right
Spread ← {
s ← ⊑¨ 𝕩
neighbourhood ← ⌽⟜s¨⋈⌜˜¯1‿0‿1
spread ← ⊑0<+˝˘ 1↑1↓ neighbourhood
spread ⋈ ¨ 1⊑¨ 𝕩
}
Harvest ← {
s‿d ← 𝕩
s ? d ; '.' # just to see it better
}
# Adapted BQNCrate split for digits only
SplitDigits ← {((⊢-˜¬×·+`»⊸<)∘¬∘IsDigit˜⊔⊢) 𝕩}
MaxDigitLen ← {⌈´ ≠¨ ∾ SplitDigits¨ 𝕩}
# Taken from dzaima's utils
# https://github.com/dzaima/aoc/blob/master/2023/BQN/utils.bqn
Ints ← {•ParseFloat¨((¯1+⊢×·+`»⊸<)𝕩∊'0'+↕10)⊔𝕩}
# We've padded this already, so it's safe to ⥊ this without worrying about
# digits on two lines joining.
# https://mlochbaum.github.io/BQN/doc/fill.html
init ← Cull¨ Grow ⌾ (⊑¨) parsed
fin ← Harvest¨ Cull¨∘Spread⍟(1-˜MaxDigitLen input) init
•Show ⟨"Part 1", +´ Ints ⥊ fin⟩
# ========== Part 2
gears ← Pad '*'= >input
# # https://github.com/dzaima/aoc/blob/master/2023/BQN/3.bqn
# Pre-identifying the part numbers that belong
# togther at the start makes our lives much easier as we don't
# have to try to figure that out at a cellular automata level!
part_ix ← ¯1+(+`1∾1‿0⍷⊢)⌾⥊⊸× ' '≠digits
part_n ← •ParseFloat¨ part_ix⊔digits
Moore ← {⌽⟜𝕩¨⋈⌜˜¯1‿0‿1}
# These magical functions come from Marshall, aka mlochbaum, the creator of BQN
# There's all types of higher order array wrangling
# <⎉1⍉∘>∘⥊ # list variant, colapses internal shape information
# <⎉2⍉⍟2> # shape preserving variant
# =⊸{<⎉𝕨⍉⍟𝕨>𝕩} # generic shape preserving, in bqncrate
# Invert array of same-rank arrays, exchanging inner with outer axes
Magic ← {𝕨 <⎉2⍉⍟2> 𝕩}
Exactly2 ← {
g ← ⊑1↓˘1↓ ⊑¨ 𝕩
p ← ¯1⊸≠⊸/ ⍷ 1⊑¨ ⥊ 𝕩
g∧2=≠p ? p ; ⟨⟩
}
Cleanup ← ⟨⟩⊸≢¨⊸/⍷∘⥊
p2 ← +´ (×´⊏⟜part_n)¨ Cleanup Exactly2¨ Magic Moore gears ⋈¨ part_ix
•Show ⟨"Part 2", p2⟩