Portál AbcLinuxu, 21. května 2024 19:01

pocity zážitky a dojmy z adventofcode 2020

28.12.2020 11:48 | Přečteno: 2882× | Výběrový blog | poslední úprava: 31.12.2020 02:32

pozorrr!!!!!!!! :O :O vykecám správný/fungující řešení takže kdo nechce přijít vo překvápko protože si to jako chce taky jakoby zahrát tak nečíst!!!!!!!!! :O :O

Adventofcode hele je něco jako takovej adventní kalendář na čokoládky akorátže misto čokoládky z něj každý ráno vypadne nějakej drobnej problémek na psaní zdrojáčku nebo argolitmizaci. Blbý na něm je to že se tam musíte registrovat protože všecky ty zadání má každej uživatel nějaký svý unikátní. Blbý taky je že se nemáte vubec šanci dostat do tabulky s highscore protože má asi jenom nějakejch sto míst ato ždycky vobsaděj různý nejšvihlejší poloautisti co už maj hotový řešení zatimco my normální lidi eště ani nemáme způlky dočtený zadání :/ :/

Ale jinak to celkem šlo i když věčina úkolů byla nudná tak se dva tři zajímavý našli :D noa když jako přihlídneme ktomu že to ten člověk vymejšlí a piše sám ve svým volným čase tak to je uplně supr věc :D

Úkolů bylo zadanejch 25, každej je na dvě půlky, lechčí a těší. Za každou vyřešenou půlku úkolu mužem jakoby dostat nějakou takovou zlatou minci s vodní hvězdicí a musíme jich nazbírat všech pade aby se nám rozhejbala animace toho vánočního kalendáře. Nóóóóó nebylo to teda nicmoc extra ta animace abyste teda jako neměli nějaký velký vočekávání :/ :/

Mý řešení těch úkolů. Sem to dělala v pythonu protože v pythonu se uplně nejrychlejc dá něco takovýho naprasečit :D zdrojáčky co tady u těch jednotlivejch úkolů sou pepeless hnus a dělám tam vošklivý věci takle se rozhodně v pythonu programovat nemá a vubec sem je nechtěla ukazovat :O :O ale fungujou :D :D voni po nás taky naštěstí ve všech těch úkolech chtěj jenom nějakej numerickej výsledek a vubec po nás nechtěj abysme jim tam strkali na net svuj skriptík/prográmek takže si mužem prasit jak jako jenom uznáme za vhodný :O :D :D ;D

prvních několik dnů bylo uplně jednoduchejch

1. den

Proiterovat pole a najít společnej součet nejdřiv dvou čísel. V druhý půlce uplně to samý ale pro tři čísla v poli.

nums = []
inp = open('input')
for row in inp.readlines():
    nums.append(int(row))
    
nums_len = len(nums)

# první část
for i in range(nums_len):
    for j in range(i, nums_len):
        a = nums[i]
        b = nums[j]
        if(a + b == 2020):
            print(f'num1: {a} num2 {b} mul {a*b}')
            
# druhá část
for i in range(nums_len):
    for j in range(i, nums_len):
        for k in range(j, nums_len):
            a = nums[i]
            b = nums[j]
            c = nums[k]
            if(a + b + c == 2020):
                print(f'num1: {a} num2 {b} num3 {c} mul {a*b*c}')

2. den

procházení stringu a počitání znaků

input = open('input')

# počty validních hesel který jako máme zistit
kolik_valid_cast1 = 0
kolik_valid_cast2 = 0

def count(pismeno, heslo):
    sum = 0
    for ch in heslo:
        if ch == pismeno:
            sum += 1
    return sum

for pswd in input.readlines():
    
    parts = pswd.split(' ')
    
    min, max = parts[0].split('-')
    min = int(min)
    max = int(max)
    
    pismeno = parts[1][0]
    
    heslo = parts[2]
    
    print(pswd)
    pocet = count(pismeno, heslo)
    print(f'min {min} max {max} pismeno {pismeno} heslo {heslo} \n okurence {pocet}')
    
    if pocet >= min and pocet <= max:
        kolik_valid_cast1 += 1
        
    # část dva
    print(len(heslo))
    prvni_char = heslo[ min -1 ]
    druhy_char = heslo[ max -1 ]
    
    if prvni_char != druhy_char and (prvni_char == pismeno or druhy_char == pismeno):
        print("valid")
        kolik_valid_cast2 += 1

print(f'kolik_valid_cast1: {kolik_valid_cast1}')
print(f'kolik_valid_cast2: {kolik_valid_cast2}')

3. den

hejbání se v dvojrozměrným poli kde se jakoby znáčky jednotlivejch řádků vopakujou 'donekonečna'

lines = open('input').readlines()

len_radku = len(lines[0]) - 1 # zrada!!!!!!!!!!!!!!!!!!!!!! :O :O
# na konci řádku bylo jedno prázdný místo pokaždý :O :O :/ :/
def is_pozice_strom(radek, pozice):
    
    # korekce pozice pro vopakování řádku
    pozice = pozice % len_radku
    return radek[pozice] == '#'

def trasa_obyc(krok_len):
    x_pos = 0
    sum_stromu = 0
    for radek in lines:
        if is_pozice_strom(radek, x_pos):
            sum_stromu += 1
        x_pos += krok_len
        
    return sum_stromu

print()
print(trasa_obyc(3))

# část dva

# trasa kdy se skáče po dvou políčkách dolu a doprava jen vojedno
def trasa_extra(krok_len):
    x_pos = 0
    preskocit = True
    sum_stromu = 0
    for radek in lines:
        preskocit = not preskocit
        if preskocit:
            continue
        if is_pozice_strom(radek, x_pos):
            sum_stromu += 1
        x_pos += krok_len
        
    return sum_stromu


vysledek = trasa_obyc(1) * trasa_obyc(3) *trasa_obyc(5) * trasa_obyc(7) * trasa_extra(1)
print(vysledek)

4. den

validování takovejch jakože osobních průkazek jestli tam je všecko co tam má bejt a jeto dobře napsaný

import re

cele = open('input').read()[:-1]
passports = cele.split('\n\n')


def valid(passport):
    for key in ['byr', 'iyr', 'eyr', 'hgt', 'hcl', 'ecl', 'pid']:
        if not key in passport:
            return False
    return True

kolik_valid = 0
for ps in passports:
    if valid(ps):
        kolik_valid += 1
        
print(kolik_valid)

# část dva

def valid_ii(passport):
    if valid(passport):
        kusy = re.split('\s|\n',passport)
        slovnik = {}
        for kus in kusy:
            key, val = kus.split(':')
            slovnik[key] = val
            
        # validace jednotlivejch klíčů
        # rok
        if not slovnik['byr'].isnumeric():
            print('byr')
            return False
        rok = int(slovnik['byr'])
        if rok < 1920 or rok > 2002:
            print('byr')
            return False
        
        # issue rok
        if not slovnik['iyr'].isnumeric():
            print('iyr')
            return False
        rok = int(slovnik['iyr'])
        if rok < 2010 or rok > 2020:
            print('iyr')
            return False
        
        # eggspirace
        if not slovnik['eyr'].isnumeric():
            print('eyr')
            return False
        rok = int(slovnik['eyr'])
        if rok < 2020 or rok > 2030:
            print('eyr')
            return False
        
        # vejska
        if not slovnik['hgt'].isalnum():
            print('hgt')
            return False
        num_part = ''
        str_part = ''
        hlidadlo = False
        for ch in slovnik['hgt']:
            if ch.isdigit():
                num_part += ch
                
                #číslo nemuže bejt někde mezi písmenama
                if hlidadlo:
                    print('hlidadlo')    
                    return False
            else:
                hlidadlo=True
                str_part += ch
                
        # natodleto sem zamoměla a furt jako kráva četla výstupy platnejch a 
        #neplatnejch aneane se dopočítat :O :/
        # byl tam jenom jeden takovej........
        if len(str_part) != 2: 
            return False
        vejska = int(num_part)
        if str_part=='in' and (vejska < 59 or vejska > 76):
            print('inchs')
            return False
        if str_part=='cm' and (vejska < 150 or vejska > 193):
            print('cms')
            return False
        
        # barva vlasů
        if not slovnik['hcl'][0] == '#':
            print('hcl')
            return False
        code = slovnik['hcl'][1:]
        if len(code) != 6 and not code.isalnum():
            print("hcl not six")
            return False
        if re.search('[g-zA-Z]',code) is not None:
            print("hcl regexp")
            return False
        
        #voči
        if not slovnik['ecl'].isalpha():
            print('ecl')
            return False
        if not slovnik['ecl'] in ['amb','blu','brn','gry','grn','hzl','oth']:
            print('ecl2')
            return False
        
        #pid
        if not slovnik['pid'].isnumeric() or len(slovnik['pid'])!=9:
            print('pid')
            return False
        
        return True
        
    return False


validni = []

kolik_valid = 0
for ps in passports:
    if valid_ii(ps):
        kolik_valid += 1
        validni.append(ps)
    else:
        print('invalid:')
        print(ps)
        print()
        print()
        print()
        
print(kolik_valid)

5. den - židle v letadle

tady to poprvý začalo bejt trošičku zajímavý :D

máme letadlo ve kterým sou židle k sezení voznačený stejně dlouhým kódem kterej se zkládá ze čtyr různejch písmen F B L a R který znamenaj přední půlka, zadní půlka, levá půlka a pravá půlka. každý to písmenko toho kódu nám dycky prostor kde muže bejt tamta židle dělí na půlku noa my se jakoby potřebujem dobrat ke konkrétním id těch židlí a najít maximální. v druhý půlce musíme zase jako najít id naší židle která jako v tom seznamu jedniná chybí.

tady sem se nejspíš lechce vodchýlila vod nima zamejšlenýho postupu a misto id použila na identifikaci židlí tuple xy souřadnicí protože sem si myslela že na každým místě muže bejt přece jenom jedna židle najednou jenže vono ne :O :O se ukázalo že každá souřadnice tam je dvakrát až teda na tu s naší židlí ta je tam jenom jednou. vono to letadlo je asi nějak na dvě půlky kde každá má svuj system souřadnic nebo nevim :D nóó takže to stálo trošičku přemejšlení navíc :D

def radek_to_id(radek):
    
    #řádek
    min = 0
    max = 127
    for i in range(7):
        d = abs(max - min) // 2
        ch = radek[i]
        if ch == 'F':
            max = min + d
        else: #B
            min += d
            
    row = max
    if radek[6] == 'B':
        row = min
    
    # sloupec
    
    min = 0
    max = 7
    
    for i in range(7,10):
        d = abs(max - min) // 2
        ch = radek[i]
        if ch == 'L':
            max = min + d
        else: #R
            min += d
            
    sloupec = max
    if radek[6] == 'R':
        sloupec = min

    id = row * 8 + sloupec
    
    return id, sloupec, row

        

id_list = []

souradnice_sedadel = []

max_y = 0

for radek in open('input').readlines():
    id, sloupec, row = radek_to_id(radek)
    id_list.append(id)
    pos = (sloupec, row)
    if row > max_y:
        max_y = row
    souradnice_sedadel.append(pos)
    
# v první části máme zistit jaká je max možná velikost id nějaký židle v tom letadle
print(f'max id: {max(id_list)}')
print(f'rows len: {max_y}')

# druhá část
# zištěný id mý židle

# se zdá že tam maj chybu a ta sada je jakoby nějaká zdovejná
# nebo semi to nějak podařilo zdojit mě tady????? nevim :O :O
# by to nemělo bejt velký 16 ale jenom 8 ale jeto těch 16 :O :O
# možná špatně chápu to jejich zadání nebo to maj jakoby blbě :D

