Day 5: Supply Stacks

(besedilo naloge)

Imamo sliko skladišča in navodila, kaj prelagamo kam. Razlika med prvim in drugim delom je v tem, da v prvem delu navodilo "prestavi 3 pakete iz 2 na 4" izvedemo tako, da prestavimo te tri pakete enega za drugim (in tako obrnemo njihov vrstni red), v drugem delu pa prestavimo vse tri (ne da bi obrnili vrstni red).

    [D]
[N] [C]
[Z] [M] [P]
 1   2   3

move 1 from 2 to 1
move 3 from 1 to 3
move 2 from 2 to 1
move 1 from 1 to 2

Branje podatkov

Naloga je trivialna, obupno zoprno pa je branje podatkov. Po mnogo poskusih biti pameten in elegantnen, sem končal pri tem. Ni lepo, je pa vsaj pregledno.

from copy import deepcopy

lines, instructions = open("example.txt").read().split("\n\n")
lines = lines.splitlines()
stacks = {lines[-1][column]: [lines[row][column]
                              for row in range(len(lines) - 2, -1, -1)
                              if len(lines[row]) > column and lines[row][column] != " "]
          for column in range(1, len(lines[-1]), 4)}

stacks2 = deepcopy(stacks)

Celotno vsebino datoteke razkosamo na lines in instructions.

Potem imamo zanko, ki šteje stolpce: column bo šel po x-koordinatah slike: prvi stolpec je na indeksu (znotraj vrstica) 1, drugi na 5 in tako naprej.

Zanka sestavlja slovar.

To je to. Grdo, ampak dela.

Na koncu naredimo kopijo vsega, za drugi del. Če bi naivno napisali stacks2 = stacks.copy(), bi dobili kopijo slovarja, ki pa bi vseboval iste elemente. Ker želimo, da so tudi elementi kopije, uporabimo funkcijo deepcopy iz modula copy.

Zdaj pa bomo kar vzporedno rešili oba dela.

Beremo navodila. Če jih razbijemo s split, bomo vedno dobili šest reči, pri čemer nas zanimajo, druga, četrta in šesta, ki povedo koliko paketov premikamo, odkod in kam.

Vzamemo torej navodila; s strip() odsekamo zadnji \n, da ne bo sitnosti; jih s splitlines razbijemo na vrstice, in nato vsak niz razbijemo s str.split na besede. Iz teh razbitij vzamemo quantity, source in destination.

Potem prelagamo tovor: v prvem delu prestavimo zadnjih quantity elementov v obratnem vrstnem redu, za drugi del v takšnem, kot je.

for _, quantity, _, source, _, destination in map(str.split, instructions.strip().splitlines()):
    quantity = int(quantity)

    # Part 1
    stacks[destination] += stacks[source][-1:-quantity-1:-1]
    del stacks[source][-quantity:]

    # Part 2
    stacks2[destination] += stacks2[source][-quantity:]
    del stacks2[source][-quantity:]

Na koncu izpišemo, kot zahteva naloga, imena vrhnjih paketov.

print("".join(stack[-1] for stack in stacks.values()))
print("".join(stack[-1] for stack in stacks2.values()))
CMZ
MCD