def get_factors_with_limitation(Factors): for factor in Factors: Elves[factor] = Elves[factor] + 1 if factor in Elves else 1 return {factor for factor in Factors if Elves[factor] <= 50} #### Main part. Elves = {} house = 0 house_1 = 0 house_2 = 0 while True: house += 1 Factors = get_factors(house) # Part One if 10 * sum(Factors) >= INPUT and house_1 == 0: house_1 = house # Part Two if 11 * sum( get_factors_with_limitation(Factors)) >= INPUT and house_2 == 0: house_2 = house if house_1 * house_2 != 0: break print_results(house_1, house_2)
import hashlib from common import print_results, readline INPUT = readline(__file__) def find_suffix(prefix, suffix=0): while True: md5 = hashlib.md5(str.encode(INPUT + str(suffix))) if md5.hexdigest().startswith(prefix): return suffix suffix += 1 #### Main part. five = find_suffix('0' * 5) six = find_suffix('0' * 6, five) print_results(five, six)
not self.handled and self.low_to is not None and self.high_to is not None and len(self.values) == 2 ) class Output: def __init__(self, number): self.number = number self.values = set() def add_value(self, value): self.values.add(value) def get_sum(self): return sum(self.values) #### Main part. factory = Factory() for line in readlines(__file__): factory.add(line) factory.run() print_results( factory.get_bot_which_handles([17, 61]), factory.get_multiplied_outputs([0, 1, 2]) )
from common import print_results, readline def find_basement_position(parentheses): floor = 0 for i, p in enumerate(parentheses, start=1): floor += 1 if p == '(' else -1 if floor == -1: return i #### Main part. parentheses = readline(__file__) print_results( parentheses.count('(') - parentheses.count(')'), find_basement_position(parentheses), )
def __init__(self): self.x = 0 self.y = 0 self.visited_locations = {(0, 0)} def update_location(self, direction): dx, dy = self.STR2VEC[direction] self.x += dx self.y += dy self.visited_locations.add((self.x, self.y)) #### Main part. directions = readline(__file__) # Part One santa_only = Runner() for d in directions: santa_only.update_location(d) # Part Two santa = Runner() robo_santa = Runner() for d, e in zip(directions[0::2], directions[1::2]): santa.update_location(d) robo_santa.update_location(e) print_results(len(santa_only.visited_locations), len(santa.visited_locations | robo_santa.visited_locations))
import json import re from common import print_results, read NUMBER_REGEX = re.compile(r'-?\d+') json_string = read(__file__) # Part One count_1 = sum(int(s) for s in NUMBER_REGEX.findall(json_string)) # Part Two red = lambda x: {} if 'red' in x.values() else x json_string = json.dumps(json.loads(json_string, object_hook=red)) count_2 = sum(int(s) for s in NUMBER_REGEX.findall(json_string)) print_results(count_1, count_2)
import re from common import print_results, readline sequence = readline(__file__) DIGIT_GROUP = re.compile(r'((\d)\2*)') def play_game(times): global sequence for _ in range(times): res = '' for group, digit in DIGIT_GROUP.findall(sequence): res += '{}{}'.format(len(group), digit) sequence = res return len(sequence) print_results(play_game(40), play_game(10))
from numpy import prod from common import print_results, readlines def get_wrapping_paper(present): sides = ( present[0] * present[1], present[0] * present[2], present[1] * present[2], ) return 2 * sum(sides) + min(sides) def get_ribbon(present): return 2 * (present[0] + present[1]) + prod(present) #### Main part. wrapping_paper = 0 ribbon = 0 for line in readlines(__file__): present = sorted(map(int, line.split('x'))) wrapping_paper += get_wrapping_paper(present) ribbon += get_ribbon(present) print_results(wrapping_paper, ribbon)
position += instruction[2] elif instruction[0] == 'jmp': position += instruction[2] elif instruction[0] == 'jie': position += instruction[2] if x % 2 == 0 else 1 elif instruction[0] == 'jio': position += instruction[2] if x == 1 else 1 return (x, b) if instruction[1] == 'a' else (a, x) while True: try: a, b = update_register(instructions[position]) except: return b #### Main part. instructions = [] for line in readlines(__file__): m = INPUT_ARRANGEMENT.match(line) if m.group(1) == 'jio' or m.group(1) == 'jie': instructions.append((m.group(1), m.group(2), int(m.group(3)))) elif m.group(1) == 'jmp': instructions.append((m.group(1), '', int(m.group(2)))) else: instructions.append((m.group(1), m.group(2), 1)) print_results(run_program(0), run_program(1))
def __get_babs_of_abas(self): babs = [] for part in self.supernet_parts: abas = self.ABA_REGEX.finditer(part) for aba in abas: if aba.group(2) != aba.group(3): babs.append(self.__get_bab(aba.group(1))) return babs def __get_bab(self, aba): return aba[1] + aba[0] + aba[1] def supports_tls(self): return (any(self.__has_abba(part) for part in self.supernet_parts) and not any(self.__has_abba(part) for part in self.hypernet_parts)) def supports_ssl(self): babs = self.__get_babs_of_abas() for bab in babs: if any(bab in part for part in self.hypernet_parts): return True return False #### Main part. ip_addresses = [IPAddress(ip_address) for ip_address in readlines(__file__)] print_results(sum(ip_address.supports_tls() for ip_address in ip_addresses), sum(ip_address.supports_ssl() for ip_address in ip_addresses))
from common import print_results, readline NUMBER_ELVES = int(readline(__file__)) def get_winner_of_game_1(): number_participants = 1 winner = 1 while number_participants < NUMBER_ELVES: number_participants += 1 winner = winner + 2 if winner + 2 <= number_participants else 1 return winner def get_winner_of_game_2(): participants = list(range(1, NUMBER_ELVES + 1)) turn = 0 number_participants = NUMBER_ELVES while number_participants > 1: elf_to_kick = (int(number_participants / 2) + turn) % number_participants del participants[elf_to_kick] number_participants = len(participants) turn = (turn if elf_to_kick < turn else turn + 1) % number_participants return participants[0] #### Main part. print_results(get_winner_of_game_1(), get_winner_of_game_2())
REPLACEMENT_REGEX = re.compile(r'(\w+) => (\w+)') replace = lambda s, i, rep: s[:i] + rep[1] + s[i + len(rep[0]):] #### Main part. lines = readlines(__file__) replacements = [REPLACEMENT_REGEX.match(line).groups() for line in lines[:-2]] medicine = lines[-1] LENGTH = len(medicine) # Part One Molecules = set() for rep in replacements: for occ in [n for n in range(LENGTH) if medicine.find(rep[0], n) == n]: Molecules.add(replace(medicine, occ, rep)) # Part Two (using a Greedy-like algorithm) replacements.sort(key=lambda repl: repl[1], reverse=True) step = 0 while medicine != 'e': for repl in replacements: if medicine.replace(repl[1], repl[0], 1) == medicine: continue medicine = medicine.replace(repl[1], repl[0], 1) step += 1 break print_results(len(Molecules), step)
IPInterval = namedtuple('IPInterval', 'start end') def get_smallest_possible(intervals): smallest_ip = 0 start, end = intervals.popleft() while start <= smallest_ip: smallest_ip = end + 1 start, end = intervals.popleft() return smallest_ip def count_all_possible(intervals): counter, possible_white_ip = 0, 0 while len(intervals) > 0: start, end = intervals.popleft() counter += max(0, start - possible_white_ip) possible_white_ip = max(end + 1, possible_white_ip) return counter + NUMBER_IP_ADDRESSES - possible_white_ip #### Main part. intervals = sorted((IPInterval(*map(int, REGEX_RANGE.match(line).groups())) for line in readlines(__file__)), key=lambda interval: interval.start) print_results(get_smallest_possible(deque(intervals)), count_all_possible(deque(intervals)))
self.__set_up_graph() # Find shortest path to each node starting at 'SOURCE'. self.shortest_paths = nx.shortest_path_length(self.graph, source=SOURCE) # Set up a graph where the nodes are the open spaces. Neighboring open # spaces are connected by an edge. def __set_up_graph(self): for i, j in prod(range(0, MAX_EXPANSION), repeat=2): if self.__is_open_space(i, j): for k, l in list(prod([-1, 1], [0])) + list(prod([0], [-1, 1])): if self.__is_open_space(i + k, j + l): self.graph.add_edge((i, j), (i + k, j + l)) def __is_open_space(self, x, y): if x < 0 or y < 0: return False return format((x + y)**2 + 3*x + y + FAVORITE, 'b').count('1') % 2 == 0 def get_number_paths_not_longer_than(self, threshold): return sum(1 for i in self.shortest_paths.values() if i <= threshold) #### Main Part. maze = Maze() print_results( maze.shortest_paths[TARGET], maze.get_number_paths_not_longer_than(MAX_DISTANCE) )
def get_real_sue(): return sues.index([sue for sue in sues if tt.is_subset_of_tape(sue)][0]) + 1 #### Main part. sues = [] for line in readlines(__file__): m = INPUT_ARRANGEMENT.match(line) sues.append({ (m.group(2), int(m.group(3))), (m.group(4), int(m.group(5))), (m.group(6), int(m.group(7))) }) tt = TickerTape(TICKER_TAPE) # Part One sue_1 = get_real_sue() # Part Two max_value = max(max(thing[1] for thing in sue) for sue in sues) tt.add_things_greater_than('cats', max_value) tt.add_things_greater_than('trees', max_value) tt.add_things_less_than('pomeranians') tt.add_things_less_than('goldfish') sue_2 = get_real_sue() print_results(sue_1, sue_2)
@property def message_length(self): return len(self.message) def find_shortest_path(positions=[Position()]): next_positions = [] for position in positions: for direction in position.get_possible_directions(): next_position = position.move(direction) if next_position.is_destination(): return next_position.digest.message_as_string next_positions.append(next_position) return find_shortest_path(next_positions) def find_steps_of_longest_path(): max_steps = 0 positions = deque([Position()]) while positions: position = positions.popleft() directions = position.get_possible_directions() if position.is_destination(): max_steps = max(position.digest.message_length, max_steps) else: positions.extend(position.move(d) for d in directions) return max_steps #### Main part. print_results(find_shortest_path(), find_steps_of_longest_path())
)) # Go over to property tripel only. Possibilities = [ addTupels(addTupels(pos[0], pos[1]), addTupels(pos[2][0], pos[2][1])) for pos in Possibilities ] #### Main part. # Create the boss reading the data from the file. lines = readlines(__file__) boss_live = INPUT_REGEX.match(lines[0]).group(1) boss_damage = INPUT_REGEX.match(lines[1]).group(1) boss_armor = INPUT_REGEX.match(lines[2]).group(1) minimum = float('inf') maximum = 0 for pos in Possibilities: boss = Player(boss_live, boss_damage, boss_armor) player = Player(100, pos[1], pos[2]) while player.is_alive() and boss.is_alive(): player.attack(boss) boss.attack(player) if not boss.is_alive(): minimum = min(minimum, pos[0]) if not player.is_alive() and boss.is_alive(): maximum = max(maximum, pos[0]) print_results(minimum, maximum)
'OR': lambda wire: self[wire.left_wire] | self[wire.right_wire], 'LSHIFT': lambda wire: self[wire.left_wire] << self[wire.right_wire], 'RSHIFT': lambda wire: self[wire.left_wire] >> self[wire.right_wire], }[wire.gate](wire) return wire.signal def reset(self): for wire in self.wires.values(): if wire.gate: wire.signal = None #### Main part. circuit = Circuit() for line in readlines(__file__): circuit.add_wire(*Wire.createcommon_wire(line)) # Part One signal_1 = circuit['a'] # Part Two circuit.reset() circuit.wires['b'].signal = signal_1 signal_2 = circuit['a'] print_results(signal_1, signal_2)
import re from common import print_results, readline ROW_COLUMN_REGEX = re.compile(r'Enter the code at row (\d+), column (\d+)\.') ROW, COLUMN = map(int, ROW_COLUMN_REGEX.search(readline(__file__)).groups()) A_0 = 20151125 FACTOR = 252533 DIVISOR = 33554393 # First, calculate how many steps are necessary. b = ROW + COLUMN - 2 number_steps = b * (b + 1) // 2 + b + 2 - ROW def do_step(a_n): while True: yield a_n a_n = FACTOR * a_n % DIVISOR #### Main part. sequence = do_step(A_0) for _ in range(number_steps - 1): sequence.__next__() print_results(sequence.__next__(), 'Merry Christmas!')
ZEROS = 5 def compute_ids(): id_1 = [] id_2 = list(8 * '_') nextPart = get_next_part() while '_' in id_2: position, value = nextPart.__next__() id_1.append(position) try: if id_2[int(position)] == '_': id_2[int(position)] = value except: pass return ''.join(id_1[:8]), ''.join(id_2) def get_next_part(): suffix = 0 while True: md5 = hashlib.md5(str.encode(INPUT + str(suffix))).hexdigest() if md5.startswith('0' * ZEROS): yield md5[5], md5[6] suffix += 1 #### Main part. print_results(*compute_ids())
# difference of 100 and the sum of the three preceding ones. possibilities = list(product(range(0, 98), repeat=3)) possibilities = [list(pos) for pos in possibilities if sum(pos) <= 100] for pos in possibilities: pos.append(100 - sum(pos)) # Now go through all combinations. maximum_1 = 0 # Saves the maximum regarding Part One. maximum_2 = 0 # Saves the maximum regarding Part Two. for pos in possibilities: # Calculate the total value of each property. Make sure that there is no # negative entry. value_of_properties = [ max(0, sum(Properties[j][i] * pos[j] for j in range(number_ingredients))) for i in range(NUMBER_PROPERTIES) ] # Multiply these values together. f = prod(value_of_properties) # Part One maximum_1 = max(maximum_1, f) # Part Two calories = sum(Properties[j][4] * pos[j] for j in range(number_ingredients)) if calories == 500: maximum_2 = max(maximum_2, f) print_results(maximum_1, maximum_2)
MARKER_REGEX = re.compile(r'^(\d+)x(\d+)') def get_length(sequence, version_two=False): pos = 0 counter = 0 end_pos = len(sequence) while pos < end_pos: if sequence[pos] is '(': number, factor = MARKER_REGEX.match(sequence[pos+1:]).groups() marker_length = 1 + len(number) + 1 + len(factor) + 1 if version_two: sub_sequence = sequence[ pos + marker_length : pos + marker_length + int(number) ] counter += int(factor) * get_length(sub_sequence, version_two=True) else: counter += int(number) * int(factor) pos += marker_length + int(number) else: counter += 1 pos += 1 return counter #### Main part. sequence = readline(__file__) print_results(get_length(sequence), get_length(sequence, version_two=True))
for w in widths: position = self.position + w.dot(self.rotation) if not self.visitedLocationTwice: self.__is_position_bookmarked(position) self.bookmarks.append(np.copy(position)) self.position = self.bookmarks[-1] def __is_position_bookmarked(self, position): if any((position == p).all() for p in self.bookmarks): self.firstVisitedTwice = np.copy(position) self.visitedLocationTwice = True @staticmethod def get_manhattan_distance(point): return sum(map(abs, point)) #### Main part. instructions = [ m.groups() for m in map(INSTRUCTION_REGEX.match, read(__file__).split(', ')) ] path = Path() for instruction in instructions: path.update_position(*instruction) print_results(Path.get_manhattan_distance(path.position), Path.get_manhattan_distance(path.firstVisitedTwice))
from common import print_results, read def get_message(function, messages): return ''.join(map(lambda x: function(x, key=x.count), messages)) #### Main part. flipped_messages = list(zip(*read(__file__).split())) print_results(get_message(max, flipped_messages), get_message(min, flipped_messages))
REGEX_INPUT = re.compile( r'^Disc #\d+ has (\d+) positions; at time=0, it is at position (\d+).$') def positions_of_discs(time, discs): return map(lambda t: (t[1][1] + time + t[0]) % t[1][0], enumerate(discs, start=1)) def first_possible_start_time(discs, start_time=0): time = start_time while True: if sum(positions_of_discs(time, discs)) == 0: return time time += 1 #### Main part. discs = list( map(lambda line: tuple(map(int, REGEX_INPUT.match(line).groups())), readlines(__file__))) part_1 = first_possible_start_time(discs) part_2 = first_possible_start_time(discs + [ADDITIONAL_DISC], start_time=part_1) print_results(part_1, part_2)
def get_password(self): return ''.join(self.passwort) class ReversedScrambler(Scrambler): INVERSE_ROTATE_POS_TABLE = [(1 + 2 * i + (i >= 4)) % 8 for i in range(8)] def rotate_dir(self, dir, steps): super().rotate_dir('right' if dir == 'left' else 'left', steps) def rotate_pos(self, letter): index = self.passwort.index(letter) diff = index - ReversedScrambler.INVERSE_ROTATE_POS_TABLE.index(index) super().rotate_dir('left', diff if diff >= 0 else 8 + diff) def move(self, x, y): super().move(y, x) #### Main part. rules = readlines(__file__) scrambler = Scrambler(STRING_PART_1) reversed_scrambler = ReversedScrambler(STRING_PART_2) for i in range(len(rules)): scrambler.scramble(rules[i]) reversed_scrambler.scramble(rules[-i - 1]) print_results(scrambler.get_password(), reversed_scrambler.get_password())
find_minimal_quantum_entaglement(packs) else: completed = True return else: return prod(sublists[sublists.index(sl) - 1]) return prod(sublists[-1]) if completed else 'Problem not solvable' weight = sum(packages) // number_boxes min_num = weight // packages[0] + 1 completed = False return find_minimal_quantum_entaglement(packages) def find_shortest_sublist(packs, weight, min_num): while True: sublist = [ s for s in combinations(packs, min_num) if sum(s) == weight ] if sublist == []: min_num += 1 else: return sublist #### Main part. packages = sorted((int(line) for line in readlines(__file__)), reverse=True) print_results(solve_problem(packages, 3), solve_problem(packages, 4))
print('Operation \'{}\' not recognized.'.format(operation)) def __turn_on_rect(self, width, height): self.display[:height, :width] = 1 def __rot_row(self, row, shift): self.display[row, :] = np.roll(self.display[row, :], shift) def __rot_col(self, column, shift): self.display[:, column] = np.roll(self.display[:, column], shift) def count_pixels(self): return sum(sum(self.display)) def get_letters(self): letters = '' for i in range(0, 50, 5): for k, v in Display.LETTERS.items(): if np.array_equal(v, self.display[:, i:i + 5]): letters += k return letters #### Main part. display = Display() for operation in readlines(__file__): display.process_operation(operation) print_results(display.count_pixels(), display.get_letters())
from common import print_results, read def is_triangle(possible_triangle): a, b, c = sorted(possible_triangle) return a + b > c #### Main part. sides = list(map(int, read(__file__).split())) row_triangles = [sides[i:i + 3] for i in range(0, len(sides), 3)] column_triangles = [ sides[i + j:i + j + 7:3] for i in range(0, len(sides), 9) for j in range(3) ] print_results(sum(is_triangle(triangle) for triangle in row_triangles), sum(is_triangle(triangle) for triangle in column_triangles))
from common import print_results, readlines def powerlist(iterable): res_list = [[]] for l in iterable: res_list.extend([subset + [l] for subset in res_list]) return res_list containers = map(int, readlines(__file__)) pos = [len(l) for l in powerlist(containers) if sum(l) == 150] print_results(len(pos), pos.count(min(pos)))