animate 16
This commit is contained in:
parent
3d6bf4f154
commit
a7dfd81d21
|
@ -21,3 +21,7 @@ or
|
|||
```
|
||||
kotlinc -include-runtime -d seven.jar seven.kt && java -jar seven.jar < input7
|
||||
```
|
||||
or
|
||||
```
|
||||
./sechszehn.py -vv <input16
|
||||
```
|
||||
|
|
97
sechszehn.py
97
sechszehn.py
|
@ -1,12 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from useful import *
|
||||
import cv2 as cv
|
||||
|
||||
def draw(pic, backup):
|
||||
for y in range(pic.shape[0]):
|
||||
for x in range(pic.shape[1]):
|
||||
print('#' if pic[y,x] else {45:'/',135:'\\',0:'-',90:'|'}.get(backup[y,x], '.'), end='')
|
||||
print()
|
||||
from useful import *
|
||||
|
||||
sin = {0:0,90:-1,180:0,270:1}
|
||||
cos = {0:1,90:0,180:-1,270:0}
|
||||
|
@ -15,11 +11,56 @@ mirrors = np.array([[{'/':45,'\\':135,'-':0,'|':90,'.':69}[c] for c in l] for l
|
|||
size = mirrors.shape[0] # w = h anyway, don't bother genericizing
|
||||
done = np.zeros((size * 4, 4, size, size), dtype=bool)
|
||||
|
||||
totest=deque()
|
||||
verbose = len(sys.argv) > 1 and '-v' in sys.argv[1]
|
||||
draw_every = 1 if verbose and '-vv' in sys.argv[1] else 666
|
||||
|
||||
if verbose:
|
||||
"""
|
||||
why aren't there single characters identifiers for top left or northwest?
|
||||
let's use initials of countries: canada, soviet, brazil, australia
|
||||
in addition to udlr and also "middle"
|
||||
"""
|
||||
initials = {letter: np.asarray(coords) / 2 for coords, letter in
|
||||
np.ndenumerate(np.array(list('cuslmrbda')).reshape((3, 3)))}
|
||||
mirror_rections = {45:'bs',135:'ca',0:'lr',90:'ud'}
|
||||
frame = 0
|
||||
cv.namedWindow('lasers', flags=cv.WINDOW_GUI_NORMAL | cv.WINDOW_AUTOSIZE)
|
||||
|
||||
def draw(linger=16):
|
||||
global canvas, frame
|
||||
for (y, x), angle in np.ndenumerate(mirrors): # just put them on top
|
||||
if angle == 69:
|
||||
continue
|
||||
line(y, x, mirror_rections[angle], (0x7f, 0x9a, 0xa5)[::-1])
|
||||
zewm = 840 // canvas.shape[0]
|
||||
cv.imshow('lasers', np.kron(canvas, np.ones((zewm, zewm, 1), dtype='uint8')))
|
||||
#cv.imwrite('lasers%04d.png' % frame, np.kron(canvas, np.ones((zewm, zewm, 1), dtype='uint8')))
|
||||
frame += 1
|
||||
cv.waitKey(linger)
|
||||
|
||||
def line(y, x, rection, color):
|
||||
global canvas, scale
|
||||
off1 = initials[rection[0]]
|
||||
off2 = initials[rection[1]]
|
||||
cv.line(canvas,
|
||||
(x * scale + int(off1[1] * (scale - 1)),
|
||||
y * scale + int(off1[0] * (scale - 1))),
|
||||
(x * scale + int(off2[1] * (scale - 1)),
|
||||
y * scale + int(off2[0] * (scale - 1))),
|
||||
color,
|
||||
1)
|
||||
|
||||
scale = 7
|
||||
canvas = np.kron(np.ones((size * scale, size * scale, 1)),
|
||||
np.asarray((0x43, 0x3c, 0x34))[::-1].reshape((1, 1, 3))).astype('uint8')
|
||||
|
||||
draw(1000)
|
||||
|
||||
def nextvel(y, x, vel):
|
||||
here = mirrors[y,x]
|
||||
if here == 45: # 0->90 avv, 180->270 avv: (init % 180)
|
||||
if here == 69:
|
||||
return [vel, ]
|
||||
elif here == 45: # 0->90 avv, 180->270 avv: (init % 180)
|
||||
return [(vel // 180) * 180 + (90 - vel % 180), ]
|
||||
elif here == 135: # 0->270 avv, 180->90 avv
|
||||
return [270 - vel, ]
|
||||
|
@ -33,8 +74,6 @@ def nextvel(y, x, vel):
|
|||
return [90, 270]
|
||||
else:
|
||||
return [vel, ]
|
||||
elif here == 69:
|
||||
return [vel, ]
|
||||
else:
|
||||
raise ValueError('omg')
|
||||
|
||||
|
@ -49,14 +88,41 @@ def set_done(y, x, vel, beam):
|
|||
done[beam,vel // 90,y,x] = True
|
||||
|
||||
def test(y, x, vel, beam):
|
||||
if len(sys.argv) > 1 and sys.argv[1] == '-v' and beam == 0:
|
||||
ic(y, x, vel)
|
||||
global totest
|
||||
if is_done(y, x, vel, beam):
|
||||
return
|
||||
set_done(y, x, vel, beam)
|
||||
totest += nexts(y, x, vel, beam)
|
||||
if verbose and beam % draw_every == 0: # meh
|
||||
here = mirrors[y,x]
|
||||
if here == 69:
|
||||
line(y, x, {0:'lr',90:'ud'}[vel%180], (0, 0, 255))
|
||||
elif here == 45: # 0->90 avv, 180->270 avv: (init % 180)
|
||||
if vel in (0, 270):
|
||||
line(y, x, 'lm', (0, 0, 255))
|
||||
line(y, x, 'mu', (0, 0, 255))
|
||||
else:
|
||||
line(y, x, 'rm', (0, 0, 255))
|
||||
line(y, x, 'md', (0, 0, 255))
|
||||
elif here == 135:
|
||||
if vel in (0, 90):
|
||||
line(y, x, 'lm', (0, 0, 255))
|
||||
line(y, x, 'md', (0, 0, 255))
|
||||
else:
|
||||
line(y, x, 'rm', (0, 0, 255))
|
||||
line(y, x, 'mu', (0, 0, 255))
|
||||
elif here == 0:
|
||||
if vel == 90:
|
||||
line(y, x, 'dm', (0, 0, 255))
|
||||
elif vel == 270:
|
||||
line(y, x, 'um', (0, 0, 255))
|
||||
elif here == 90:
|
||||
if vel == 0:
|
||||
line(y, x, 'lm', (0, 0, 255))
|
||||
elif vel == 180:
|
||||
line(y, x, 'rm', (0, 0, 255))
|
||||
|
||||
totest=deque()
|
||||
for step in range(size):
|
||||
totest += [(step, 0, 0, step), ]
|
||||
totest += [(step, size - 1, 180, step + size), ]
|
||||
|
@ -64,10 +130,13 @@ for step in range(size):
|
|||
totest += [(size - 1, step, 90, step + size * 3), ]
|
||||
|
||||
while totest:
|
||||
if len(sys.argv) > 1 and sys.argv[1] == '-v':
|
||||
draw(done[0].sum(axis=0), mirrors)
|
||||
if verbose:
|
||||
draw()
|
||||
for _ in range(len(totest)):
|
||||
test(*totest.popleft())
|
||||
|
||||
print(np.count_nonzero(done[0].sum(axis=0).astype(bool)))
|
||||
print(max(np.count_nonzero(done.sum(axis=1).astype(bool), axis=(1, 2))))
|
||||
|
||||
if verbose:
|
||||
draw(0)
|
||||
|
|
Loading…
Reference in New Issue