for y in range(max_y):
    tmp = []
    for pos in souradnice_sedadel:
        if pos[1] == y:
            tmp.append(pos)
    if len(tmp) == 0:
        continue
    if len(tmp) == 15:
        _y = tmp[0][1]
        for x in range(8):
            if tmp.count((x,_y)) == 1:
                print((x,_y))
                print(f'moje id: {_y * 8 + x}')

6. den

zase jednoduchý. dělání s množinama kde se nám supr hodí pythoní oběkt set() na dělání průniku dvou množin a takový věci různý.

def zpracujDotaznik(dotaznik):
    znaky = set()
    for radek in dotaznik:
        for ch in radek.strip():
            znaky.add(ch)
            
    return len(znaky)

# pro druhou část
def zpracujDotaznik_ii(dotaznik):
    sady = []
    for radek in dotaznik.split('\n'):
        sada = set()
        for ch in radek:
            sada.add(ch)
        
        sady.append(sada)

    prunik = sady[0]
    if len(sady) > 1:
        for sada in sady[1:]:
            prunik = prunik.intersection(sada)

    return len(prunik)


suma = 0
suma_ii = 0
for dotaznik in open('input').read()[:-1].split('\n\n'):
    
    for r in dotaznik:
        print(r)
    kolik = zpracujDotaznik(dotaznik)
    for r in dotaznik:
        print(r)
    print('----------')
    suma += kolik
    
    suma_ii += zpracujDotaznik_ii(dotaznik)
    
    
print(f'vysledek: {suma}')
print(f'vysledek dva: {suma_ii}')

7. den

máme danej seznam různejch různobarevnejch pytlů noa každej ten pytel vobsahuje nula nebo různý množství jinejch pytlů z toho samýho seznamu. máme zadanej nějakej svuj lesklezlatej pytel a v první půlce musíme zistit kolik z těch všech různejch pytlů v tom seznamu muže vobsahovat ten náš. V druhý půlce zase musíme zistit přesnej počet jinejch pytlů který ten náš má jakoby skovanejch uvnitř v sobě.

voboje řešitelný rekurzí

první půlka

import re

input = open('input')
radky = input.readlines()

kolik_obsahuje_gold = 0

#obsahy jednotlivejch pytlů
obsahy = []

pytle_ktere_maj_gold = set()

def najdi(pytel):
    
    for o in obsahy:
        if o[1] is not []:
            print(o[1])
            if pytel in o[1]:
                print(pytel)
                print(o)
                print()
                pytle_ktere_maj_gold.add(o[0])
                najdi(o[0])
        

for radek in radky:
    kusy = radek.split('contain')
    obsah_pytle = kusy[1].split(',')
    barvy = []
    if obsah_pytle[0].strip() != 'no other bags.':
        for kus in obsah_pytle:
            kus = kus.strip()
            kusy_kusu = kus.split(' ')
            barva = kusy_kusu[1] + ' ' + kusy_kusu[2]
            barvy.append(barva)
    
    obsahy.append((kusy[0].split(' bags')[0], barvy))
    
    
for o in obsahy:
    if o[1] is not []:
        if 'shiny gold' in o[1]:
            pytle_ktere_maj_gold.add(o[0])
            najdi(o[0])

print()
print(pytle_ktere_maj_gold)
print(len(pytle_ktere_maj_gold))

druhá půlka

import re

input = open('input')
radky = input.readlines()

#obsahy jednotlivejch pytlů
obsahy = []

                
def kolik_pytel_pytlu(pytel_name):
    pytel = None
    for o in obsahy:
        if o[0] == pytel_name:
            pytel = o
            break
        
    pytlu = 0
    if len(pytel[1]) != 0:
        for subpytel in pytel[1]:
            print(subpytel)
            pridat = subpytel[0] + subpytel[0] * kolik_pytel_pytlu(subpytel[1])
            print(f"pridat: {pridat}")
            pytlu += pridat
    else:
        pytlu = 0
    return pytlu
        

for radek in radky:
    kusy = radek.split('contain')
    obsah_pytle = kusy[1].split(',')
    barvy = []
    if obsah_pytle[0].strip() != 'no other bags.':
        for kus in obsah_pytle:
            kus = kus.strip()
            kusy_kusu = kus.split(' ')
            barva = (int(kusy_kusu[0]), kusy_kusu[1] + ' ' + kusy_kusu[2])
            barvy.append(barva)
    
    obsahy.append((kusy[0].split(' bags')[0], barvy))


kolik = kolik_pytel_pytlu('shiny gold')
print(kolik)

8. den

v zadání je nějakej mocřádkovej zdrojáček složenej ze tří druhů instruckí acc jmp a nop a za každou je nějaký kladný nebo záporný číslo. acc dělá že přičte nebo vodečte hodnotu vod nějaký jediný společný proměný, jmp dělá že přeskočí v dělání instrukcí na jinej řádek jakože k aktuálnímu číslu řádku přičte tu svou hodnotu. noa operace nop nedělá vůůůbec nic.

v první půlce musíme zistit hodnotu tý společný proměný po tom co jaoby ten prográmek necháme bežet a zastavíme v okamžiku předtim než znova vleze na už naštívenej řádek. v druhý části musíme ve zdrojáčku vopravit přesně jednu instrukci tak aby nám už zdrojáček neběhal v nekonečnejch smyčkách a normálně celej proběh a pak taky říct hodnotu tý proměný.

tamten zadanej zdrojáček má jenom nějakejch slabejch +-600 řádků takže to vopravování instrukcí de ještě vpohodě udělat bez přemejšlení hrubou silou ;D

radky = open('input').readlines()

# jestli zdrojáček naštíví všechny instrukce
def ma_reseni():
    hodnota = 0
    navstivene = set()
    max_i =0
    i = 0
    while i < (len(radky)):
        if i > max_i:
            max_i = i
        if i in navstivene:
            break
        else:
            navstivene.add(i)
            
        instrukce, val = radky[i].strip().split(' ')
        if instrukce == 'nop':
            i +=1
            continue
        elif instrukce == 'jmp':
            x = int(val)
            i += x

            continue
        elif instrukce == 'acc':
            hodnota += int(val)
        
            i+= 1
    print(f'max i: {max_i} max len: {len(radky)}')
    return max_i == len(radky) -1
        
# postupně zkusíme vopravit všecky instrukce a budem koukat jestli toje jako
# tim našim hledaným řešením
i = 0
while i < (len(radky)): 
    
    radek = radky[i]
    if 'jmp' in radek or 'nop' in radek:
        original = radek
        if 'jmp' in radek:
            radky[i] = radek.replace('jmp', 'nop')
        else:
            radky[i] = radek.replace('nop', 'jmp')
            
        if ma_reseni():
            print('ma reseni')
            break
        else:
            radky[i] = original
    
    i+=1

# novej průběh
navstivene = set()
max_i =0
i = 0
hodnota = 0
while i < (len(radky)):
    print(f"i: {i}")
    if i > max_i:
        max_i = i
    if i in navstivene:
        break
    else:
        navstivene.add(i)
    print(radky[i].strip())
    instrukce, val = radky[i].strip().split(' ')
    if instrukce == 'nop':
        i +=1
        continue
    elif instrukce == 'jmp':
        x = int(val)
        i += x
        print(i)
        continue
    elif instrukce == 'acc':
        hodnota += int(val)
    
        i+= 1
        
print(f'hodnota: {hodnota}')

9. den

celkem nudný dělání s číslama nějaký prebambule nebo čeho jako

data = open('input').readlines()

preamble_len = 25
cisla = []
index = 0
for cislo in data:
    
    x = int(cislo)
    cisla.append(x)
    
cisla_len = len(cisla)


nevalidni_cislo = 0
for i in range(preamble_len, cisla_len):
    x = cisla[i]
    valid = False
    for j in range(i-preamble_len,i):
        for k in range(j+1, i):
            a = cisla[j]
            b = cisla[k]
            
            if x == a+b:
                valid = True
                break
        if valid:
            break
    
    if not valid:
        print(f'nevalidni: {x}')
        nevalidni_cislo = x
        break
    
# část dvě najít nudli čísel která dá dohromady to nevalidní a vypsat součet min a max prvku

for i in range(cisla_len):
    
    posloupnost = [ cisla[i] ]
    for j in range(i+1, cisla_len):
        posloupnost.append(cisla[j])
        if sum(posloupnost) == nevalidni_cislo:
            print(min(posloupnost) + max(posloupnost))
            quit()

10. den - adaptéry

První těšší úkol :D Máme pytlik nějakejch napájecích adaptérů který pasujou do sebe v řadě navzájem a maj každej definovanej nějakej výkon v joltech. Aty adaptéry mužou bejt do sebe zapojený akorát tak aby rozdíl výkonů každejch dvou různejch adaptérů byl max 3. v jednoduší první půlce musíme spočítat počet adaptérů mezi kterejma je rozdíl 1 jolt a 3 jolty, toje ještě snadný.

Jééénže v druhý půlce musíme najít počet všech možnejch kombinací jak různě de adaptéry v tý naši šňůrce uspořádat noa hrubou silou to podle autora mužou bejt až trillióny různejch kombinací :O :O

takže se na ty data musíme kouknout a zapřemejšlet se. Všimnem si že sou na nás hodný a ty data nejsou uplně náhodný a adaptéry v tý maximální možný šňůrce si mužem rozdělit do takovejch řekněme nudliček/clusterů ze kterýho když nějakej počet adaptérů vodendáme tak ten cluster furt bude umožňovat napojení jinýho clusteru adaptérů. tydlety clustetry naštěstí maj v našich vstupních datech ždycky max dýlku pěti adaptérů a podle počtu adaptérů mezi dvouma krajníma teda dovolujou max 2 4 nebo 7 kombinací usořádání. Tímdletím nasekáním nanudličky se nám to dost zjednoduší nato abysme to mohli spočítat :D ;D

jolty = []
for line in open('input').readlines():
    jolty.append(int(line))
    
jolty.append(max(jolty)+3)
jolty.append(0)
jolty = sorted(jolty)

print(jolty)

diff1 = 0
diff2 = 0
diff3 = 0

for i in range(1, len(jolty)):
    predchozi = jolty[i -1]
    tedko = jolty[i]
    diff = tedko - predchozi
    
    if diff == 1:
        diff1 += 1
    elif diff == 2:
        diff2 +=1
    elif diff == 3:
        diff3 += 1
    else:
        print('neco je spatne')
        
        
print(f'diff1 {diff1}, diff2 {diff2}, diff3 {diff3}')
print(f'nasobek: {diff1 * diff3}')


# část dva

def najdi_clustry(pole):
    clustry = []
    zacatek = 0
    konec = 0
    clus_data = []
    pole_len = len(pole)
    plnim_clus = False
    i = 1
    while i < pole_len - 1:
        diff_a = pole[i] - pole[i-1]
        diff_b = pole[i+1] - pole[i]
        if diff_a + diff_b <=3:
            if not plnim_clus:
                plnim_clus = True
                zacatek = pole[i-1]
                clus_data.append(zacatek)
            clus_data.append(pole[i])
        else:
            if plnim_clus:
                konec = pole[i]
                clus_data.append(konec)
                clustry.append(clus_data)
                clus_data = []
            plnim_clus = False
                

        i +=1
            
    return clustry


clustry = najdi_clustry(jolty)
print(clustry)
kombos = 1
for cluster in clustry:
    cl = len(cluster)-2
    if cl == 1:
        kombos *= 2
    elif cl ==2:
        kombos *= 4
    elif cl ==3:
        kombos *= 7
        
print(f'pocet kombinaci ruznejch: {kombos}')

11. den

varianta na game of life vod toho pana Conwaye co letos umřel hele. v druhý části židle nekoukaj na svý nejbliší sousedy ale koukaj jakoby v osmi základních směrech na nejvíc nejbliší jinou židli

