from utils import timed import itertools from aocd import data input = data.split() @timed def part_one(boxes): twice = thrice = 0 for box in boxes: twice += any(box.count(letter) == 2 for letter in box) thrice += any(box.count(letter) == 3 for letter in box) checksum = twice * thrice return checksum @timed def part_one(boxes): """Shorter version, but harder to understand""" f = lambda c: sum(any(b.count(l) == c for l in b) for b in boxes) return f(2) * f(3) @timed def part_two(boxes): for x, y in itertools.combinations(boxes, 2): difference = [i for i, l in enumerate(x) if y[i] != l] if len(difference) == 1: index = difference[0]
import sys from collections import defaultdict from lib import util from queue import Queue from aocd import data, submit lines = data.split('\n') a = util.get_ints(lines[0])[0] b = util.get_ints(lines[1])[0] #a = 65 #b = 8921 af = 16807 bf = 48271 MOD = 2147483647 cnt = 0 for i in range(5000000): a = a * af % MOD while a % 4 != 0: a = a * af % MOD b = b * bf % MOD while b % 8 != 0: b = b * bf % MOD if a & 65535 == b & 65535: cnt += 1 if i % 100000 == 0: print(i) print(cnt)
from aocd import data def unique(phrase): return len(phrase) == len(set(phrase)) def anagram(phrase): return unique(list(map(lambda s: ''.join(sorted(s)), phrase))) phrases = list(map(lambda l: l.split(), data.split('\n'))) print('part 1:', sum(map(unique, phrases))) print('part 2:', sum(map(anagram, phrases)))
yield from check_rules(remaining, rules) def check_rule(word, rule): if isinstance(rule_map[rule], list): for rules in rule_map[rule]: yield from check_rules(word, rules) elif word and word[0] == rule_map[rule]: yield word[1:] def match(word, rule): return any(remaining == '' for remaining in check_rule(word, rule)) rules, messages = data.split('\n\n') rule_map = {} for rule in rules.splitlines(): n, rule = rule.split(':') if '|' in rule: rule = [r.split() for r in rule.split('|')] elif 'a' in rule or 'b' in rule: rule = rule.strip('" ') else: rule = [rule.split()] rule_map[n] = rule messages = messages.splitlines()
def a(): c = (0, 0) for d in data.split(','): dq, dr = dirs[d] c = (c[0] + dq, c[1] + dr) return u.hex_axial_distance(c, (0, 0))
# Setup from aocd import data from collections import Counter as c from functools import reduce as r from operator import mul as m d = data.split('\n') # Longform # answer = reduce( mul, ( sum( ( repetition in count.values() ) for count in ( Counter(box_id) for box_id in data) ) for repetition in (2,3) ) ) # Golfed s=string, h=hash, x=generic number a=r(m,(sum((x in h.values())for h in(c(s)for s in d))for x in(2,3))) # Output print(a)
def ok(n, part="a"): # It is a six-digit number. if not (100_000 <= n <= 999_999): return False # Two adjacent digits are the same. (part a) # ... but not part of a larger group of matching digits (part b) str_n = str(n) for s in "0123456789": if 2 * s in str_n: if part == "a": break elif part == "b" and 3 * s not in str_n: break else: return False # Going from left to right, the digits never decrease for i in range(5): if str_n[i + 1] < str_n[i]: return False return True lo, hi = data.split("-") ns = range(int(lo), int(hi) + 1) print("part a:", sum(ok(n, part="a") for n in ns)) print("part b:", sum(ok(n, part="b") for n in ns))
def parse_data(): return [(x[0], int(x[1:])) for x in input_data.split('\n')]
from aocd import data data = data.split('\n\n') for i in range(len(data)): data[i] = data[i].replace('\n', ' ').strip() passport_information = ["byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"] eyeColor = ["amb", "blu", "brn", "gry", "grn", "hzl", "oth"] def passport_check(passport: dict): required_fields = 0 required_fields = 0 for key in passport_information: if key in passport: required_fields += 1 if required_fields == 7: return True return False def passport_strict(passport): hgt = int(str(0) + passport.get("hgt")[:-2]) cmin = passport.get("hgt")[-2:] if not 1920 <= int(passport.get("byr")) <= 2002: return False if not 2010 <= int(passport.get("iyr")) <= 2020: return False if not 2020 <= int(passport.get("eyr")) <= 2030: return False if passport.get("ecl") not in eyeColor: return False
""" --- Day 2: Inventory Management System --- https://adventofcode.com/2018/day/2 """ from collections import Counter from itertools import combinations from aocd import data counters = [Counter(s) for s in data.split()] doubles = sum(1 for c in counters if 2 in c.values()) triples = sum(1 for c in counters if 3 in c.values()) print("part a:", doubles * triples) for a, b in combinations(data.split(), 2): s = "".join([x for x, y in zip(a, b) if x == y]) if len(s) == len(a) - 1: print("part b:", s) break
def parse_data(): return [d.split(')') for d in input_data.split('\n')]
if prev_node[0][0] == "COM": #this is the origin node return ["COM", object] else: return pathmapper(orbit_list, prev_node[0][0]) + [object] def node_dist(path, node_1, node_2): """ Calculates distance between node1 and node2 :param path: list of nodes in order :param node_1: :param node_2: :return: distance between two nodes """ index_1 = path.index(node_1) index_2 = path.index(node_2) distance = abs(index_1 - index_2) return distance if __name__ == "__main__": test_ls = test2_str.split("\n") #split_ls=[x.split(")") for x in test_ls] #orbit_map_counter(split_ls) data_ls = data.split("\n") split_ls = [x.split(")") for x in data_ls] #count=orbit_map_counter(split_ls) distance = transfer_calc(split_ls, "YOU", "SAN") print("foo")
# solution from reddit user i_have_no_biscuits from time import perf_counter from aocd import data data18 = data.split('\n') KEYS = "abcdefghijklmnopqrstuvwxyz" # Part 1 plan: # ------------ # Do (letters +1) BFS's, finding the distances between each pair of keys # (and between the keys and the starting point), recording for each # destination key the doors and keys that you pass through on the way. # # Then do a breadth first memoized walk through the different ways to # collect keys - for each key keeping track of the distance taken to get # there. At the end we will have a shortest distance to all keys. # # It worked! # Performs a BFS from a given source point to all reachable points of interest def distances_from(source, data): sx, sy = source visited = set([(sx, sy)]) queue = [(sx, sy, 0, "")] routeinfo = {} for (x, y, dist, route) in queue: contents = data[y][x] if contents not in ".@1234#" and dist > 0:
def part_a(data): return sum([int(x) for x in data.split()])
def part_a(data): counters = [Counter(s) for s in data.split()] doubles = sum(1 for c in counters if 2 in c.values()) triples = sum(1 for c in counters if 3 in c.values()) return doubles * triples
def process_data(): return [group for group in data.split("\n\n")]
def parse_data(): return [int(x) for x in input_data.split(',')]
def parse_data(): return [x.replace(' ', '') for x in input_data.split('\n')]
template_first = """\ Begin in state {state0}. Perform a diagnostic checksum after {n:d} steps.""" template_rest = """\ In state {state_current}: If the current value is 0: - Write the value {val0:d}. - Move one slot to the {direction0}. - Continue with state {state0}. If the current value is 1: - Write the value {val1:d}. - Move one slot to the {direction1}. - Continue with state {state1}.""" first, *rest = data.split("\n\n") prog = parse(template_first, first).named directions = {"right": 1, "left": -1} for text in rest: data = parse(template_rest, text).named prog[data["state_current"]] = { 0: (directions[data["direction0"]], data["val0"], data["state0"]), 1: (directions[data["direction1"]], data["val1"], data["state1"]), } tape = defaultdict(int) cursor = 0 state = prog["state0"] for i in range(prog["n"]): instructions = prog[state] val = tape[cursor]
:param min: minimum number to consider :param max: maximum number to consider :return: number of passwords found within the range """ if max - min == 1: #two numbers are adjacent return sum([password_test2(min), password_test2(max)]) elif max - min == 2: #three numbers in range return sum([ password_test2(min), password_test2(max - 1), password_test2(max) ]) else: mid = (max - min) // 2 + min return sum( [password_counter(min, mid), password_counter(mid + 1, max)]) if __name__ == "__main__": """Part 1""" #test for password in TEST_ls: print("{} {}".format(password, password_test(password))) #data number_range = data.split("-") min = int(number_range[0]) max = int(number_range[1]) password_test2(168688) num_pass = password_counter(min, max) print(num_pass)
def get_input(): return [group.split("\n") for group in data.split("\n\n")]
import re from collections import defaultdict from itertools import combinations, product from aocd import data tiles = defaultdict(dict) for tile in data.split('\n\n'): tile_id, image = tile.split('\n', 1) tile_id = int(re.search(r'(\d+)', tile_id)[1]) L = '' # Left R = '' # Right T = '' # Top B = '' # Bottom for y, row in enumerate(image.splitlines()): for x, pixel in enumerate(row): tiles[tile_id][(x, y)] = pixel if y == 0: T += pixel elif y == 9: B += pixel if x == 0: L += pixel elif x == 9: R += pixel tiles[tile_id]['T'] = (hash(T), hash(T[::-1])) tiles[tile_id]['B'] = (hash(B), hash(B[::-1])) tiles[tile_id]['L'] = (hash(L), hash(L[::-1]))
monster = [ " # ", "# ## ## ###", " # # # # # # ", ] print(f"File line count: {len(lines)}") def rstr(s): return "".join(reversed(s)) tiles = {} ts = data.split("\n\n") for t in ts: tid, *rest = t.splitlines() tid = u.ints(tid)[0] tiles[tid] = tuple(rest) def rot(tile): r = [] for i in range(len(tile)): r.append("".join(x[i] for x in tile)) return tuple(reversed(r)) BorderList = namedtuple("Borrderlist", ["top", "left", "bottom", "right"])
def part_a(data): samples = data.split("\n" * 4)[0].split("\n" * 2) result = sum(1 for s in samples if len(choices(s)) >= 3) return result
from aocd import data data = [x.strip() for x in data.split('\n\n')] anyone = 0 everyone = 0 for i in range(len(data)): anyone += len(set(data[i].replace('\n', ''))) alls = data[i].split('\n') sets = set(alls[0]) for i in range(len(alls)): sets = sets.intersection(set(alls[i])) everyone += len(sets) print(anyone) print(everyone)
from aocd import data def part_1(data): twos = 0 threes = 0 for input in data: counter = Counter(input) for occurency in set(counter.values()): if occurency == 2: twos += 1 if occurency == 3: threes += 1 return twos * threes def part_2(data): most_chars = [] for a, b in permutations(data, 2): new_chars = [a[i] for i in range(len(a)) if a[i] == b[i]] if len(new_chars) > len(most_chars): most_chars = new_chars return most_chars if __name__ == '__main__': data = data.split() print(f"Part 1: {part_1(data)}") print(f"Part 2: {''.join(part_2(data))}")
# Setup from aocd import data from datetime import datetime from re import match from collections import defaultdict, Counter from itertools import chain d = { datetime.strptime(time, '%Y-%m-%d %H:%M'): True if event == 'falls asleep' else False if event == 'wakes up' else int( match(r'.*#(\d+) .*', event).group(1)) for time, event in (match(r'\[(.+)\] (.+)', entry).groups() for entry in data.split('\n')) } # Longform naps_per_guard = defaultdict(list) for time, event in sorted(d.items()): if type(event) is int: guard = event elif event: start = time else: naps_per_guard[guard].append((start.minute, time.minute)) total_naptime_per_guard = { guard: sum(b - a for a, b in naps) for guard, naps in naps_per_guard.items() } sleepiest_guard = max(total_naptime_per_guard, key=total_naptime_per_guard.get) a = Counter( chain(*(range(start, end) for start, end in naps_per_guard[sleepiest_guard] ))).most_common(1)[0][0] * sleepiest_guard
def part_b(data): for a, b in combinations(data.split(), 2): s = "".join([x for x, y in zip(a, b) if x == y]) if len(s) == len(a) - 1: return s
""" --- Day 7: The Treachery of Whales --- https://adventofcode.com/2021/day/7 """ from aocd import data import numpy as np A = np.array([int(n) for n in data.split(",")]) a = b = np.inf for n in range(A.min(), A.max()): d = abs(A - n) a = min(a, d.sum()) b = min(b, (d * (d + 1) // 2).sum()) print("part a:", a) print("part b:", b)
""" --- Day 25: Let It Snow --- https://adventofcode.com/2015/day/25 """ from aocd import data words = data.split() row = int(words[-3].rstrip(",")) col = int(words[-1].rstrip(".")) def n(row, col): i = (row + col) * (row + col) + 2 - col - 3 * row return i // 2 m = 252533 d = 33554393 i = n(row, col) code = 20151125 for _ in range(1, i): code = m * code % d print(code)