2015. december 5., szombat

Advent of Code 01-02

Azt hiszem időszerű újra írni valami kis bejegyzést, elvégre már majdnem vége az évnek!

Redditen találtam az Advent of Code nevű kezdeményezést, ami arról szól, hogy a programozói adventi kalendáriumnak minden ablaka 2 kis kódolni való feladványt rejt. A történt ismertetése után adnak pár kisebb példát hogy milyen inputra milyen outputot kell adni, majd elengedik az ember kezét, és egyedül kell onnantól válaszolni. A részvételhez regisztráció szükséges, de a feladatok szövege a nélkül is elolvasható. Ebben a bejegyzésben a feladat címére kattintva elolvashatjátok a részleteket is. Ahogy a címből látszik, ez post az első 2 ablakról szól, összesen 4 példáról. A teljes sorozatot itt ki lehet listázni.

Na akkor lássuk is őket:

#01 — Day 1: Not Quite Lisp —

A történt szerint a jó öreg télapó mászkál egy végtelen magas és végtelen mély épületben ajándékokat kézbesítve, és az inputján a ) karakterek azt jelenik, hogy egy emeletet lejjebb kell másznia, míg a ( egy emeletet felfelé jelent.

A kérdés az, hogy az input beolvasása végén melyik emeleten áll majd a télapó?

Ezek szerint:
- A (()) és ()() ugyan úgy a 0. emeletet redeményezi
- A ((( és (()(()( a 3. emeletet
- A ))((((( is a 3. emelet
- A (() és ))( egyaránt a -1. emelet
- A ))) és )())()) egyaránt a -3.

Az egyszerű végénél fogtam meg a problémát: külön-külön megszámolom hogy hányszor halad fel vagy le és kivonom őket egymásból:

data = input()
print(data.count('(') - data.count(')'))

2. rész

A második részben az a kérdés, hogy hányadik volt az az utasítás, amikor először érkezett meg a pincébe a télapó?

Példa:
- Ha az input egy ) akkor az 1. utasításnál érkezett a pincébe
- ()()) esetén az 5. utasításnál

Ez egy picit hosszabb már:

data = input()

position = 0
for i, c in enumerate(data, 1):
    if c == '(':
        position += 1
    elif c == ')':
        position -= 1

    if position < 0:
        print(i)
        break
else:
    print('Never entered the basement')

Az aktuális pozíciót a position változó tárolja. A feladat specifikálta hogy ez a 0. Ez után karakterenként iteráljuk az inputot, az enumerate() gondoskodik a szorszámozásról. Fontos: a feladat szerint 1-től indul a számozás, így itt ezt meg is adtam paraméterül.

Ezek után egyszerűen ( esetén csökkentjük a pozíciót, ) esetén növeljük. Amint a position kisebb mint 0, kiírjuk a karakter sorszámát és brake-el elhagyjuk a terepet.
Ha sose lépünk be a ciklusba, vagy sose érünk le a pincébe, akkor a rend kedvéért kiírjuk hogy Never entered the basement.

#02 — Day 2: I Was Told There Would Be No Math —

Ebben a feladatban azt kellett kiszámolni, hogy a tégla alakú csomagokhoz mennyi csomagoló papírra van szükség. A felületet a 2*l*w + 2*w*h + 2*h*l képlettel lehet kiszámolni. Extra csavar, hogy van egy kis ráhagyás is a csomagolásnál: a legkisebb oldal felülete.

A kérdés: mennyi csomagolóanyag kell összesen?

A példák szerint:
- A 2x3x4-es dobozhoz 2*2*3 + 2*3*4 + 2*4*2 = 52 négyzetláb* mennyiségű csomagolás és 2*3=6 négyzetláb ráhagyás kell, összesen tehát 52 + 6 = 58 négyzetláb csomagolóanyag.
- A 1x1x10-es dobozhoz 2*1*1 + 2*1*10 + 2*10*1 = 42 négyzetláb csomagolóanyag és 1*1 = 1 ráhagyás, összesen 42 + 1 = 43 négyzetláb tehát.
*A mértékegységnek nincs jelentősége ebben a példában

total = 0

while True:
    dimension = input()
    if dimension == '':
        print(int(total))
        break
    else:
        l, w, h  = [int(_) for _ in dimension.split('x')]

        areas = [(2 * l * w), (2 * w * h), (2 * h * l)]
        total += sum(areas) + (min(areas)/2)

A jó öreg Pythonos hátultesztelő patternnel indul a kód: addig olvasunk be méreteket amíg üres sort nem kapunk eredményül (tehát az utolsó adat után egy sima ENTER-t kell nyomni). Ha megvolt az üres sor akkor kiíródik a számláló (amit formai okokból int-é alakítok) és távozunk a ciklusból.

Ha viszont nem üres sort kaptunk, akkor a 'x' karakterek mentén szétvágjuk a beolvasott sort, minden értékét int-é castoljuk és szépen kicsomagoljuk őket 3 változóba: l, w és h.

Ezt követően kiszámoljuk a test 3 oldalának felületeit, ami bekerül az areas tömbbe. A legvégén pedig a számlálóhoz hozzáadjuk az oldalak felületeinek összegét, és a min(areas)-al a legkisebb felületet is. Itt kell még egy plusz osztás, mert korábban fel lett szorozva minden érték!

2. rész

A második részben azt kell kiszámolni hogy egy csomaghoz mennyi szalagra van szükség. Ebbe bele kell számolni a masnihoz szükséges mennyiséget is. A szalag hossza a doboz legkisebb kerületével egyenlő. A masnihoz szükséges plusz mennyiség pedig annyi mint az ajándék térfogata (mértékegység nélkül)

A kérdés az, hogy mennyi szalag kell az összes ajándékhoz?

A példák szerint:
- A 2x3x4-es doboznál egyszer 2+2+3+3 = 10 lábnyi sima szalag és 2*3*4 = 24 láb masnis szalag kell, összesen tehát 10 + 24 = 34 láb.
- A 1x1x10-es doboznál 1+1+1+1 = 4 lábnyi szalag és 1*1*10 = 10 masni szalag kell, összesen 4 + 10 = 14 láb.

total = 0

while True:
    dimension = input()
    if dimension == '':
        print(int(total))
        break
    else:
        l, w, h  = sorted([int(_) for _ in dimension.split('x')])

        total += (l + l + w + w) + (l * w * h)

Ez a kód szinte tök ugyan az mint az előző. A különbség, hogy a szétvágott adat értékeit növekvő sorrendbe rendezem még mielőtt változókba rakosgatnám őket. Így az l és w változó összeadásával megkapom a legkisebb kerületet. A térfogatnak meg mindegy hogy milyen sorrendben jönnek a számok, a szorzás amúgy is kommutatív.

Jóéjt

Ez a kis rövid jutott így ma estére. Igyekszem nem jövő márciusban folytatni a sorozatot.

-slp

Nincsenek megjegyzések:

Megjegyzés küldése