pole = []
for line in open('input').readlines():
    radek_pole = []
    for ch in line:
        if ch in ['.','#','L']:
            radek_pole.append(ch)
        
    pole.append(radek_pole)
    
vyska_pole = len(pole)
sirka_pole = len(pole[0])

def in_bounds(x,y):
    return x>= 0 and x<=sirka_pole-1 and y>=0 and y<= vyska_pole-1

def kolik_obsazenych_okolo(x,y):
    kolik = 0
    
    if in_bounds(x-1,y-1):
        if pole[y-1][x-1] == '#':
            kolik += 1
            
    if in_bounds(x-1,y):
        if pole[y][x-1] == '#':
            kolik += 1
            
    if in_bounds(x-1,y+1):
        if pole[y+1][x-1] == '#':
            kolik += 1
            
    if in_bounds(x,y-1):
        if pole[y-1][x] == '#':
            kolik += 1
    if in_bounds(x,y+1):
        if pole[y+1][x] == '#':
            kolik += 1
            
    if in_bounds(x+1,y-1):
        if pole[y-1][x+1] == '#':
            kolik += 1
    if in_bounds(x+1,y):
        if pole[y][x+1] == '#':
            kolik += 1
    if in_bounds(x+1,y+1):
        if pole[y+1][x+1] == '#':
            kolik += 1
                
    return kolik

def kolik_znaku_v_poli(ch):
    kolik = 0
    for y in range(vyska_pole):
        for x in range(sirka_pole):
            if pole[y][x] == ch:
                kolik += 1
                
    return kolik

while True:
    nove_pole = []
    sedadlo_zmeneno = False
    for y in range(vyska_pole):
        novy_radek = []
        for x in range(sirka_pole):
            ch = pole[y][x]
            if ch != '.':
                kolik = kolik_obsazenych_okolo(x,y)
                if ch == 'L' and kolik == 0:
                    novy_radek.append('#')
                    sedadlo_zmeneno = True
                elif  ch == '#' and kolik >= 4:
                    novy_radek.append('L')
                    sedadlo_zmeneno = True
                else:
                    novy_radek.append(ch)
            
            else:
                novy_radek.append('.')
                
        nove_pole.append(novy_radek)

        
    if not sedadlo_zmeneno:
        print(kolik_znaku_v_poli('#'))
        break
    else:
        pole = nove_pole

část dva

pole = []
for line in open('input').readlines():
    radek_pole = []
    for ch in line:
        if ch in ['.','#','L']:
            radek_pole.append(ch)
        
    pole.append(radek_pole)
    
vyska_pole = len(pole)
sirka_pole = len(pole[0])

def in_bounds(x,y):
    return x>= 0 and x<=sirka_pole-1 and y>=0 and y<= vyska_pole-1

def kolik_obsazenych_okolo(x,y):
    kolik = 0
    
    for x_smer in range(-1,2):
        for y_smer in range(-1,2):
            #print((x_smer, y_smer))
            if x_smer==0 and y_smer==0:
                continue
            rel_x = x
            rel_y = y
            
            while True:
                rel_x += x_smer
                rel_y += y_smer
            
                if in_bounds(rel_x,rel_y):
                    ch = pole[rel_y][rel_x]
                    if ch == '#':
                        kolik += 1
                        break
                    elif ch == 'L':
                        break
                else:
                    break
                
    return kolik


def kolik_znaku_v_poli(ch):
    kolik = 0
    for y in range(vyska_pole):
        for x in range(sirka_pole):
            if pole[y][x] == ch:
                kolik += 1
                
    return kolik

while True:
    nove_pole = []
    sedadlo_zmeneno = False
    for y in range(vyska_pole):
        novy_radek = []
        for x in range(sirka_pole):
            ch = pole[y][x]
            if ch != '.':
                kolik = kolik_obsazenych_okolo(x,y)
                if ch == 'L' and kolik == 0:
                    novy_radek.append('#')
                    sedadlo_zmeneno = True
                elif  ch == '#' and kolik >= 5:
                    novy_radek.append('L')
                    sedadlo_zmeneno = True
                else:
                    novy_radek.append(ch)
            
            else:
                novy_radek.append('.')
                
        nove_pole.append(novy_radek)

        
    if not sedadlo_zmeneno:
        print(kolik_znaku_v_poli('#'))
        break
    else:
        pole = nove_pole

12. den

Takový ježdění lodičkou po 2d mapě. lechkej úkol.

část jedna

pozice_x = 0
pozice_y = 0
kam_kouka = 0

def dist(x,y):
    return abs(x)+abs(y)
        
def uhel_na_svetovou_stranu(uhel):
    while uhel<0:
        uhel+=360
    
    if uhel == 0:
        return 'E'
    elif uhel == 90:
        return 'N'
    elif uhel == 180:
        return 'W'
    else:
        return 'S'
            
def otoc_lod(uhel, smer):
    if uhel==0:
        return 0
    
    if smer=='L':
        return uhel
    else:
        return -uhel
    

for instrukce in open('input').readlines():
    
    co = instrukce[0]
    kolik = int(instrukce[1:])
    
    if co in ['E','N','W','S']:
        if co =='E':
            pozice_x += kolik
        elif co =='N':
            pozice_y += kolik
        elif co == 'W':
            pozice_x -= kolik
        else:
            pozice_y -= kolik
            
    elif co in ['L', 'R']:
        kam_kouka+=otoc_lod(kolik, co)
        
    elif co == 'F':
        
        kam = uhel_na_svetovou_stranu(kam_kouka)
        if kam =='E':
            pozice_x += kolik
        elif kam =='N':
            pozice_y += kolik
        elif kam == 'W':
            pozice_x -= kolik
        else:
            pozice_y -= kolik
            
print(f'x: {pozice_x} y: {pozice_y} dist: {dist(pozice_x, pozice_y)}')

část dva

lod_x = 0
lod_y = 0

waypoint_x = 10
waypoint_y = 1

def dist(x,y):
    return abs(x)+abs(y)
        
def uhel_na_svetovou_stranu(uhel):
    while uhel<0:
        uhel+=360
    
    if uhel == 0:
        return 'E'
    elif uhel == 90:
        return 'N'
    elif uhel == 180:
        return 'W'
    else:
        return 'S'
            
def otoc_waypoint(uhel, smer, orig_x, orig_y):
    if uhel==0:
        return 0
    
    waypoint_x = 0
    waypoint_y = 0
    
    if smer=='L':
        if uhel == 90:
            waypoint_y = orig_x
            waypoint_x = -orig_y
            
        if uhel == 180:
            waypoint_y = -orig_y
            waypoint_x = -orig_x
            
        if uhel == 270:
            waypoint_x = orig_y
            waypoint_y = -orig_x
            
    else:
        if uhel == 90:
            waypoint_y = -orig_x
            waypoint_x = orig_y
            
        if uhel == 180:
            waypoint_y = -orig_y
            waypoint_x = -orig_x
            
        if uhel == 270:
            waypoint_x = -orig_y
            waypoint_y = orig_x
            
    return waypoint_x, waypoint_y
    

for instrukce in open('input').readlines():
    
    co = instrukce[0]
    kolik = int(instrukce[1:])
    
    if co in ['E','N','W','S']:
        if co =='E':
            waypoint_x += kolik
        elif co =='N':
            waypoint_y += kolik
        elif co == 'W':
            waypoint_x -= kolik
        else:
            waypoint_y -= kolik
            
    elif co in ['L', 'R']:
        waypoint_x, waypoint_y = otoc_waypoint(kolik, co, waypoint_x, waypoint_y)
        
    elif co == 'F':
        
        lod_x += waypoint_x * kolik
        lod_y += waypoint_y * kolik
            
            
print(f'x: {lod_x} y: {lod_y} dist: {dist(lod_x, lod_y)}')

13. den - autobusy

Pro mě nejvíc nejzajímavější úkol z celýho tamtoho letošního kalendáře a stál mě nejvíc přemejšlení :D První půlka byla něco uplně jednoduchýho ale ta druhá jejejejejejejjej sem vod toho nejmíň třikrát vodešla než sem to vymyslela jak to jako řešit :O :O :D ;D máme jízdní řád nějakejch autobusů co furt pendlujou mezi letištěm a nějakejma jinejma místama a furt se za nějakou dobu vracej spátky na start, noa každýmu tomu autobusu to trvá zaprvý různě dlouho a zadruhý vodstartovali od toho letiště uplně nazačátku každej v jinej čas. noa našim úkolem je najít takovej čas (vodlišnej vod začátku ;D) kdy ty autobusy postupně přijedou k tomu letišti přesně v takovecj vzájemnejch časovejch rozestupech jako když vod toho letiště vodjížděli. Když třeba druhej autobus vystartoval vosum minut po prvním a třetí jedenáct minut po druhým tak hledáme další první výskyt tý samý situace kdy druhej autobus přijede k letišti 7 minut po tom prvním a třetí zase těch jedenác po druhým. zní to celkem snadně akorátže muj výslednej čas bylo nějaký uplně ulítlí šestnáctimístný číslo :O :O

Nejdřiv si to přemejšlení zjednodušíme tak že budem přemjšlet jenom nad uvedeným potkáváním jenom nějakejch dvou autobusů. Oběvování jednoho autobusu před letištěm si mužem popsat zorečkem x*c1 + c2 kde c1 je doba jakou autobusu dycky trvá udělat jeho kolečko a c2 jeho posun jak dlouho čekal uplně nazačátku.

pro druhej bude pdobně platit y*c3 + c4. Noa my si chceme ty dva autobusy jakoby sloučit do takovýho jednoho novýho pomyslnýho kterej bude jezdit v tom správným čase s tim správným časovým offsetem takže bude splňovat podmínky vobou autobusů :D

Doba vobjíždění bude nejvíc nejmenčí společnej násobek vobou časů vobjíždění. Takový zajímavý je že všecky ty časy za který se autobusy vracej z vobjížděk sou asi nějakou neuvěřitelnou náhodou prvočísla :D takže nejvíc nejmenčí společnej násobek bude bez nějakýho přemejšlení rovnou vobyč násobek.

Ještě ale jako musíme nějak zistit ten časovej offset toho novýho autobusu :O :O

Že když vod prvního autobusu vodečtem c2 tak musí bejt dělitelnej bezezbytku c1 je jasný. Aby se první autobus voběvoval i ve stejný době jako ten druhej tak po přidání časovýho offestu druhýho musí bejt taky současně dělitelnej bezezbytku c3, jakože tou dobou kterou to autobusu2 trvá všecko vobět. Dostanem matematickej zoreček s modulem

( (x*c1) + c2 +c4 ) % c3 == 0
kterej mužem modulární aritmetikou udělat víc jednoduší

x*c1 % c3 + (c2 + c4)%c3==0
x*c1 % c3 == (c2 + c4)%c3
x*c1 % c3 == c5

ze kterýho si už mužeme celkem snadno hrubou silou zistit x a jako bonus nebudem při hledání skákat vo jedničku ale vo c1 :O ;D offset uděláme tak že vezmem dobu vobjíždění autobusu (ten náš společnej nejvíc nejmenčí násobek) a vodečtem vod něj (x*c1)-c2. a takle si po dvou zjednušíme všecky ty autobusy noa ten hledanej čas bude offset posledního autobusu.

vo tom chybějícím mínusu vim ale s nim to ňák nefungovalo :D

část jedna

radky = open('input').readlines()
muj_cas = int(radky[0])
busy = []

for x in radky[1].strip().split(','):
    if x != 'x':
        busy.append(int(x))
        
min_bus = 99999999
min_zbytek = 999999999
for bus in busy:
    zbytek =bus - (muj_cas % bus)
    if zbytek < min_zbytek:
        min_bus = bus
        min_zbytek = zbytek
        
        
