input = AOC.readDayInput('03') tree = '#' def checkTrees(map, right, down): x = 0 xMax = len(map[0]) trees = 0 for y in range(down, len(map), down): x = (x + right) % xMax if (map[y][x] == tree): trees += 1 return trees # FIRST STAR allTrees = checkTrees(input, 3, 1) AOC.printDayAnswer(1, allTrees) # SECOND STAR slopes = [ [1, 1], [5, 1], [7, 1], [1, 2] ] for slope in slopes: allTrees *= checkTrees(input, slope[0], slope[1]) AOC.printDayAnswer(2, allTrees)
direction = indexToDirection.index('E') for command in input: action = command[:1] value = int(command[1:]) if action == 'F': action = indexToDirection[direction] if action in directions.keys(): coords[0] += value * directions[action][0] coords[1] += value * directions[action][1] else: direction = shipRotations[action](direction, value // 90, len(indexToDirection)) AOC.printDayAnswer(1, sum([abs(n) for n in coords])) ## SECOND STAR ship = [0, 0] waypoint = [10, 1] waypointRotations = { 'L': lambda x, y: [y * -1, x], 'R': lambda x, y: [y, x * -1], } for command in input: action = command[:1] value = int(command[1:]) if action in directions.keys():
groups = regex.match(password).groups() min = int(groups[0]) max = int(groups[1]) letter = groups[2] word = groups[3] counter = 0 for let in word: if (let == letter): counter += 1 if (counter >= min and counter <= max): correctWords += 1 AOC.printDayAnswer(1, correctWords) # SECOND STAR correctWords = 0 for password in input: groups = regex.match(password).groups() index1 = int(groups[0]) - 1 index2 = int(groups[1]) - 1 letter = groups[2] word = groups[3] analysis = 0 if (word[index1] == letter): analysis += -1 if (word[index2] == letter): analysis += +1
## FIRST STAR def getAdjacentOccupied(seats, x, y): occupied = 0 for pos in positions: adjX = x + pos[0] adjY = y + pos[1] if (0 <= adjX < lenX and 0 <= adjY < lenY and seats[adjY][adjX] == occupiedSeat): occupied += 1 return occupied AOC.printDayAnswer(1, getOccupiedInEquilibrium(input, getAdjacentOccupied)) ## SECOND STAR def getVisibleOccupied(seats, x, y): occupied = 0 for pos in positions: visX = x visY = y while 0 <= visX < lenX and 0 <= visY < lenY: visX += pos[0] visY += pos[1] if 0 <= visX < lenX and 0 <= visY < lenY:
import itertools import modules.aoc as AOC input = AOC.readDayInput('09', True) preamble = 25 ## FIRST STAR for i in range(preamble, len(input)): if not any([ sum(comb) == input[i] for comb in itertools.combinations(input[i - preamble:i], 2) ]): invalid = input[i] AOC.printDayAnswer(1, input[i]) break ## SECOND STAR start = 0 end = 1 weakSum = input[start] + input[end] while (weakSum != invalid): if (weakSum < invalid): end += 1 weakSum += input[end] elif (weakSum > invalid): while (weakSum > invalid and start < end): weakSum -= input[start] start += 1
if field != 'cid': currentPassport[field] = value else: passports.append(currentPassport) currentPassport = {} passports.append(currentPassport) requiredFields = ['byr', 'ecl', 'eyr', 'hcl', 'hgt', 'iyr', 'pid'] validPassports = [] for passport in passports: if len(set(passport.keys()) & set(requiredFields)) == len(requiredFields): validPassports.append(passport) AOC.printDayAnswer(1, len(validPassports)) # SECOND STAR validations = { 'byr': lambda value: 1920 <= int(value) <= 2002, 'iyr': lambda value: 2010 <= int(value) <= 2020, 'eyr': lambda value: 2020 <= int(value) <= 2030, 'hgt': lambda value: ("in" in value and 59 <= int(re.sub(r"in", '', value)) <= 76) or ("cm" in value and 150 <= int(re.sub(r"cm", '', value)) <= 193), 'hcl': lambda value: re.match(r"^#[0-9a-f]{6}$", value),
currentMaskTo0 = None for line in input: command, value = line.split(' = ') if (command == 'mask'): currentMaskTo1 = int(value.replace('X', '0'), base=2) currentMaskTo0 = int(value.replace('X', '1'), base=2) continue command = command.replace('mem[', '').replace(']', '') value = int(value) memory[command] = (value | currentMaskTo1) & currentMaskTo0 AOC.printDayAnswer(1, sum(memory.values())) ## SECOND STAR memory = dict() currentMask = '' for line in input: command, value = line.split(' = ') if (command == 'mask'): currentMask = value continue command = int(command.replace('mem[', '').replace(']', '')) value = int(value)
def memoryGame(starters, lastNumber): occurences = dict() spoken = starters[:] for i in range(len(spoken)): occurences[spoken[i]] = [i] for i in range(len(spoken), lastNumber): lastSpoken = spoken[i - 1] if len(occurences[lastSpoken]) == 1: spoken.append(0) else: spoken.append(occurences[lastSpoken][-1] - occurences[lastSpoken][-2]) if spoken[i] in occurences: occurences[spoken[i]].append(i) else: occurences[spoken[i]] = [i] return spoken[-1] ## FIRST STAR AOC.printDayAnswer(1, memoryGame(input, 2020)) ## SECOND STAR AOC.printDayAnswer(2, memoryGame(input, 30000000))
letterDict[chr(i)] = 0 return letterDict # FIRST STAR totalAnswers = 0 for group in input: groupSet = set() for personAnswers in group: [groupSet.add(answer) for answer in personAnswers] totalAnswers += len(groupSet) AOC.printDayAnswer(1, totalAnswers) # SECOND STAR totalAnswers = 0 for group in input: frequency = createLetterDict() for personAnswers in group: for answer in personAnswers: frequency[answer] += 1 frequency = { letter:freq for (letter,freq) in frequency.items() if freq == len(group) } totalAnswers += len(frequency) AOC.printDayAnswer(2, totalAnswers)
import modules.aoc as AOC input = AOC.readDayInput('10', True) input.sort() ## FIRST STAR differences = [0, 0, 1] differences[input[0] - 1] += 1 for i in range(1, len(input)): differences[input[i] - input[i - 1] - 1] += 1 AOC.printDayAnswer(1, differences[0] * differences[2]) ## SECOND STAR input = [0] + input possibilities = [None] * len(input) maxJolt = max(input) def calcPossibilities(i): if (input[i] == maxJolt): return 1 count = 0 for next in range(i + 1, i + 4): if next < len(input) and (input[next] - input[i]) <= 3: if possibilities[next] is None: count += calcPossibilities(next) else:
buses = [int(bus) if bus != 'x' else bus for bus in input[1].split(',')] ## FIRST STAR earliestBusID = None earliestBusTime = myEarliestTime * myEarliestTime for busID in buses: if (busID == 'x'): continue firstBus = int(math.ceil(myEarliestTime / busID)) * busID if (firstBus < earliestBusTime): earliestBusTime = firstBus earliestBusID = busID AOC.printDayAnswer(1, earliestBusID * (earliestBusTime - myEarliestTime)) ## SECOND STAR def chineseRemainderTheorem(numbers, remainders): product = math.prod(numbers) productDiv = [product // num for num in numbers] inverses = [ pow(productDiv[i], numbers[i] - 2, numbers[i]) for i in range(len(productDiv)) ] x = 0 for i in range(len(numbers)): x += productDiv[i] * inverses[i] * remainders[i]
if index in executedIndexes: looped = True break executedIndexes.add(index) if (instructions[index]['op'] == 'acc'): accumulator += instructions[index]['arg'] if (instructions[index]['op'] == 'jmp'): index += instructions[index]['arg'] else: index += 1 return accumulator, looped acc, looped = executeBoot(instructions) AOC.printDayAnswer(1, acc) ## SECOND STAR for i in range(len(instructions)): if instructions[i]['op'] != 'acc': newInstructions = copy.deepcopy(instructions) newInstructions[i][ 'op'] = 'nop' if newInstructions[i]['op'] == 'jmp' else 'jmp' acc, looped = executeBoot(newInstructions) if not looped: AOC.printDayAnswer(2, acc) break
import re import modules.aoc as AOC def getBinaryFromInput(line): line = re.sub(r"[F|L]", '0', line) return re.sub(r"[B|R]", '1', line) input = [getBinaryFromInput(line) for line in AOC.readDayInput('05')] seatIDs = [int(seat, base=2) for seat in input] ## FIRST STAR AOC.printDayAnswer(1, max(seatIDs)) ## SECOND STAR seatIDs.sort() for i in range(len(seatIDs) - 1): if seatIDs[i] + 2 == seatIDs[i + 1]: AOC.printDayAnswer(2, seatIDs[i] + 1) break
operators.append(token) while operators: postfix.append(operators.pop()) return postfix def evaluateExpression(expression, precedence): postfix = getPostfixNotation(expression, precedence) operands = [] for token in postfix: if token.isnumeric(): operands.append(int(token)) else: val2 = operands.pop() val1 = operands.pop() operands.append(eval(str(val1) + token + str(val2))) return operands[0] ## FIRST STAR precedence = { '+': 1, '*': 1 } result = sum([ evaluateExpression(exp, precedence) for exp in input ]) AOC.printDayAnswer(1, result) ## SECOND STAR precedence = { '+': 2, '*': 1 } result = sum([ evaluateExpression(exp, precedence) for exp in input ]) AOC.printDayAnswer(2, result)
for cube in list(startGrid.keys()): for neighbor in neighbors: neighborCoord = sumCoord(cube, neighbor) if neighborCoord not in startGrid: startGrid[neighborCoord] = '.' newGrid = startGrid.copy() for cube in startGrid: activatedNeighbors = 0 for neighbor in neighbors: neighborCoord = sumCoord(cube, neighbor) if neighborCoord in startGrid and startGrid[ neighborCoord] == '#': activatedNeighbors += 1 if startGrid[cube] == '#' and activatedNeighbors not in [2, 3]: newGrid[cube] = '.' elif startGrid[cube] == '.' and activatedNeighbors == 3: newGrid[cube] = '#' startGrid = newGrid return list(startGrid.values()).count('#') AOC.printDayAnswer(1, bootingCycles(input, 3)) # FIRST STAR AOC.printDayAnswer(2, bootingCycles(input, 4)) # SECOND STAR
allBags[currentBag] = bagContent ## FIRST STAR contentBags = [myBag] contentIndex = 0 while (contentIndex < len(contentBags)): currentBag = contentBags[contentIndex] for bagKey in allBags: if currentBag in allBags[bagKey] and bagKey not in contentBags: contentBags.append(bagKey) contentIndex += 1 AOC.printDayAnswer(1, len(contentBags) - 1) ## SECOND STAR def countBagsInside(bag): if allBags[bag] == {}: return 0 amount = 0 for insideBagKey in allBags[bag]: amountOfThisBag = int(allBags[bag][insideBagKey]) amount += amountOfThisBag + (countBagsInside(insideBagKey) * amountOfThisBag) return amount
import modules.aoc as AOC input = AOC.readDayInput('01', True) input.sort() # FIRST STAR frequency = [None] * 2021 for number in input: frequency[number] = True if (frequency[abs(number - 2020)]): AOC.printDayAnswer(1, number * abs(number - 2020)) break # SECOND STAR right = len(input) - 1 left = 0 mid = 1 sum = -1 while (sum != 2020): sum = input[left] + input[mid] + input[right] if (sum < 2020): mid += 1 if (sum > 2020): if (mid >= right): right -= 1 left = 0