Najprej preberimo podatke; ločimo jih na koordinate in navodila za prepogibanje.
import numpy as np
= open("example.txt").read().split("\n\n") xy, instructions
Spisek koordinat razdelimo na vrstice (xy.splitlines()
).
Za vsako vrstico (for v in xy.splitlines()
) sestavimo
seznam, ki vsebuje števila iz vrstice, ki jo razbijemo z vejico kot
ločilom ([int(x) for x in v.split(",")]
). Ta seznam
seznamov spremenimo v tabelo
= np.array([[int(x) for x in v.split(",")]
xy for v in xy.splitlines()])
xy
array([[ 6, 10],
[ 0, 14],
[ 9, 10],
[ 0, 3],
[10, 4],
[ 4, 11],
[ 6, 0],
[ 6, 12],
[ 4, 1],
[ 0, 13],
[10, 12],
[ 3, 4],
[ 3, 0],
[ 8, 4],
[ 1, 10],
[ 2, 14],
[ 8, 10],
[ 9, 0]])
V prvem stolpcu so koordinate x
, v drugem
y
. Poiskati moramo največjo in prišteti 1 (ker začnemo z
0); bo bodo dimenzije naše tabele.
max(xy, axis=0) + 1 np.
array([11, 15])
Imeli bomo 15 vrstic in 11 stolpcev, torej moramo to še obrniti. Tako
dobimo obliko, ki jo podamo np.zeros
. Recimo, da bomo
uporabljali tabelo bool
-ov.
= np.zeros(np.max(xy, axis=0)[::-1] + 1, dtype=bool) dots
Zdaj pa na mesta, ki ju določajo koordinate y
in
x
(dobimo jih z xy[:, 1]
in
xy[:, 0]
) zapišemo enice.
1], xy[:, 0]] = 1 dots[xy[:,
Na hitro izpišimo, da vidimo, kaj imamo: gremo čez vse vrstice
(for v in dots
), za vsako gremo čez vse vrednosti
for i in v
, in to vrednost, spremenjeno v int
,
uporabimo kot indeks v niz ".#"
; kadar je i
enak 0
, bomo izpisali .
, kadar je
1
, pa #
. Znakce združimo z
"".join
, vrstice pa z "\n".join
.
print("\n".join("".join(".#"[int(i)] for i in v) for v in dots))
...#..#..#.
....#......
...........
#..........
...#....#.#
...........
...........
...........
...........
...........
.#....#.##.
....#......
......#...#
#..........
#.#........
Tole je enako kot v opisu v nalogi, torej pravilno. Celotno branje je torej, še enkrat
= open("example.txt").read().split("\n\n")
xy, instructions
= np.array([[int(x) for x in v.split(",")] for v in xy.splitlines()])
xy = np.zeros(np.max(xy, axis=0)[::-1] + 1, dtype=bool)
dots 1], xy[:, 0]] = 1 dots[xy[:,
Še nekoliko preprosteje je, če koordinate vrtimo kar brez
numpy
-ja, za kar pa je potrebno znati transponirati podatke
z zip
.
= open("example.txt").read().split("\n\n")
xy, instructions
= zip(*(map(int, v.split(",")) for v in xy.splitlines()))
x, y = np.zeros((max(y) + 1, max(x) + 1), dtype=bool)
dots = 1 dots[y, x]
Tako ali drugače torej dobimo začetni razpored pik.
Zdaj gremo čez navodila. Če vrstica navodil vsebuje y
,
prepogibamo tako, da seštevamo spodnje in zgornje vrstice, sicer
seštevamo levi in desni del. Če sta h
in w
trenutni dimenziji (h, w = dots.shape
), je
dots[:h // 2]
je zgornja polovica vrstic,
dots[:h // 2:-1]
pa prezrcaljena spodnja polovica. Podobno
je dots = dots[:, :w // 2]
leva polovica,
dots[:, :w // 2:-1]
pa prezrcaljena desna. Tidve ali onidve
polovici seštejemo in tako dobimo novo matriko pik.
for instruction in instructions.splitlines():
= dots.shape
h, w if "y" in instruction:
= dots[:h // 2] + dots[:h // 2:-1]
dots else:
= dots[:, :w // 2] + dots[:, :w // 2:-1]
dots
print("\n".join("".join(".#"[int(i)] for i in v) for v in dots))
#####
#...#
#...#
#...#
#####
.....
.....
In to je to. Če reč poženemo na pravih podatkih (recimo mojih),
dobimo nekaj črk, ki jih je bilo potrebno vnesti. Mimogrede poskrbimo le
še za prvi del naloge, ki je hotel, da izpišemo število pik po prvem
koraku prepogibanja. Za to bomo števili korake in če je števec enak
0
, izpisali vsoto tabele.
= open("input.txt").read().split("\n\n")
xy, instructions
= np.array([[int(x) for x in v.split(",")] for v in xy.splitlines()])
xy = np.zeros(np.max(xy, axis=0)[::-1] + 1, dtype=bool)
dots 1], xy[:, 0]] = 1
dots[xy[:,
for i, instruction in enumerate(instructions.splitlines()):
= dots.shape
h, w if "x" in instruction:
= dots[:, :w // 2] + dots[:, :w // 2:-1]
dots else:
= dots[:h // 2] + dots[:h // 2:-1]
dots if not i:
print(np.sum(dots))
print("\n".join("".join(".#"[int(i)] for i in v) for v in dots))
712
###..#....#..#.####...##.###....##.####.
#..#.#....#..#.#.......#.#..#....#.#....
###..#....####.###.....#.#..#....#.###..
#..#.#....#..#.#.......#.###.....#.#....
#..#.#....#..#.#....#..#.#....#..#.#....
###..####.#..#.#.....##..#.....##..#....