musim_cekat = min_zbytek

print(f'bus id: {min_bus} musim cekat: {muj_cas + min_zbytek} nasobek: {musim_cekat*min_bus}')

část dva

import math

radky = open('input').readlines()
muj_cas = int(radky[0])

busy = []
offset = 0
min_id = 9999999999
max_id = 0
for x in radky[1].strip().split(','):
    if x != 'x':
        busy.append((int(x), offset))
        
        if int(x) < min_id:
            min_id = int(x)
        if int(x) > max_id:
            max_id = int(x)
    
    offset += 1
        
print(busy)

def nej_spol_nas(bus1 ,bus2):
    nas = bus1[0]*bus2[0]
    
    c1 = bus1[0]
    c2 = bus1[1]
    c3 = bus2[0]
    c4 = bus2[1]
    x = 0

    # x *c1 + c2 == y * c3 + c4
    #x*c1 % c3 + (c2 + c4)%c3==0
    
    zbytek = (c2 + c4)%c3
    
    while True:
        x+=1
        if x*c1 % c3 == zbytek:
            print(x*c1-c2)
            return (nas,nas - (x*c1-c2))

bus_x = busy[0]
for bus in busy[1:]:
    bus_x = nej_spol_nas(bus_x, bus)
    print(bus_x)
    

print()
print(bus_x[1])

14. den

Dělání s binárníma číslama s tim že v druhý půlce máme kromě vobyč 01 bitů znak 'x' kterej muže bejt jednička i nula současně.

část jedna

maska = ['x'] * 36
vysledek = [0] * 36

adresy = {}

def cislo_to_bin(cislo):
    vysledek = [0] * 36
    i = 36
    while i >= 0:
        
        bit = 2**(i)
        
        if cislo>=bit:
            cislo-=bit
            vysledek[36-i-1] = 1
        else:
            vysledek[36-i-1] = 0
        
        i-=1
    return vysledek


def bin_to_dec(cislo):
    vratit = 0
    for i in range(36):
        vratit += 2**(36-i-1) * cislo[i]
        
    return vratit


def maskuj_cislo(cislo, maska, vysledek):
    
    for i in range(36):
        bit_maska = maska[i]
        
        if bit_maska == 'x':
            vysledek[i] = cislo[i]
        else:
            vysledek[i] = maska[i]
    
    return vysledek



for radek in open('input').readlines():
    
    instrukce, co = radek.split('=')
    
    if 'mask' in instrukce:
        for i in range(36):
            ch = co[i+1]
            print(f'ch: {ch}')
            if ch=='X':
                maska[i]='x'
            else:
                maska[i] = int(ch)
                
        print(f'maska: {maska}')
                
    elif 'mem' in instrukce:
        #cislo = int(co.split('[')[1].split(']')[0])
        adresa = int(instrukce.split('[')[1].split(']')[0])
        cislo = int(co)
        
        if not adresa in adresy:
            adresy[adresa]= [0] *36
        
        vysledek = maskuj_cislo(cislo_to_bin(cislo), maska, adresy[adresa])
        print(f'vysledek: {vysledek}\nvysledek_dec: {bin_to_dec(vysledek)}')
        adresy[adresa] = vysledek
        x = bin_to_dec(vysledek)
 

suma = 0
for hodnota in adresy.values():
    suma += bin_to_dec(hodnota)
print(f'suma: {suma}')

část dva

maska = ['x'] * 36
vysledek = [0] * 36

adresy = {}

def cislo_to_bin(cislo):
    vysledek = [0] * 36
    i = 36
    while i >= 0:
        
        bit = 2**(i)
        if cislo>=bit:
            cislo-=bit
            vysledek[36-i-1] = 1
        else:
            vysledek[36-i-1] = 0
        i-=1

    return vysledek


def increment_bin(cislo):
    
    for i in range(len(cislo)):
        index = len(cislo) - i -1
        if cislo[index] == 0:
            cislo[index] = 1
            break
        else:
            cislo[index] = 0
    return cislo


def maskuj_cislo(cislo, maska, vysledek):
    
    for i in range(36):
        bit_maska = maska[i]
        
        if bit_maska == 'x':
            vysledek[i] = 'x'
        elif bit_maska == 0:
            vysledek[i] = cislo[i]
        else:
            vysledek[i] = 1
    
    return vysledek


def ziskej_adresy(cislo):
    f_indexes = []
    zaklad = 0
    for i in range(36):
        if cislo[i]!='x':
            zaklad += 2**(36-i-1) * cislo[i]
        else:
            f_indexes.append(i)
    
    kolik_f = len(f_indexes)
    stav_f = [0] * kolik_f
    stav_f[-1]=1
    vratit = [zaklad]
    if kolik_f > 0:
        while 1 in stav_f:
            hodnota = zaklad

            for i in range(kolik_f):
                
                if stav_f[i]==1:
                    val = 2**(36-f_indexes[i]-1)
                    hodnota+=val
                    
            vratit.append(hodnota)
            stav_f = increment_bin(stav_f)
            
    return vratit



for radek in open('input').readlines():
    
    instrukce, co = radek.split('=')
    
    if 'mask' in instrukce:
        for i in range(36):
            ch = co[i+1]
            if ch=='X':
                maska[i]='x'
            else:
                maska[i] = int(ch)
                
        print(f'maska: {maska}')
                
    elif 'mem' in instrukce:
        adresa = int(instrukce.split('[')[1].split(']')[0])
        cislo = int(co)
        adr_bin = cislo_to_bin(adresa)
        maskovana_adr = maskuj_cislo(adr_bin, maska, [0] * 36)
        list_adres = ziskej_adresy(maskovana_adr)
        
        for a in list_adres:
            if not a in adresy:
                adresy[a]= [0] *36
        
            adresy[a] = cislo
 
suma = 0
for hodnota in adresy.values():
    suma += hodnota
print(f'suma: {suma}')
quit()

15. den - mluvicí hra

Nějaká taková mluvicí hra s elfama kdy hráči postupně řikaj čísla noa když řeknou číslo který ještě nikdo neřek tak pak další hráč musí říct nulu. pokavaď se číslo už řeklo tak hráč misto toho musí říct vzdálenost toho danýho čísla vod jeho předchozího výskytu v nějaký ty řadě čísel. V první půlce máme říct číslo na 2020tým místě v řadě noa to jetšě de celkem vpohodě dělat vobyč polem. v druhý půlce ale musíme říct číslo na nějaký třímiliontý pozici noa to jako nejde už to pole nějak normálně prohledávat a musíme si udělat dict() kde si budem pamatovat poslední pozice těch čísel.

Si jinak myslim žeto je jako dost pitomej způsob zábavy tadleta elfí hra toje lepší koukat z vokna :O :/

nums = [1,20,11,6,12]

orig_len = len(nums)
vzdalenosti = {}
predminule_vzdalenosti = {}

def pridej_do_vzdalenosti(co, vzdalenost):
    if co in vzdalenosti.keys():
        predminule_vzdalenosti[co] = vzdalenosti[co]
    vzdalenosti[co] = vzdalenost
    
for i in range(len(nums)):
    vzdalenosti[nums[i]] = i

i=5
minule = 0
cislo = 0

while i < 30000000:
        if i % 100000==0:
            print(f'hotovo {(i/(30000000))*100.0}%')

        if minule not in vzdalenosti.keys():
            vzdalenosti[minule] = i
          
            if not 0 in vzdalenosti.keys():
                pridej_do_vzdalenosti(0,i+1)
                i+=1
                
            pridej_do_vzdalenosti(0,i+1)
            
            i+=1
            minule = 0
            predminule = minule

        else:
            
            nove = vzdalenosti[minule] - predminule_vzdalenosti[minule]
            if nove not in vzdalenosti.keys():
                minule = nove
                continue
            pridej_do_vzdalenosti(nove,i)
            minule = nove
            
            cislo = minule

        i+=1

print(f'cislo: {cislo}')

16. den

Nějaký validování jízdenek kde máme na vstupu různý parametry tý jízdenky jakože třídu, řadu nebo sedadlo u nich u každý stanovený dva intervali ve kterejch ta hodnota jakoby muže bejt. Noa pak seznam čísel napsanejch v sloupečcích kde každej ten sloupeček vodpovídá některýmu z těch parametrů jizdenky. noa my musíme zistit který číslo vodpovídá který tý kategorii/parametru ;D

protože tušíme že je na nás pan autor na vánoce hodnej :D tak budem předpokládat že toje dycky řešitelný noa aby to bylo řešitelný tak musí v každým kroku existovat právě jeden parametr tý jízdenky ke kterýmu bude štymovat právě jeden sloupeček těch hodnot. A když ho určíme a škrtnem vod vostatních u kterejch ještě na 100% nevíme tak zase jako musí existovat další jedinej sloupeček a jediná kategorie který k sobě štymujou. takle si je jako mužem postupně všecky určit ajeto jako :D ;D

radky = open('input').readlines()

classes = []
muj = []
ostatni = []

plnim_classes = True
plnim_svuj = False
plnim_ostatni = False

for radek in radky:
    if radek == '\n':
        if plnim_classes:
            plnim_classes = False
            plnim_svuj = True
        else:
            plnim_svuj = False
            plnim_ostatni = True
        
        continue
    
    if plnim_classes:
        nazev, tmp = radek.split(':')
        tmp = tmp.split('or')
        
        interval1 = (int(tmp[0].split('-')[0]), int(tmp[0].split('-')[1]))
        interval2 = (int(tmp[1].split('-')[0]), int(tmp[1].split('-')[1]))
        
        classes.append((nazev, interval1, interval2))
        
    if plnim_svuj:
        if ':' in radek:
            continue
        for x in radek.split(','):
            muj.append(int(x))
            
    if plnim_ostatni:
        if ':' in radek:
            continue
        
        novy = []
        for x in radek.split(','):
            novy.append(int(x))
            
        ostatni.append(novy)

#validace

ostatni_valid = []

def in_interval(interval, x):
    return x >= interval[0] and x<= interval[1]

chybne = 0
for ticket in ostatni:
    
    cely_valid = True
    for x in ticket:
        validni = False
        for trida in classes:
            interval1 = trida[1]
            interval2 = trida[2]
            
            if in_interval(interval1, x) or in_interval(interval2, x):
                validni = True
                break
            
        
        if not validni:
            chybne += x
            cely_valid = False
            
    if cely_valid:
        ostatni_valid.append(ticket)
            
print(chybne)


# část dva
# najdu min/max rosahy jednotlivejch tříd

delka_radku = len(muj)
mins = [99999999999] * delka_radku
maxs = [-1] * delka_radku
for radek in ostatni_valid:
    for i in range(delka_radku):
        x = radek[i]
        if x < mins[i]:
            mins[i] = x
            
        if x > maxs[i]:
            maxs[i] = x

# přiřadim ke každýmu intervalu možný třídy
            
seznam = []

for i in range(delka_radku):
    
    mozne_tridy = []
    for trida in classes:
        interval1 = trida[1]
        interval2 = trida[2]
        
        
        muzu_pridat = True
        for radek in ostatni_valid:
            val = radek[i]
            if not in_interval(interval1, val) and not in_interval(interval2, val):
                muzu_pridat = False
                break
            
        if muzu_pridat:
            mozne_tridy.append(trida)
    seznam.append((i, mozne_tridy))
    
sparovane = []

while len(seznam)>0:
    for polozka in seznam:
        
        tridy = polozka[1]
        if len(tridy) == 1:
            sparovane.append(polozka)
            trida = tridy[0]
            seznam.remove(polozka)
            for polozka in seznam:
                polozka[1].remove(trida)
            continue
        
print()
print('sparovane: ')
for x in sparovane:
    print(x)
    
    
