Uvozimo numpy in preberemo podatke.
import numpy as np
state = np.array([list(v.strip()) for v in open("example.txt")])Vsako vrstico smo odstripali znaka za novo vrsto in jo spremenili v seznam. Stanje je zdaj
statearray([['v', '.', '.', '.', '>', '>', '.', 'v', 'v', '>'],
['.', 'v', 'v', '>', '>', '.', 'v', 'v', '.', '.'],
['>', '>', '.', '>', 'v', '>', '.', '.', '.', 'v'],
['>', '>', 'v', '>', '>', '.', '>', '.', 'v', '.'],
['v', '>', 'v', '.', 'v', 'v', '.', 'v', '.', '.'],
['>', '.', '>', '>', '.', '.', 'v', '.', '.', '.'],
['.', 'v', 'v', '.', '.', '>', '.', '>', 'v', '.'],
['v', '.', 'v', '.', '.', '>', '>', 'v', '.', 'v'],
['.', '.', '.', '.', 'v', '.', '.', 'v', '.', '>']], dtype='<U1')
Višino in širino si bomo za preglednejši rabo shranili v spremenljivki.
h, w = state.shapeOglejmo si tiste, ki hočejo dol. Kje so?
y, x = np.nonzero(state == "v")xarray([0, 7, 8, 1, 2, 6, 7, 4, 9, 2, 8, 0, 2, 4, 5, 7, 6, 1, 2, 8, 0, 2,
7, 9, 4, 7])
yarray([0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 5, 6, 6, 6, 7, 7,
7, 7, 8, 8])
Kakšne so koordinate polj pod njimi od njih?
newx, newy = x, (y + 1) % hnewy v resnici potrebujemo, newx, ki je kar
enak x, pa nam bo prišel prav kasneje.
Katera izmed teh polj, na katera bi šli tile, so prosta?
can_move = state[newy, newx] == "."can_movearray([ True, False, True, False, True, True, True, False, True,
False, True, False, False, True, True, True, True, True,
False, True, True, True, False, False, False, False])
Še enkrat izpišimo stanje (da ga bomo lažje primerjali), potem premaknimo tiste, ki jih lahko in potem ponovno izpišimo stanje.
statearray([['v', '.', '.', '.', '>', '>', '.', 'v', 'v', '>'],
['.', 'v', 'v', '>', '>', '.', 'v', 'v', '.', '.'],
['>', '>', '.', '>', 'v', '>', '.', '.', '.', 'v'],
['>', '>', 'v', '>', '>', '.', '>', '.', 'v', '.'],
['v', '>', 'v', '.', 'v', 'v', '.', 'v', '.', '.'],
['>', '.', '>', '>', '.', '.', 'v', '.', '.', '.'],
['.', 'v', 'v', '.', '.', '>', '.', '>', 'v', '.'],
['v', '.', 'v', '.', '.', '>', '>', 'v', '.', 'v'],
['.', '.', '.', '.', 'v', '.', '.', 'v', '.', '>']], dtype='<U1')
state[y[can_move], x[can_move]] = "."
state[newy[can_move], newx[can_move]] = "v"statearray([['.', '.', '.', '.', '>', '>', '.', 'v', '.', '>'],
['v', 'v', '.', '>', '>', '.', '.', '.', 'v', '.'],
['>', '>', 'v', '>', 'v', '>', 'v', 'v', '.', '.'],
['>', '>', 'v', '>', '>', '.', '>', '.', '.', 'v'],
['v', '>', 'v', '.', '.', '.', '.', '.', 'v', '.'],
['>', '.', '>', '>', 'v', 'v', '.', 'v', '.', '.'],
['.', '.', 'v', '.', '.', '>', 'v', '>', '.', '.'],
['.', 'v', '.', '.', '.', '>', '>', 'v', 'v', 'v'],
['v', '.', 'v', '.', 'v', '.', '.', 'v', '.', '>']], dtype='<U1')
Deluje, ne? Zložimo vse skupaj v program, premike v desno in dol pa zložimo v zanko, saj je večina dela enaka ne glede na smer.
state = np.array([list(v.strip()) for v in open("input.txt")])
changes = True
step = 0
h, w = state.shape
while changes:
changes = False
for dir in ">v":
y, x = np.nonzero(state == dir)
if dir == ">":
xnew, ynew = (x + 1) % w, y
else:
xnew, ynew = x, (y + 1) % h
can_move = state[ynew, xnew] == "."
state[y[can_move], x[can_move]] = "."
state[ynew[can_move], xnew[can_move]] = dir
changes = changes or np.any(can_move)
step += 1
print(step)534
Rešitev je lepa, ker vse teče lepo, vzporedno, z minimalnim številom zank, pa tudi kar razumljivo je.
S tem se naš tečaj končuje. Upam, da ste prišli čez, se veliko naučili in se ob tem tudi zabavali.
Srečno novo leto!