parent
540bbb9a9e
commit
98a4dffb3c
125
day23/sol.ivy
125
day23/sol.ivy
|
@ -1,7 +1,8 @@
|
||||||
)get "input.ivy"
|
)get "input.ivy"
|
||||||
sample = 7 7 rho '....#..' '..###.#' '#...#.#' '.#...##' '#.###..' '##.#.##' '.#..#..'
|
sample = 7 7 rho '....#..' '..###.#' '#...#.#' '.#...##' '#.###..' '##.#.##' '.#..#..'
|
||||||
|
|
||||||
board = sample == '#'
|
#board = sample == '#'
|
||||||
|
board = input == '#'
|
||||||
#board
|
#board
|
||||||
|
|
||||||
op north a = 1 flip a
|
op north a = 1 flip a
|
||||||
|
@ -11,6 +12,9 @@ op east a = -1 rot a
|
||||||
|
|
||||||
#north 3 3 rho iota 9
|
#north 3 3 rho iota 9
|
||||||
|
|
||||||
|
op lift a = (1,rho a) rho a
|
||||||
|
op n moveNSWE a = (lift n flip a[1]), (lift (-n) flip a[2]), (lift n rot a[3]), (lift (-n) rot a[4])
|
||||||
|
|
||||||
op a coalesce b =
|
op a coalesce b =
|
||||||
a: a
|
a: a
|
||||||
b
|
b
|
||||||
|
@ -22,43 +26,102 @@ op maybePad a =
|
||||||
needsPad a: pad a
|
needsPad a: pad a
|
||||||
a
|
a
|
||||||
|
|
||||||
|
op maybePad1 a =
|
||||||
|
c1 = any a[1]
|
||||||
|
c2 = any a[(rho a)[1]]
|
||||||
|
c1 and c2: 0,a,0
|
||||||
|
c1: 0,a
|
||||||
|
c2: a,0
|
||||||
|
a
|
||||||
|
|
||||||
|
op maybePad a =
|
||||||
|
a = maybePad1 a
|
||||||
|
(any a[;1]) or (any a[;(rho a)[2]]): transp maybePad1 transp a
|
||||||
|
a
|
||||||
|
|
||||||
op smearWE a = a or (west a) or (east a)
|
op smearWE a = a or (west a) or (east a)
|
||||||
op smearNS a = a or (north a) or (south a)
|
op smearNS a = a or (north a) or (south a)
|
||||||
op lift a = (1,rho a) rho a
|
|
||||||
|
|
||||||
op show a = (text ".#23456789"[1+a]),"\n-"
|
op show a = (text ".#23456789"[1+a]),"\n-"
|
||||||
|
|
||||||
M = 0
|
M = 0
|
||||||
|
|
||||||
a = maybePad board
|
op axis1 a = 3 1 2 transp a
|
||||||
n = south smearWE a
|
|
||||||
s = north smearWE a
|
|
||||||
e = west smearNS a
|
|
||||||
w = east smearNS a
|
|
||||||
#n
|
|
||||||
|
|
||||||
p = 4 3 2 1
|
op look a =
|
||||||
|
ns = lift smearNS a
|
||||||
|
we = lift smearWE a
|
||||||
|
-1 moveNSWE (we, we, ns, ns)
|
||||||
|
|
||||||
C = (lift n) , (lift s) , (lift w) , (lift e)
|
op dup4 a = (4,rho a) rho a
|
||||||
rho C
|
|
||||||
canMove = a and or/ 3 1 2 transp C # can move if there is an elf nearby
|
# look in each direction
|
||||||
C2 = (not C) and (rho C) rho canMove # can move in a direction if not alone and there is no elf in that direction
|
# an elf can move in a direction if there is no elf in said direction and there is an elf somewhere nearby
|
||||||
show C2
|
# returns a 4x(rho a) matrix
|
||||||
P1 = max/ p * 3 1 2 transp C2 # select direction
|
op canMove a =
|
||||||
P2 = p o.== P1 # decompose into 4x?x? matrix
|
C = look a
|
||||||
P1; "\n-"
|
(not C) and dup4 (a and or/axis1 C)
|
||||||
C3 = (north P2[1]) + (south P2[2]) + (west P2[3]) + (east P2[4])
|
|
||||||
C3; "\n-"
|
|
||||||
notBlock = C3 == 1
|
# prepare moves
|
||||||
C4 = (lift south notBlock), (lift north notBlock), (lift east notBlock), (lift west notBlock)
|
# assign each move a priority and take the max
|
||||||
rho C4
|
# remove lower priority moves
|
||||||
P3 = P2 and C4
|
op p prepare choices =
|
||||||
show P3
|
best = max/ p * axis1 choices # select best direction
|
||||||
moved = or/ 3 1 2 transp P3
|
p o.== best # decompose into 4x?x? matrix
|
||||||
moved
|
|
||||||
#a and not moved
|
# count how many elves want to move to each square
|
||||||
#show P3
|
# filter out moves which conflict
|
||||||
B = (a and not moved) + (north P3[1]) + (south P3[2]) + (west P3[3]) + (east P3[4])
|
op unblocked moves =
|
||||||
show a
|
open = 1 == +/axis1 1 moveNSWE moves
|
||||||
show B
|
moves and -1 moveNSWE dup4 open
|
||||||
|
|
||||||
|
priority = 4 3 2 1
|
||||||
|
M = 0
|
||||||
|
changed = 0
|
||||||
|
|
||||||
|
op M round a =
|
||||||
|
a = maybePad a
|
||||||
|
moves = unblocked (M flip priority) prepare canMove a
|
||||||
|
moved = or/axis1 moves
|
||||||
|
changed; changed = +/, moved
|
||||||
|
b = (a and not moved) + +/axis1 1 moveNSWE moves
|
||||||
|
b
|
||||||
|
|
||||||
|
op round a = M round a
|
||||||
|
|
||||||
|
# this is implemented using globals
|
||||||
|
# to store the board instead of recursion
|
||||||
|
# in order to avoid keeping a bunch of large
|
||||||
|
# intermediate values alive on the stack
|
||||||
|
B = 0
|
||||||
|
op i loop n =
|
||||||
|
i > n: i
|
||||||
|
changed; changed = 0
|
||||||
|
B = M round B
|
||||||
|
M = M - 1
|
||||||
|
changed == 0: i
|
||||||
|
(i+1) loop n
|
||||||
|
|
||||||
|
op n rounds a =
|
||||||
|
B; B = a
|
||||||
|
M; M = 0
|
||||||
|
1 loop n
|
||||||
|
B
|
||||||
|
|
||||||
|
op n numrounds a =
|
||||||
|
B; B = a
|
||||||
|
M; M = 0
|
||||||
|
1 loop n
|
||||||
|
|
||||||
|
op score a =
|
||||||
|
a = maybePad a
|
||||||
|
n = */ (rho a) - 2
|
||||||
|
n - +/, a
|
||||||
|
|
||||||
|
show round board
|
||||||
|
show 10 rounds board
|
||||||
|
score 10 rounds board
|
||||||
|
|
||||||
|
1000 numrounds board
|
||||||
|
#numrounds board
|
||||||
|
|
Loading…
Reference in New Issue