print()
print('departude:')
indexes = []
for x in sparovane:
    if 'departure' in x[1][0][0]:
        print(x)
        indexes.append(x[0])
        
val = 1

for i in indexes:
    val *=muj[i]
    
print(val)

17. den

Další úkol s game of life akorátže v první půlce 3d a v druhý půlce ve 4d hyperkostky :O :O na první pohled to vypadá strašidelně ale stačí tam prostě uplně slepě přidat jeden rozměr navíc ajeto :D

v obou půlkách máme nazačátku v zadání jenom jakoby jednu jedinou 3d vrstvu těch kostek a ta se nám děsně rozroste. noa protože víme že nám to poroste uplně stejně symetricky dolu jak nahoru tak nám stačí nasimulovat jenom jeden směr a ten výslednej počet co po nás jako chtěj vynásobit dvouma + počet kostek v první vrstvě :O ;D

dimenze = {}
sirky_dimenzi = {}
min_z = 0
max_z = 0

new_dim = {}

y = 0

def kolik_sousedu(x,y,z,aktualni_vrstva, vrstva_nad, vrstva_pod):
    
    kolik = 0
    for _x in [-1,0,1]:
        for _y in [-1,0,1]:
            for _z in [-1,0,1]:
                if _x==0 and _y ==0 and _z==0:
                    continue
                if aktualni_vrstva.in_range(_x+x, _y+y, _z+z):
                    if aktualni_vrstva.data[(_x+x,_y+y, _z+z)] == True:
                        kolik += 1
    if vrstva_nad is not None:
        for _x in [-1,0,1]:
            for _y in [-1,0,1]:
                for _z in [-1,0,1]:
                    if vrstva_nad.in_range(_x+x, _y+y, _z+z):
                        if vrstva_nad.data[(_x+x,_y+y,_z+z)] == True:
                            kolik += 1
    if vrstva_pod is not None:
        for _x in [-1,0,1]:
            for _y in [-1,0,1]:
                for _z in [-1,0,1]:
                    if vrstva_pod.in_range(_x+x, _y+y, _z+z):
                        if vrstva_pod.data[(_x+x,_y+y,_z+z)] == True:
                            kolik += 1
    return kolik


class Vrstva:
    
    def __init__(self,min_x,min_y,max_x,max_y,min_z,max_z):
        
        self.data = {}
        
        self.min_x = min_x
        self.min_y = min_y
        self.max_x = max_x
        self.max_y = max_y
        
        self.min_z = min_z
        self.max_z = max_z
        
        for y in range(min_y,max_y+1):
            for x in range(min_x,max_x+1):
                for z in range(min_z,max_z+1):
                    self.data[(x,y,z)] = False
                
    def in_range(self,x,y,z):
        
        if x >= self.min_x and x< self.max_x:
            if y >= self.min_y and y< self.max_y:
                if z >= self.min_z and z< self.max_z:
                    return True
            
        return False
                
    def expanduj(self):
        self.min_x -=1
        self.min_y -=1
        self.min_z -=1
        self.max_x +=1
        self.max_y +=1
        self.max_z +=1
        
        
        for x in range(self.min_x, self.max_x +1):
            for y in range(self.min_y, self.max_y +1):
                self.data[(x,y,self.min_z)] = False
                self.data[(x,y,self.max_z)] = False
                
        for x in range(self.min_x, self.max_x +1):
            for z in range(self.min_z, self.max_z +1):
                self.data[(x,self.min_y,z)] = False
                self.data[(x,self.max_y,z)] = False
                
        for y in range(self.min_y, self.max_y +1):
            for z in range(self.min_z, self.max_z +1):
                self.data[(self.min_x,y,z)] = False
                self.data[(self.max_x,y,z)] = False
        
            
    # předpokládaj se stejný rozměry
    def vyrob_aktualizovanou(self,nad,pod):
        nova = Vrstva(self.min_x, self.min_y, self.max_x, self.max_y,self.min_z,self.max_z)
        
        for x in range(self.min_x, self.max_x+1):
            for y in range(self.min_y, self.max_y+1):
                for z in range(self.min_z, self.max_z+1):
                    
                    zapsat =self.data[(x,y,z)]
                    aktivnich_sousedu = kolik_sousedu(x,y,z,self,nad,pod)
                    
                    if zapsat == True:
                        if aktivnich_sousedu==2 or aktivnich_sousedu==3:
                            zapsat = True
                        else:
                            zapsat = False
                    else:
                        if aktivnich_sousedu==3:
                            zapsat = True
                    
                    nova.data[(x,y,z)] = zapsat
                
        return nova
            
    def kolik_aktivnich(self):
        kolik = 0
        for y in range(self.min_y, self.max_y+1):
            for x in range(self.min_x, self.max_x+1):
                for z in range(self.min_z, self.max_z+1):
                    if self.data[(x,y,z)]:
                        kolik +=1
                    
        return kolik

#vrstva = Vrstva(0,0,3,3,0,0)
vrstva = Vrstva(0,0,8,8,0,0)

for radek in open('input').readlines():
    x = 0
    for ch in radek.strip():
        if ch == '#':
            vrstva.data[(x,y,0)] = True
        else:
            vrstva.data[(x,y,0)] = False
        x+=1
    y+=1
    

vrstvy = [vrstva]                        
for c in range(3+3):
    print(f'c: {c}')
    
    vrstvy.append(Vrstva(vrstvy[-1].min_x,vrstvy[-1].min_y,vrstvy[-1].max_x,vrstvy[-1].max_y,vrstvy[-1].min_z,vrstvy[-1].max_z))
    
    for vrstva in vrstvy:
        vrstva.expanduj()
        
    nove_vrstvy = []
    
    nove_vrstvy.append(vrstvy[0].vyrob_aktualizovanou(vrstvy[1],vrstvy[1]))
    for i in range(1,len(vrstvy)-1):
        nove_vrstvy.append(vrstvy[i].vyrob_aktualizovanou(vrstvy[i+1], vrstvy[i-1]))
        
    nove_vrstvy.append(vrstvy[-1].vyrob_aktualizovanou(None, vrstvy[-2]))
        
    vrstvy = nove_vrstvy
    
kolik = 0
for v in vrstvy[1:]:
    kolik += v.kolik_aktivnich()
    
print(kolik*2)
kolik = vrstvy[0].kolik_aktivnich() + kolik *2
print(kolik)

18. den

Počítání nějakej divnejch matematickejch příkladů kde matika funguje uplně jinak třeba plusy maj věčí prioritu v dělání operací než násobení a tak. Si jakoby musíme ty stringy rosparsovat a udělat ty operace s těma číslama. Zase snadnej úkol

import re

# spočítá řetězec bez závorek
def vypocitat_string(retezec):
    retezec = retezec.strip().replace(' ','')
    
    cisla = re.split('[*+]',retezec)
    operace = re.split('\d+',retezec)[1:-1]
    
    vysledek = int(cisla[0])
    
    for i in range(1,len(cisla)):
        o = operace[i-1]
        if o == '*':
            vysledek*=int(cisla[i])
        else:
            vysledek+=int(cisla[i])
            
    return vysledek

# spočítá řetězec bez závorek - část dva
def vypocitat_string2(retezec):
    retezec = retezec.strip().replace(' ','')
    print(f'vstup: {retezec}')
    cisla = re.split('[*+]',retezec)
    operace = re.split('\d+',retezec)[1:-1]
    
    vysledek = int(cisla[0])
    
    while '+' in operace:
        for i in range(len(operace)):
            if operace[i]=='+':
                print(cisla)
                nove_cislo = int(cisla[i]) + int(cisla[i+1])
                del operace[i]
                del cisla[i]
                cisla[i] = str(nove_cislo)
                print(cisla)
                break
                
    suma = int(cisla[0])
    for x in cisla[1:]:
        suma*=int(x)
            
    return suma


def nahradit_spodni_zavorky(retezec):
    
    start_index = -1
    
    for i in range(len(retezec)):
        
        ch = retezec[i]
        if ch =='(':
            start_index = i
            mam = ''
        elif ch==')':
            konec_index = i
            obsah_zavorek = retezec[1+start_index:konec_index]
            vysledek = vypocitat_string2(obsah_zavorek)
            novy_str = retezec[:start_index] + str(vysledek) + retezec[konec_index+1:]
            return True, novy_str
        
    return False,None
        
suma = 0
for radek in open('input').readlines():
    print(radek)
    while True:
        nalezeno, rtzc = nahradit_spodni_zavorky(radek)
        if not nalezeno:
            break
        else:
            radek = rtzc
            
    vysledek = vypocitat_string2(radek)
    print(f'vysledek: {vysledek}')
    suma +=vysledek
    
print(f'suma: {suma}')

19. den - satelit

se to teda asi jako mělo dělat převedením na strom ale jak sem tam v tom zadání viděla ty znáčky unixový trubičky jakože znak | kterejma se v regexpech dělá or tak sem to vzala jako takovou tajnou nápovědu a vygenerovala nejvíc nejvěčí regexp svýho života :O :O :D :D

v druhý půlce se musej upravit zadaný pravidla takže nám tam vznikne nekonečná smyčka protože nově pravidlo muže v sobě mit nula až nekonečno vopakování sebe samotnýho :O :O jenže jak sem jako koukala na ty stringy ve vstupních datech semi zase jako nezdály tak děsně dlouhý nóó tak sem riskla že se každá ta smyčka rekurzivně zvopákne max desetkrát a vyšlo mi to :D

btw ty regexpy by asi jako šlo napsat líp ale učel to splnilo. popravdě sem čekala žese to 'zadře' a budu to muset udělat celý znova vodzačátku uplně jinak ale vono ne :O :O :D :D

import re

overit = []
instrukce = {}
uz_pulka = False
a_index = 0
b_index = 0
max_index = 0
for radek in open('input2').readlines():
    
    if radek == '\n':
        uz_pulka = True
        continue
    
    if uz_pulka:
        overit.append(radek.strip())
        
    else:
        index, zbytek = radek.split(':')
        index = int(index)
        
        if index > max_index:
            max_index = index
        
        if 'a' in zbytek:
            a_index = index
        elif 'b' in zbytek:
            b_index = index
        else:
            if '|' not in zbytek:
                instrukce[index] = '('+zbytek.strip()+')'
            else:
                p1, p2 = zbytek.split('|')
                instrukce[index] = '(('+p1.strip()+')|('+p2.strip()+'))'
            
            
prevedene = {}
prevedene[a_index] = 'a'
prevedene[b_index] = 'b'


while len(instrukce) > 3:
    
    for i in range(10):
        for index in instrukce:
            if index in instrukce.keys():
                ins = instrukce[index]
                cisla = re.findall('\\d+',ins)
                if len(cisla)<1:
                    prevedene[index] = ins 
                    print(f'{index}: {prevedene[index]}')
                    del instrukce[index]
                    print(f'zbyva: {len(instrukce)}')
                    
                    break
                for cislo in cisla:
                    cislo = int(cislo)
                    if cislo in prevedene.keys():
                        ins = re.sub('\\b'+str(cislo)+'\\b', prevedene[cislo], ins)
                        
                instrukce[index] = ins

regexpy_8 = []
regexpy_11 = []
num = 10
for i in range(num):
    ins = instrukce[8]
    for j in range(i):
        ins = ins.replace('8',instrukce[8])
    ins.replace('8','')
    regexpy_8.append(ins.replace(' ',''))
    
for i in range(num):
    ins = instrukce[11]
    for j in range(i):
        ins = ins.replace('11',instrukce[11])
    ins.replace('11','')
    regexpy_11.append(ins.replace(' ',''))


def je_validni(radek):
    
    for reg8 in regexpy_8:
        for reg11 in regexpy_11:
            exp = '\\b' + reg8 + reg11 + '\\b'
            if re.match(exp, radek) is not None:
                return True
            
    return False

