diff options
| author | blenovo <bk@gmail.com> | 2025-08-06 00:51:06 +0200 |
|---|---|---|
| committer | blenovo <bk@gmail.com> | 2025-08-06 00:51:06 +0200 |
| commit | 0a441ce2306ae9edefb009fbc0596f4d511cdc7f (patch) | |
| tree | 11d5aca4383bbce8a35acb912698f473b8180215 | |
| parent | 12f551dbfef138880b29ba6abe4576714ae942cb (diff) | |
summertime warmup session - finish
| -rw-r--r-- | 2020/aoc2020-d21.py | 41 | ||||
| -rw-r--r-- | 2020/aoc2020-d22.py | 74 | ||||
| -rw-r--r-- | 2020/aoc2020-d23.py | 58 | ||||
| -rw-r--r-- | 2020/aoc2020-d24.py | 85 | ||||
| -rw-r--r-- | 2020/aoc2020-d25.py | 29 |
5 files changed, 287 insertions, 0 deletions
diff --git a/2020/aoc2020-d21.py b/2020/aoc2020-d21.py new file mode 100644 index 0000000..f6edea8 --- /dev/null +++ b/2020/aoc2020-d21.py @@ -0,0 +1,41 @@ +#advent of code 2020 +#day 21 +#part 2 very similar to ticket problem from the same year + +ingredients = []; +AllergyDict = dict(); +PossibleAllergens = set(); +AssignedAllergens = dict(); + +PuzzleInput = open("21.in","r"); +for line in PuzzleInput: + line = line.replace("\n",""); + FoodIngr, FoodAllr = line[:-1].split(" (contains "); + FoodIngr = FoodIngr.split(" "); + FoodAllr = FoodAllr.split(", "); + ingredients.extend(FoodIngr); + for a in FoodAllr: + if a in AllergyDict: + AllergyDict[a].intersection_update(set(FoodIngr)); + else: + AllergyDict[a] = set(FoodIngr); +PuzzleInput.close(); + +for al in AllergyDict: + print(al, AllergyDict[al]); + PossibleAllergens.update(AllergyDict[al]); + +p1 = len([i for i in ingredients if i not in PossibleAllergens]); +print("part 1 =",p1); + +while len(AssignedAllergens) != len(AllergyDict): + #print(len(AssignedAllergens),"/", len(AllergyDict)); #in case it takes long + for al in AllergyDict: + if len(AllergyDict[al]) == 1: + found = AllergyDict[al].pop(); + AssignedAllergens[al] = found; + else: + AllergyDict[al].difference_update( AssignedAllergens.values() ); + +p2 = ",".join([AssignedAllergens[allergen] for allergen in sorted(AssignedAllergens.keys())]); +print("part 2 =",p2); diff --git a/2020/aoc2020-d22.py b/2020/aoc2020-d22.py new file mode 100644 index 0000000..01b9a4c --- /dev/null +++ b/2020/aoc2020-d22.py @@ -0,0 +1,74 @@ +#advent of code 2020 +#day 22 +#some problems with copying, modifying, accessing data between functions +#had a bit of workarounds +#Im too lazy to reduce the amount of code +#by including part1 and part2 in a single function + +def NormalCombat(player1, player2): + decks = dict(); + decks[0] = player1.copy(); + decks[1] = player2.copy(); + while len(decks[0]) > 0 and len(decks[1]) > 0 : + card0 = decks[0].pop(0); + card1 = decks[1].pop(0); + if card0 > card1: + decks[0].append(card0); + decks[0].append(card1); + elif card0 < card1: + decks[1].append(card1); + decks[1].append(card0); + score = 0; + for deck in decks: + if len(decks[deck]) == 0: continue; + for c, card in enumerate(decks[deck]): + score += (len(decks[deck])-c)*card + break; + return score; + +def RecursiveCombat(player1, player2): + decks = dict(); + decks[0] = player1.copy(); + decks[1] = player2.copy(); + previoushands = dict(); + previoushands[0] = []; + previoushands[1] = []; + while len(decks[0]) > 0 and len(decks[1]) > 0 : + if tuple(decks[0]) in previoushands[0] and tuple(decks[1]) in previoushands[1]: + return 0, None; + previoushands[0].append(tuple(decks[0])); + previoushands[1].append(tuple(decks[1])); + card0 = decks[0].pop(0); + card1 = decks[1].pop(0); + if card0 <= len(decks[0]) and card1 <= len(decks[1]): + winner, winscore = RecursiveCombat(decks[0][:card0],decks[1][:card1]); + elif card0 > card1: + winner = 0; + elif card0 < card1: + winner = 1; + playedcards = [card0,card1]; + decks[winner].append(playedcards[winner]); + decks[winner].append(playedcards[(winner+1)%2]); + score = 0; + for deck in decks: + #print(decks[deck]); + if len(decks[deck]) == 0: continue; + for c, card in enumerate(decks[deck]): + score += (len(decks[deck])-c)*card + winplayer = 0 + deck; + break; + return winplayer, score; + +PuzzleInput = open("22.in","r").read(); +playerdata1, playerdata2 = PuzzleInput.split("\n\n"); +playerdecks = dict(); +for pi, playerdata in enumerate( [playerdata1,playerdata2] ): + playerdecks[pi] = [int(val) for val in playerdata.split("\n")[1:] if val != ""]; + +p1 = NormalCombat(playerdecks[0],playerdecks[1]); +print("part 1 =",p1); +_, p2 = RecursiveCombat(playerdecks[0],playerdecks[1]); +print("part 2 =",p2); +print('''part 1 = 34664 +part 2 = 32018 +'''); diff --git a/2020/aoc2020-d23.py b/2020/aoc2020-d23.py new file mode 100644 index 0000000..b0bb6c0 --- /dev/null +++ b/2020/aoc2020-d23.py @@ -0,0 +1,58 @@ +#advent of code 2020 +#day 23 +#kinda cheated, I used another guy's solution for debugging +# https://0xdf.gitlab.io/adventofcode2020/23 (cool source btw) +#turns out my dictionary was getting one value from input replaced +#which caused "cutting off" most of the other numbers +#also tried filling out the dictionary with all numbers +#but I was getting confused by different indexation +#puzzle uses (0,1mil] instead of "standard" [0,1mil) +#also minor mistakes in substitution ordering +PuzzleInput = open("23.in","r").read().replace("\n",""); +cups = [int(v) for v in PuzzleInput]; + +def cupgame(cuplabels, lim, cuplim): + cupdict = dict(); + for c_i in range(len(cuplabels) -1): + cupdict[cuplabels[c_i]] = cuplabels[c_i+1]; + if cuplim == len(cuplabels): + cupdict[cuplabels[-1]] = cuplabels[0]; + else: + cupdict[cuplabels[-1]] = 10; + for c_i in range(len(cuplabels)+1,cuplim): + cupdict[c_i] = c_i + 1; + cupdict[ cuplim ] = cuplabels[0]; + + c0 = 0 + cuplabels[0]; + for step in range(lim): + if step%1000000 == 0: print(step//1000000,"/",lim//1000000); + c1 = cupdict[c0] #,(c0+1)%(cuplim+1) +1); + c2 = cupdict[c1] #,(c1+1)%(cuplim+1) +1); + c3 = cupdict[c2] #,(c2+1)%(cuplim+1) +1); + cupdict[c0] = cupdict[c3] #,(c3+1)%(cuplim+1) +1); + d0 = c0 - 1; + if d0 == 0: d0 = cuplim; + while True: + if d0 not in [c1,c2,c3]: break; + d0 -= 1; + if d0 == 0: d0 = cuplim; + cupdict[c3] = cupdict[d0]; + cupdict[d0] = c1; + c0 = cupdict[c0]; + + if cuplim == len(cuplabels): + solution = ""; + NextVal = 1; + for s in range(8): + NextVal = cupdict[NextVal]; + solution += str(NextVal); + else: + solution = cupdict[1] * cupdict[cupdict[1]]; + + return solution; + +p1 = cupgame(cups,100, len(cups)); +p2 = cupgame(cups,10000000, 1000000); +print("part 1 =",p1); +print("part 2 =",p2); + diff --git a/2020/aoc2020-d24.py b/2020/aoc2020-d24.py new file mode 100644 index 0000000..c886be1 --- /dev/null +++ b/2020/aoc2020-d24.py @@ -0,0 +1,85 @@ +#advent of code 2020 +#day 24 +# https://www.redblobgames.com/grids/hexagons/ +# nested ifs in CheckAdjacent function aren't really slower than +# making it a function, so i'm leaving it bc its more readable that way + +def CheckAdjacent(point, blackset): + black = 0; + py,px,pz = point; + for dkey in directions: + dx,dy,dz = directions[dkey]; + p = (py+dy,px+dx, pz+dz); + if p in blackset: + black += 1; + + if point in blackset: + if black == 0 or black > 2: + return False; + else: + return True; + else: + if black == 2: + return True; + else: + return False; + +tilesteps = []; + +PuzzleInput = open("24.in","r") +for line in PuzzleInput: + line = line.replace("\n",""); + instructions = []; + i = 0; + while i < len(line): + if line[i] in ["n","s"]: + instructions.append(line[i:i+2]); + i += 2; + else: + instructions.append(line[i]); + i += 1; + tilesteps.append(instructions); +PuzzleInput.close(); + +directions = dict(); +directions["e"] = (1,0,-1); +directions["w"] = (-1,0,1); +directions["ne"] = (1,-1,0); +directions["nw"] = (0,-1,1); +directions["sw"] = (-1,1,0); +directions["se"] = (0,1,-1); + +grid = dict(); +# 0 - white +# 1 - black + +for tilestep in tilesteps: + p = (0,0,0); + for step in tilestep: + py,px,pz = p; + dy,dx,dz = directions[step]; + p = (py+dy,px+dx, pz+dz); + grid[p] = ( grid.get(p,0) + 1)%2; + +blacks = set(); +part1 = 0; +for g in grid: + if grid[g] == 1: + part1 += 1; + blacks.add(g); + +print("part 1 =", part1); + +days = 100; +for day in range(days): + NewBlacks = set(); + for b in blacks: + if CheckAdjacent(b,blacks): NewBlacks.add(b); + for coord in directions.values(): + n = (b[0] + coord[0],b[1] + coord[1],b[2] + coord[2]); + if CheckAdjacent(n,blacks): NewBlacks.add(n); + blacks = set(); + blacks.update(NewBlacks); + +part2 = len(blacks); +print("part 2 =", part2); diff --git a/2020/aoc2020-d25.py b/2020/aoc2020-d25.py new file mode 100644 index 0000000..28d1afe --- /dev/null +++ b/2020/aoc2020-d25.py @@ -0,0 +1,29 @@ +#advent of code 2020 +#day 25 +#I made a mistake by thinking that subject number is an unknow +#while in reality it actually is =7 as in puzzle description + +def FindNumbers(pubkey): + S = 7; + L = 0; + v = 1; + while True: + L += 1; + v *= S; + v = v%20201227; + if v == pubkey: + return L; #gives loop number + +PuzzleInput = open("25.in","r").read().split("\n"); +cardkey = int(PuzzleInput[0]); +doorkey = int(PuzzleInput[1]); +#encryption key is the same +#whether we use loop of card + subject of door +#or loop of door + subject of card +encryption = 1; +for l in range(FindNumbers(cardkey)): + encryption *= doorkey; + encryption = encryption%20201227; + +part1 = encryption; +print("part 1 =", part1); |