suma_valid = 0
for radek in overit:
    if je_validni(radek):
        print(f'{radek} je validni')
        suma_valid += 1
    else:
        print(f'{radek} neni validni')
        
print(f'kolik validnich: {suma_valid}')

20. den

na vstupu máme jednobarevnej vobrázek jakoby celej nakrájenej na stejně velký čtverečky a ty čtverečky sou navíc různe překlopený nebo natočený. ale víme že každá ta hrana toho vobrázku muže vždycky navazovat na nějakej jinej vobrázek nebože na žádnej když je krajní. vprvní půlce úkolu sme museli zistit který vobrázky sou rohový jakože maj právě jenom dva nějaký sousedy. v druhý půlce se ten vobrázek musí správně sestavit a musíme v něm najít všecky lochnesky :D

class Tile:
    
    def __init__(self,radky,idd):
        
        self.idd = idd
        self.pixely = [[0 for x in range(10)] for y in range(10)] #yx
        
        for x in range(10):
            for y in range(10):
                ch = radky[y][x]
                self.pixely[y][x] = ch
        
        self.okrajL = []
        self.okrajR = []
        self.okrajU = []
        self.okrajD = []
        
        self.sousedu = 0
        self.moznych_sousedu = 0
        
        # okraje
        
        self.okrajU = radky[0]
        self.okrajD = radky[-1]
        
        for y in range(10):
            self.okrajL.append(radky[y][0])
            self.okrajR.append(radky[y][-1])
            
            
    def match_right(self,druhej):
        for i in range(10):
            if self.okrajR[i] != druhej.okrajL[i]:
                return False
        return True
    
    def match_left(self,druhej):
        for i in range(10):
            if self.okrajL[i] != druhej.okrajR[i]:
                return False
        return True
    
    def match_down(self,druhej):
        for i in range(10):
            if self.okrajD[i] != druhej.okrajU[i]:
                return False
        return True
    
    def match_up(self,druhej):
        for i in range(10):
            if self.okrajU[i] != druhej.okrajD[i]:
                return False
        return True
    
    # ve směru hodinek
    def rotate90(self):
        tmp = self.okrajR
        self.okrajR = self.okrajU
        self.okrajU = self.okrajL
        self.okrajL = self.okrajD
        self.okrajD = tmp
        
        self.okrajD = self.okrajD[::-1]
        self.okrajU = self.okrajU[::-1]
        
        nove_pixely = [[0 for x in range(10)] for y in range(10)] #yx
        
        for x in range(10):
            for y in range(10):
                nove_pixely[x][9-y] = self.pixely[y][x]
                
        self.pixely = nove_pixely
    
    def flip_y(self):
        tmp = self.okrajU
        self.okrajU = self.okrajD
        self.okrajD = tmp
        self.okrajL = self.okrajL[::-1]
        self.okrajR = self.okrajR[::-1]
        
        nove_pixely = [[0 for x in range(10)] for y in range(10)] #yx
        
        for x in range(10):
            for y in range(10):
                nove_pixely[y][x] = self.pixely[9-y][x]
                
        self.pixely = nove_pixely
        
    def any_matches_num(self,druhej):
        suma = 0
        match_l = True
        match_l_rev = True
        match_u = True
        match_u_rev = True
        match_d = True
        match_d_rev = True
        match_r = True
        match_r_rev = True
        
        for okraj in [self.okrajD, self.okrajL, self.okrajR,self.okrajU]:
        
            for i in range(10):
                if okraj[i] != druhej.okrajD[i]:
                    match_up = False
                if okraj[i] != druhej.okrajD[9-i]:
                    match_up_rev = False
                
            for i in range(10):
                if okraj[i] != druhej.okrajR[i]:
                    match_r = False
                if okraj[i] != druhej.okrajR[9-i]:
                    match_r_rev = False
                
            for i in range(10):
                if okraj[i] != druhej.okrajU[i]:
                    match_d = False
                if okraj[i] != druhej.okrajU[9-i]:
                    match_d_rev = False
                    
            for i in range(10):
                if okraj[i] != druhej.okrajL[i]:
                    match_l = False
                if okraj[i] != druhej.okrajL[9-i]:
                    match_l_rev = False
                    
                if match_u or match_u_rev:
                    suma += 1
                if match_r or match_r_rev:
                    suma += 1
                if match_d or match_d_rev:
                    suma += 1
                if match_l or match_l_rev:
                    suma += 1
            
        return suma
    
    def ma_okraj(self,okraj):
        suma = 0
        match_l = True
        match_l_rev = True
        match_u = True
        match_u_rev = True
        match_d = True
        match_d_rev = True
        match_r = True
        match_r_rev = True
        
        
        for i in range(10):
            if okraj[i] != self.okrajD[i]:
                match_u = False
            if okraj[i] != self.okrajD[9-i]:
                match_u_rev = False
                
        for i in range(10):
            if okraj[i] != self.okrajR[i]:
                match_r = False
            if okraj[i] != self.okrajR[9-i]:
                match_r_rev = False
                
        for i in range(10):
            if okraj[i] != self.okrajU[i]:
                match_d = False
            if okraj[i] != self.okrajU[9-i]:
                match_d_rev = False
                    
        for i in range(10):
            if okraj[i] != self.okrajL[i]:
                match_l = False
            if okraj[i] != self.okrajL[9-i]:
                match_l_rev = False
                    
        if match_u or match_u_rev:
            suma += 1
        if match_r or match_r_rev:
            suma += 1
        if match_d or match_d_rev:
            suma += 1
        if match_l or match_l_rev:
            suma += 1
            
        return suma > 0
        
                
    def __str__(self):
        text = f'idd: {idd}\n'
        for y in range(10):
            for x  in range(10):
                text += self.pixely[y][x] + ' '
            text += '\n'
            
        text+='\n'
        text+=f'okrajU: {self.okrajU}\n'
        text+=f'okrajR: {self.okrajR}\n'
        text+=f'okrajD: {self.okrajD}\n'
        text+=f'okrajL: {self.okrajL}\n'
            
        return text
    
    
radky = open('input')

dlazdice = {}

radky_dl = []
idd = 0

for radek in radky:
    radek = radek.strip()
    
    if 'Tile' in radek:
        idd = int(radek.split(' ')[1][:-1])
        print(idd)
        radky_dl = []
        for i in range(10):
            radky_dl.append(next(radky).strip())

        dlazdice[idd]=Tile(radky_dl, idd)


mul = 1
rohovy = None
for idd in dlazdice:
    dlaz1 = dlazdice[idd]
    mam_u = False
    mam_r = False
    mam_d = False
    mam_l = False
    for idd2 in dlazdice:
        if idd != idd2:
            dlaz2 = dlazdice[idd2]
            
            if dlaz2.ma_okraj(dlaz1.okrajU):
                mam_u = True
            if dlaz2.ma_okraj(dlaz1.okrajR):
                mam_r = True
            if dlaz2.ma_okraj(dlaz1.okrajL):
                mam_l = True
            if dlaz2.ma_okraj(dlaz1.okrajD):
                mam_d = True
    kolik = mam_u+mam_r+mam_d+mam_l
    
    if kolik == 2:
        print('mam rohovej')
        mul *= idd
        
        if not mam_l and not mam_u:
            rohovy = dlaz1
        if not mam_u and not mam_r:
            rohovy = dlaz1
            for i in range(3):
                rohovy.rotate90()
        if not mam_r and not mam_d:
            rohovy = dlaz1
            for i in range(2):
                rohovy.rotate90()
        if not mam_d and not mam_l:
            rohovy = dlaz1
            rohovy.rotate90()
        
print(mul)
print(rohovy)
print(f'dlazdic: {len(dlazdice)}')
width = 12
height = 12

mapa = {}
mapa[(0,0)] = rohovy

def vypisMapu():
    for y in range(width):
        for x in range(height):
            if mapa[(x,y)] is not None:
                print(f'{mapa[(x,y)].idd} ',end='')
            else:
                print('x ',end='')
        print()
        print()

for y in range(height):
    for x in range(width):
        vypisMapu
        if y==0 and x==0:
            continue
        
        if x==0:
            predchozi = mapa[(x,y-1)]
            pristi = None
            d = None
            
            for idd in dlazdice:
                d = dlazdice[idd]
                if predchozi.match_down(d):
                    pristi = d
                    break
                for i in range(4):
                    d.rotate90()
                    if predchozi.match_down(d):
                        pristi = d
                        break
                    d.flip_y()
                    if predchozi.match_down(d):
                        pristi = d
                        break
                    d.flip_y()
                
                if pristi is not None:
                    break
                
            mapa[(x,y)] = pristi
            print(pristi)
            
        else:
            predchozi = mapa[(x-1,y)]
            pristi = None
            
            for idd in dlazdice:
                d = dlazdice[idd]
                if predchozi.match_right(d):
                    pristi = d
                    break
                for i in range(4):
                    d.rotate90()
                    if predchozi.match_right(d):
                        pristi = d
                        break
                    d.flip_y()
                    if predchozi.match_right(d):
                        pristi = d
                        break
                    d.flip_y()
                
                if pristi is not None:
                    break
                
            mapa[(x,y)] = pristi
            
        print(pristi)


for y in range(width):
    for x in range(height):
        print(f'{mapa[(x,y)].idd} ',end='')
    print()

obrazek = [[None for x in range(width*8)] for y in range(height*8)]

for y_tile in range(height):
    for x_tile in range(width):
        d = mapa[(x_tile,y_tile)]
        for y in range(1,9):
            for x in range(1,9):
                obrazek[y-1+8*y_tile][x-1+8*x_tile] = d.pixely[y][x]

delka_monstra = 20
vyska_monstra = 3
def is_sea_monster(x,y):
    
    if x + delka_monstra >=len(obrazek[0]):
        return False
    if y + vyska_monstra >=len(obrazek):
        return False
    
    if not obrazek[y][x+18] =='#':
        return False
    if not (obrazek[y+1][x]=='#' and obrazek[y+1][x+5]=='#' and obrazek[y+1][x+6]=='#'):
        return False
    if not (obrazek[y+1][x+11]=='#' and obrazek[y+1][x+12]=='#'):
        return False
    
    if not (obrazek[y+1][x+17]=='#' and obrazek[y+1][x+18]=='#' and obrazek[y+1][x+19]=='#'):
        return False
    
    if not (obrazek[y+2][x+1]=='#' and obrazek[y+2][x+4]=='#' and obrazek[y+2][x+7]=='#'):
        return False
    
    if not (obrazek[y+2][x+10]=='#' and obrazek[y+2][x+13]=='#' and obrazek[y+2][x+16]=='#'):
        return False
    
    return True
    
def rotate90(obrazek,sirka,vyska):
    nove_pixely = [[0 for x in range(sirka)] for y in range(vyska)] #yx
    for x in range(sirka):
        for y in range(vyska):
            nove_pixely[x][(vyska - 1)-y] = obrazek[y][x]
                
    return nove_pixely
    
def flip_y(obrazek,sirka,vyska):
    nove_pixely = [[0 for x in range(sirka)] for y in range(vyska)] #yx
    for x in range(sirka):
        for y in range(vyska):
            nove_pixely[y][x] = obrazek[(vyska-1)-y][x]
    return nove_pixely

    
max_pocet = 0

for i in range(4):
    pocet_monster = 0
    for y in range(height*8):
        for x in range(width*8):
            if is_sea_monster(x,y):
                pocet_monster += 1
    if pocet_monster > max_pocet:
        max_pocet = pocet_monster
    pocet_monster = 0
    obrazek = rotate90(obrazek,width*8,height*8)
    for y in range(height*8):
        for x in range(width*8):
            if is_sea_monster(x,y):
                pocet_monster += 1
                
    if pocet_monster > max_pocet:
        max_pocet = pocet_monster
    pocet_monster = 0
    obrazek = flip_y(obrazek,width*8,height*8)
    for y in range(height*8):
        for x in range(width*8):
            if is_sea_monster(x,y):
                pocet_monster += 1
    obrazek = flip_y(obrazek,width*8,height*8)
    if pocet_monster > max_pocet:
        max_pocet = pocet_monster
                

print(f'pocet monster: {max_pocet}')

krizku = 0
for y in range(height*8):
    for x in range(width*8):
        if obrazek[y][x] == '#':
            krizku+=1
            
print(f'krizku: {krizku}')
print(f'krizku bez monster: {krizku - (max_pocet * 15)}')

21. den - alergeny

na vstupu máme řádky kde v první půlce řádků je seznam ingrediencí nějakýho receptu na jídlo a v druhý půlce řádků seznam možnejch alergenů který to jídlo vobsahuje, akorátže u těch receptů nejsou napsaný všechny ty alergeny který v těch jídlech mužou bejt. víme že každej jeden alergen je ždycky právě jenom v jedný ty přísadě.

zase to de vyřešit čarováním s množinamama a jejich průnikamama.

potraviny = []
seznam_alergenu = set()
seznam_slozek = set()

for radek in open('input').readlines():
    
    slozky_s, alergeny_s = radek.strip().split('(contains')
    
    slozky = []
    alergeny = []
    
    for slozka in slozky_s.strip().split(' '):
        slozky.append(slozka.strip())
        seznam_slozek.add(slozka.strip())
    for alergen in alergeny_s.strip()[:-1].replace(',','').split(' '):
        alergeny.append(alergen.strip())
        seznam_alergenu.add(alergen.strip())
        
    potravina = [slozky, alergeny]
    print(potravina)
    
    potraviny.append(potravina)

print()


def zda_maji_stejny_alergen(pot1,pot2):
    for alergen in pot2[1]:
        if alergen in pot1[1]:
            return True
    return False

                        
seznam_pruniku = {}
for alergen in seznam_alergenu:
    print(f'alergen: {alergen}')
    mnoziny = []
    for potravina in potraviny:
        if alergen in potravina[1]:
            mnoziny.append(potravina[0])
            
    print(mnoziny)
    
    # dělání průniku
    m = mnoziny[0]
    for mnozina in mnoziny[1:]:
        m = list(set(m) & set(mnozina))
        
    print(f'prunik: {m}')
    seznam_pruniku[alergen] = m
    print()
            
       
# který alergeny maj jedinou přísadu
vyresene = {}
       
for a in seznam_alergenu:
    if len(seznam_pruniku[a]) == 1:
        vyresene[a] = seznam_pruniku[a][0]
        del seznam_pruniku[a]

print(vyresene)
print(seznam_pruniku)


mam = True
while mam:
    mam = False
    
    for prunik_id in seznam_pruniku:
        if mam:
            break
        prunik = seznam_pruniku[prunik_id]
        for a in vyresene:
            a_polozka = vyresene[a]
            if a_polozka in prunik:
                prunik.remove(a_polozka)
            if len(prunik) == 1:
                vyresene[prunik_id] = prunik[0]
                del seznam_pruniku[prunik_id]
                mam =True
                break
        if mam:
            break
                
    
print(vyresene)
print(seznam_pruniku)
    
for v in vyresene:
    s = vyresene[v]
    if s in seznam_slozek:
        seznam_slozek.remove(s)
        
nemuze_mit = 0
for potravina in potraviny:
    for s in potravina[0]:
        if s in seznam_slozek:
            nemuze_mit += 1
            
print(f'vyskytu: {nemuze_mit}')

# část dva

def alergen_comp(x,y):
    _x = None
    _y = None
    for a in vyresene:
        ah = vyresene[a]
        if x==ah:
            _x = ah
        if y==ah:
            _y = ah
            
    if _x == _y:
        return 0
    elif _x < _y:
        return -1
    else:
        return 1

hodnoty = []
for k in vyresene.keys():
    hodnoty.append((vyresene[k],k))
hodnoty.sort(key=lambda h: h[1])
print(hodnoty)
print()

for h in hodnoty[:-1]:
    print(f'{h[0]},',end='')
print(hodnoty[-1][0])
    

22. den

simulace průběhu nějaký takový karetní hry s krabem.

část jedna

balik1 = []
balik2 = []
plnim_prvni = True

for radek in open('input').readlines()[1:]:
    
    if radek == '\n' or 'Playe' in radek:
        plnim_prvni = False
        continue
    
    radek = radek.strip()
    if plnim_prvni:
        balik1.append(int(radek))
    else:
        balik2.append(int(radek))
        
print(balik1)
print(balik2)

while len(balik1)>0 and len(balik2)>0:
    
    karta1 = balik1.pop(0)
    karta2 = balik2.pop(0)
    
    if karta1 > karta2:
        balik1.append(karta1)
        balik1.append(karta2)
    else:
        balik2.append(karta2)
        balik2.append(karta1)

print(balik1)
print(balik2)

winner = balik1 if len(balik1)>0 else balik2

vysledek = 0

for i in range(len(winner)):
    vysledek += winner[len(winner)-1-i]*(i+1)
    
print(vysledek)

část dva

import copy

balik1 = []
balik2 = []

plnim_prvni = True

for radek in open('test').readlines()[1:]:
    
    if radek == '\n' or 'Playe' in radek:
        plnim_prvni = False
        continue
    
    radek = radek.strip()
    if plnim_prvni:
        balik1.append(int(radek))
    else:
        balik2.append(int(radek))
        
print(balik1)
print(balik2)

def subgame(balik1,balik2,rekurze):
    kolo = 0
    #print()
    #print(f'=== Game {rekurze} ===')
    permutace1 = []
    permutace2 = []
    while len(balik1)>0 and len(balik2)>0:
        
        if balik1 in permutace1 or balik2 in permutace2:
            print(permutace1)
            print(permutace2)
            print('perm')
            return 1,balik1
        else:
            permutace1.append(copy.deepcopy(balik1))
            permutace2.append(copy.deepcopy(balik2))
        
        kolo += 1
        #print()
        #print(f'-- Round {kolo} (Game {rekurze}) --')
        #print(f'Hrac1 balik: {balik1}')
        #print(f'Hrac2 balik: {balik2}')
        karta1 = balik1.pop(0)
        karta2 = balik2.pop(0)
        #print(f'Hrac1 hraje: {karta1}')
        #print(f'Hrac2 hraje: {karta2}')
        
        if (karta1 <= len(balik1) and karta2 <= len(balik2)) and len(balik1)>0 and len(balik2)>0:
            #print(f'Hraje se subgame...')
            vitez,balik = subgame(copy.deepcopy(balik1[:karta1]),copy.deepcopy(balik2[:karta2]),rekurze+1)
            #print(f'navrat do hry {rekurze}')
            
            if vitez == 1:
                #print(f'hrac 1 vyhral kolo {kolo} hry {rekurze}')
                balik1.append(karta1)
                balik1.append(karta2)
            else:
                #print(f'hrac 2 vyhral kolo {kolo} hry {rekurze}')
                balik2.append(karta2)
                balik2.append(karta1)
        else:
        
            if karta1 > karta2:
                #print(f'hrac 1 vyhral kolo {kolo} hry {rekurze}')
                balik1.append(karta1)
                balik1.append(karta2)
            else:
                #print(f'hrac 2 vyhral kolo {kolo} hry {rekurze}')
                balik2.append(karta2)
                balik2.append(karta1)
                
                
    winner = 1 if len(balik1)>0 else 2
    #print(f'hru {rekurze} vyhral hrac {winner}')
    w_balik = balik1 if len(balik1)>0 else balik2
        
    return winner,w_balik

w,winner = subgame(balik1,balik2,1)
print(w)
print(winner)

print(balik1)
print(balik2)

vysledek = 0

for i in range(len(winner)):
    vysledek += winner[len(winner)-1-i]*(i+1)
    
print(vysledek)

23. den - řazení kelímků

Další hra stim krabem zevčera. Je nějaký kolečko z kelímků kde začátek jakoby navazuje nakonec a každej ten kelímek je voznačenej nějakým číslem. nějakej kelímek je voznačenej jako aktuální. krab veme do klepet tři kelímky za aktuálně zvoleným (bych to teda jako chtěla vidět jak to jako dělá když je uplně malinkatej aty klepeta má jenom dvě :O :O) a začne mezi zbylejma kelímkama hledat takovej kterej je nejdřiv voznačenej číslem == číslo aktuálního -1 a ty tři sebraný kelímky umístí hnedka za něj. když takovej kelímek nemuže najít tak zmenčí hledanou hodnotu vo jedničku a zase kouká znova na všecky kelímky (kromě 'aktuálního' a těch 3 sebranejch) a když to číslo klesne až na nulu tak začne hledat vod nejvíc nejvěčího čísla kelímku dolu.

v první půce po nás chtěj zistit jak se nám nějakejch deset zadanejch kelímků po 100 vopakování přehází. lechký. jenže v druhý půlce máme těch krabích kelímků najednou zadanejch milion a počet vopakování neni 100 ale deset mega :O :O :O :O

tady sem se jako musela už děsně zamyslet a nakonec celkem dobře fungovalo udělat z těch kelímků spojovej seznam uplně jako z kajajova domácáku hele stim že si navíc budem pamatovat ukazatel/referenci na každej ten konkrétní uzlík v dict() abysme ho mohli rychle najít a napojovat na něj protože nejvíc nejdraší je ždycky to hledání mezi těma kelímkama.

část jedna

vstup = '364297581'
cups = [int(x) for x in vstup]
print(cups)

for step in range(100):
    
    cur = cups[0]
    arr2 = cups[4:]
    print(f'pick up {cups[1:4]}')
    mam = None
    val = cur
    while mam is None:
        for x in arr2:
            if x == val:
                mam = x
                break
        
        val -= 1
        if val==0:
            val = max(arr2)
    
    print(f'dest: {mam}')
    index = arr2.index(mam)
    index +=1
    arr2.insert(index,cups[3])
    arr2.insert(index,cups[2])
    arr2.insert(index,cups[1])
    arr2.append(cur)
    
    cups = arr2
    print(f'cups: {cups}')
    
# najít pořadí clockwise od 1

while cups.index(1)!=0:
    prvni = cups[0]
    cups=cups[1:]
    cups.append(prvni)
    
print(cups)

for c in cups[1:]:
    print(c,end='')
    
print()

část dva

vstup = '364297581'
cups = [int(x) for x in vstup]

MAX = 1000000

for i in range(10,MAX+1):
    cups.append(i)

slovnik = {}

class Node:
    
    def __init__(self,val):
        self.prev = None
        self.next = None
        self.val = val
        
    def __str__(self):
        return f'prev: {self.prev.val} next: {self.next.val} my: {self.val}'


root = Node(cups[0])
predchozi = root
for i in range(1,len(cups)):
    val = cups[i]
    n = Node(val)
    n.prev = predchozi
    slovnik[val] = n
    predchozi = n
    
root.prev = predchozi

aktualni = root
for i in range(MAX*3):
    pr = aktualni.prev
    pr.next = aktualni
    aktualni = pr

slovnik[root.val] = root
    
    
def max_val(hodnoty):
    if MAX not in hodnoty:
        return MAX
    else:
        val = MAX 
        while val in hodnoty:
            val-=1
        return val
            
    
cur = slovnik[3]
for step in range(MAX*10):

    prvni = cur.next
    druhy = cur.next.next
    treti = cur.next.next.next
    
    cur.next = treti.next
    treti.next.prev = cur
    
    hodnoty = [cur.val,prvni.val,druhy.val,treti.val]

    mam = None
    val = cur.val
    while mam is None:
        
        val = cur.val-1
        if val==0:
            val = max_val(hodnoty)
        while val in hodnoty:
            if val==0:
                val = max_val(hodnoty)
            else:
                val-=1
        if val==0:
            val = max_val(hodnoty)
        
        mam = val

    
    nalezeny = slovnik[mam]
    kam_napojit = nalezeny.next
    
    nalezeny.next = prvni
    prvni.prev = nalezeny
    
    treti.next = kam_napojit
    kam_napojit.prev = treti
    
    cur = cur.next

jedna = slovnik[1]
next1 = jedna.next.val
next2 = jedna.next.next.val
print(next1)
print(next2)
print(f'vysledek: {next1 * next2}')

24. den

chození po šestiúhelníkovitý 2d mřížce. zvolila sem trojvosej způsob kdy máte pro každý dvě protilehlý strany toho hexagonu jednu takovou jakoby vosu x,y nebo z. Jo, vosu z, i když to je jakoby jenom 2d. Vosu z máte definovanovanou jako z=-(x+y). tttttssssssss ste nikdy nehráli civilizaci nebo wesnoth?? :O :O :D :D ;D ;D

druhá půlka zase byla tamta Conwayova hra. asi nějaká úchylka pana autora :D

velikost = 100
mapa = {}

kurzor = (50,50)

e=[1,0,-1]
ne=[0,1,-1]
nw=[-1,1,0]
w=[-1,0,1]
sw=[0,-1,1]
se=[1,-1,0]

for x in range(-150,150):
    for y in range(-150,150):
        z=-(x+y)
        t = (x,y,z)
        mapa[t]=True
            

def add_v(kurzor,smer):
    for i in range(3):
        kurzor[i]+=smer[i]
    return kurzor
    
for radek in open('input').readlines():
    radek = radek.strip()
    print(radek)
    kurzor=[0,0,0]
    
    ln = len(radek)
    i=0
    while i < ln:
        print(f'kurzor zacatek: {kurzor}')
        ch = radek[i]
        if ch == 'e':
            kurzor = add_v(kurzor,e)
        elif ch == 'w':
            kurzor = add_v(kurzor,w)
            
        elif ch=='n':
            i+=1
            ch = radek[i]
            if ch=='w':
                print('nw')
                kurzor = add_v(kurzor,nw)
            if ch=='e':
                kurzor = add_v(kurzor,ne)
                
        elif ch=='s':
            i+=1
            ch = radek[i]
            if ch=='w':
                print('sw')
                kurzor = add_v(kurzor,sw)
            if ch=='e':
                print('se')
                kurzor = add_v(kurzor,se)
                
        i+=1
        
        print(f'kurzor konec: {kurzor}')
        
    k = tuple(kurzor)
    if not k in mapa:
        mapa[k]=False
    else:
        mapa[k]= not mapa[k]

kolik_b = 0
for k in mapa.keys():
    if not mapa[k]:
        kolik_b+=1
            
print(kolik_b)


# část dva votáčení

for i in range(100):
    otocit = set()

    for k in mapa.keys():
        cernych_okolo = 0
        v = list(k)
        k2 = tuple(add_v(v,e))
        if k2 in mapa:
            if mapa[k2]==False:
                cernych_okolo+=1
        v = list(k)
        k2 = tuple(add_v(v,ne))
        if k2 in mapa:
            if mapa[k2]==False:
                cernych_okolo+=1
        v = list(k)
        k2 = tuple(add_v(v,nw))
        if k2 in mapa:
            if mapa[k2]==False:
                cernych_okolo+=1
        v = list(k)
        k2 = tuple(add_v(v,w))
        if k2 in mapa:
            if mapa[k2]==False:
                cernych_okolo+=1
        v = list(k)
        k2 = tuple(add_v(v,sw))
        if k2 in mapa:
            if mapa[k2]==False:
                cernych_okolo+=1
        v = list(k)
        k2 = tuple(add_v(v,se))
        if k2 in mapa:
            if mapa[k2]==False:
                cernych_okolo+=1
                
        if mapa[k]==True and cernych_okolo==2:
            otocit.add(k)
        if mapa[k]==False and (cernych_okolo==0 or cernych_okolo > 2):
            otocit.add(k)
            
    for o in otocit:
        mapa[o]=not mapa[o]
        
    kolik_b = 0
    for k in mapa.keys():
        if not mapa[k]:
            kolik_b+=1
            
    print(kolik_b)

já vim. hrůůza to moje počítání vektorů v tuplech a listech :D příště si vemu numpy nato slibuju ;D

25. den

první půlka posledního dne byla děsně snadná a šlo ji lousknout hrubou silou složitý to bylo spíš nato pochopyt cose po nás jako v tom zadání chce dělat.

Druhá půlka byla uplně zadarmo stačilo máčknout vodkaz a přilít nějakej jelen nebo co a dal mi poslední zbejvající hvězdičku :D to měl bejt asi nějakej dárek k vánocům že zatimco každej čeká 25. to nejvíc nejvěčí svinstvo nějaký možný tak to nakonec je uplně zadarmo :D ;D

card_p = 13135480
door_p = 8821721

num = 1

loop_door = 0
loop_card = 0

for i in range(1,100000000):
    num = (num * 7) % 20201227
    
    if num == card_p:
        loop_card = i
    elif num == door_p:
        loop_door = i
        
    if loop_card != 0 and loop_door != 0:
        break
    
print(f'loop door: {loop_door} loop card: {loop_card}')
print()
print()

# transformace
num = 1
for i in range(1,loop_card+1):
    num = (num * door_p) % 20201227
    print(f'loop: {i} num: {num}')

nóó tak teda takový to bylo :D

       

Hodnocení: 88 %

        špatnédobré        

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

Komentáře

Nástroje: Začni sledovat (1) ?Zašle upozornění na váš email při vložení nového komentáře. , Tisk

Vložit další komentář

Jendа avatar 28.12.2020 13:24 Jendа | skóre: 78 | blog: Jenda | JO70FB
Rozbalit Rozbalit vše Re: pocity zážitky a dojmy z adventofcode 2020
Odpovědět | Sbalit | Link | Blokovat | Admin
Nečetl jsem to, ale třeba hned ta první úloha, kterou máš kvadraticky, jde udělat v nlogn když ta čísla nejdřív seřadíš a pak postupuješ od jednoho a druhého konce a kombinuješ jenom ta čísla, kde je naděje, že to ten součet dá.
Já to s tou denacifikací Slovenska myslel vážně.
Gréta avatar 28.12.2020 18:44 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
Rozbalit Rozbalit vše Re: pocity zážitky a dojmy z adventofcode 2020

souhlasim ;D ale těch čísel zadanjech bylo jenom 200 takže i kvadratický je dost rychlý a takle prasecky to navíc seš schopnej namastit i pod 7 minut a správně bys teda jako moh bejt v tabulce někde uplně nahoře nezi autistama kde nejvíc nejrychleší člověk prvního dne měl obě půlky za těch 7 minut :O ;D

28.12.2020 19:37 kotrcka | skóre: 23 | blog: Onééé 2 | Praha
Rozbalit Rozbalit vše Re: pocity zážitky a dojmy z adventofcode 2020
Tak pretože, pozri sa: https://www.youtube.com/watch?v=ukE5YJyPTLk

alebo teda po tvojom, hele
Keďže tu účet nejde zrušiť, zmenil som si heslo na random a "zabudol ho".
Gréta avatar 28.12.2020 21:14 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
Rozbalit Rozbalit vše Re: pocity zážitky a dojmy z adventofcode 2020

tttssssssssssss já to ďála celý bez googlu hele jeho 13ka třeba :O ;D to je jako votáčet kostičky v člobrdu když se ti nelíbí coti jako padne :D ;D

28.12.2020 22:17 kotrcka | skóre: 23 | blog: Onééé 2 | Praha
Rozbalit Rozbalit vše Re: pocity zážitky a dojmy z adventofcode 2020
Dal som ho ako príklad len z dôvodu ako klepe do klávesnice.

To je potom ľahké sa urobiť za 5 minút.
Keďže tu účet nejde zrušiť, zmenil som si heslo na random a "zabudol ho".
Gréta avatar 29.12.2020 16:33 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
Rozbalit Rozbalit vše Re: pocity zážitky a dojmy z adventofcode 2020

jj jede celkem rychle :D supr sou ty vobličeje co u toho jakoby dělá :D ;D

28.12.2020 19:32 kotrcka | skóre: 23 | blog: Onééé 2 | Praha
Rozbalit Rozbalit vše Re: pocity zážitky a dojmy z adventofcode 2020
Ja som to rozdelil na dve polia s <=1010 a >1010 a porovnával len tieto navzájom, keďže som preletel zoznam a videl že čísel 3 ciferných je málo.
Keďže tu účet nejde zrušiť, zmenil som si heslo na random a "zabudol ho".
30.12.2020 09:54 Kate | skóre: 9
Rozbalit Rozbalit vše Re: pocity zážitky a dojmy z adventofcode 2020
Za cenu větší spotřeby paměti to jde i rychleji. https://paste.rs/Jcr.rs
30.12.2020 09:56 Kate | skóre: 9
Rozbalit Rozbalit vše Re: pocity zážitky a dojmy z adventofcode 2020
tl;dr - nasypat všechna čísla do setu a pak pro každé číslo hledat rozdíl od kýženého součtu.
29.12.2020 13:10 srbt | skóre: 6
Rozbalit Rozbalit vše Moje řešení, kdyby někoho zajímalo
Odpovědět | Sbalit | Link | Blokovat | Admin
https://gitlab.com/tomas.srb/adventofcode/-/tree/master/2020
Gréta avatar 29.12.2020 16:36 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
Rozbalit Rozbalit vše Re: Moje řešení, kdyby někoho zajímalo

věčinu máš vo moc hežčejc než já :D ;D

29.12.2020 18:10 srbt | skóre: 6
Rozbalit Rozbalit vše Re: Moje řešení, kdyby někoho zajímalo
Jenže nad skládáním mapy jsem strávil asi osm hodin čistého času a jednu úlohu jsem napsal v pascalu, protože jsem byl umanutej že to musím optimalizovat pomocí pointerů a až pozdě mi došlo, že v pythonu jsou pointery prakticky všechno :-), že stačí jen zapomenout na skládání polí.
29.12.2020 18:12 srbt | skóre: 6
Rozbalit Rozbalit vše Re: Moje řešení, kdyby někoho zajímalo
...a díky za kompliment :-).
29.12.2020 15:27 Dvojté Véčko
Rozbalit Rozbalit vše Re: pocity zážitky a dojmy z adventofcode 2020
Odpovědět | Sbalit | Link | Blokovat | Admin
Jaktože má tohle tučňáka a můj tet o tom, že má tux syna ne?
Gréta avatar 29.12.2020 16:31 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
Rozbalit Rozbalit vše Re: pocity zážitky a dojmy z adventofcode 2020

nóó si ho počitám spíš jako vánoční dárek než žeby byl uplně zaslouženej ;D

ale i tak jako díky :D

29.12.2020 17:16 kotrcka | skóre: 23 | blog: Onééé 2 | Praha
Rozbalit Rozbalit vše Re: pocity zážitky a dojmy z adventofcode 2020
Ale mala by si tam mať hada, nie tučniaka.

Pretože, takto nepokryte propagovať tento jazyk.. no..
Keďže tu účet nejde zrušiť, zmenil som si heslo na random a "zabudol ho".
Gréta avatar 31.12.2020 02:37 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
Rozbalit Rozbalit vše Re: pocity zážitky a dojmy z adventofcode 2020

ttsssssssss zato jako nemužu že python je uplně nejvíc nejlepší programovací jazyk na celým světě :D :D ;D ;D

Založit nové vláknoNahoru

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.