def test_load_input(): filepath = Path(__file__).parent / "sample_input_1.txt" expected = [ ("mask", "", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X"), ("mem", "8", "11"), ("mem", "7", "101"), ("mem", "8", "0"), ] assert load_input(filepath) == expected
def test_load_input(): filepath = Path(__file__).parent / "sample_input.txt" expected = [ Password(PasswordPolicy(1, 3, "a"), "asdf"), Password(PasswordPolicy(2, 5, "b"), "aaabbbbaaab"), Password(PasswordPolicy(2, 4, "c"), "accca"), Password(PasswordPolicy(1, 2, "d"), "ghjkl"), ] assert load_input(filepath) == expected
def test_load_input(): expected = { "start": {"A", "b"}, "A": {"b", "c", "end", "start"}, "b": {"A", "d", "end", "start"}, "c": {"A"}, "d": {"b"}, "end": {"A", "b"}, } assert load_input("sample_input.txt") == expected
def test_step(self): filepath = Path(__file__).parent / "sample_input.txt" layout = load_input(filepath) sim = SeatingSimulation(layout) expected = [ "#.##.##.##", "#######.##", "#.#.#..#..", "####.##.##", "#.##.##.##", "#.#####.##", "..#.#.....", "##########", "#.######.#", "#.#####.##", ] expected = [list(string) for string in expected] sim.step() assert sim.current == expected
def test_load_input(): sample_path = Path(__file__).parent / "sample_input_1.txt" expected_rules = Rules( { 0: "4 1 5", 1: "2 3 | 3 2", 2: "4 4 | 5 5", 3: "4 5 | 5 4", 4: '"a"', 5: '"b"', } ) expected_cases = [ "ababbb", "bababa", "abbbab", "aaabbb", "aaaabbb", ] expected = (expected_rules, expected_cases) assert load_input(sample_path) == expected
for b_move in possible_three_rolls: possible_b_space = simplify(b_space + sum(b_move)) possible_b_score = b_score + possible_b_space if possible_b_score >= max_score: b_wins += 1 else: sub_a_wins, sub_b_wins = play( a_space, possible_b_space, a_score, possible_b_score, next_move, max_score, ) a_wins += sub_a_wins b_wins += sub_b_wins else: print("Next move var invalid") return a_wins, b_wins if __name__ == "__main__": p1_start, p2_start = load_input() a_wins, b_wins = play(p1_start, p2_start) winner = max({ "A": a_wins, "B": b_wins }.items(), key=lambda item: item[1])[0] print(f"A wins {a_wins}, B wins {b_wins}, {winner} wins the most") print(f"Answer is {max(a_wins, b_wins)}")
y: int, character: str, ) -> int: to_check = product([-1, 0, 1], [-1, 0, 1]) count = 0 max_x = len(layout[0]) - 1 max_y = len(layout) - 1 for dx, dy in to_check: if dx == 0 and dy == 0: continue x2 = x y2 = y while True: x2 = x2 + dx y2 = y2 + dy if x2 < 0 or y2 < 0 or x2 > max_x or y2 > max_y: break elif layout[y2][x2] == character: count += 1 break elif layout[y2][x2] == "L": break return count if __name__ == "__main__": filepath = Path(__file__).parent / "input.txt" layout = load_input(filepath) sim = SeatingSimulation(layout) print(sim.run())
from part1 import load_input, parse_input def most_asleep_on_same_minute(guards): guard_id = None guard_minute_count = 0 guard_sleepiest_minute = 0 for guard in guards: minute, sleep_count = sleepiest_minute(guards[guard]) if sleep_count > guard_minute_count: guard_minute_count = sleep_count guard_id = guard guard_sleepiest_minute = minute return guard_id, guard_sleepiest_minute def sleepiest_minute(guard): count = [0] * 60 for shift in guard.keys(): for minute in range(len(count)): if guard[shift][minute]: count[minute] += 1 return count.index(max(count)), count[count.index(max(count))] if __name__ == '__main__': guards = parse_input(load_input()) guard_id, minute = most_asleep_on_same_minute(guards) print(guard_id * minute)
allergen_candidates[allergen_2].discard(candidate) updated = True break if not updated: raise NotImplementedError return answers if __name__ == "__main__": SAMPLE_INPUT = [ FoodEntry({"mxmxvkd", "kfcds", "sqjhc", "nhms"}, {"dairy", "fish"}), FoodEntry({"trh", "fvjkl", "sbzzf", "mxmxvkd"}, {"dairy"}), FoodEntry({"sqjhc", "fvjkl"}, {"soy"}), FoodEntry({"sqjhc", "mxmxvkd", "sbzzf"}, {"fish"}), ] from datetime import datetime start = datetime.now() filepath = Path(__file__).parent / "input.txt" strs = load_input(filepath) # strs = SAMPLE_INPUT allergens = resolve_allergens(strs) answer = ",".join( map(lambda x: x[1], sorted(list(allergens.items()), key=lambda x: x[0]))) end = datetime.now() time = (end - start).total_seconds() print(time) print(allergens) print(answer)
from typing import Iterable, Tuple from part1 import load_input def calculate_endpoint( instructions: Iterable[Tuple[str, int]], start: Tuple[int, int, int] = (0, 0, 0) ) -> Tuple[int, int, int]: x, y, aim = start for direction, number in instructions: if direction == "forward": x += number y += number * aim elif direction == "down": aim -= number elif direction == "up": aim += number else: raise ValueError(f"Direction not recognised: {direction}") return x, y, aim if __name__ == "__main__": instructions = load_input() x, y, aim = calculate_endpoint(instructions) print(x * -1 * y)
from __future__ import annotations from itertools import permutations from part1 import load_input, magnitude, SFNumber, snail_sum def find_max_pair_sum(numbers: list[SFNumber]) -> int: max_ = 0 for pair in permutations(numbers, 2): max_ = max(max_, magnitude(snail_sum(pair))) return max_ if __name__ == "__main__": numbers = load_input() print(find_max_pair_sum(numbers))
from functools import reduce import operator from pathlib import Path from typing import List, Tuple from part1 import load_input, TobogganMap def multiply_collisions(map_: TobogganMap, vectors: List[Tuple[int, int]]) -> int: collision_counts = map(lambda vector: map_.traverse(vector), vectors) return reduce(operator.mul, collision_counts, 1) if __name__ == "__main__": filepath = Path(__file__).parent / "input.txt" map_ = TobogganMap(load_input(filepath)) cases = [ (1, 1), (3, 1), (5, 1), (7, 1), (1, 2), ] print(multiply_collisions(map_, cases))
from collections import namedtuple from typing import List, Optional from part1 import load_input, Parser InputTuple = namedtuple("InputTuple", "noun, verb") def find_inputs(program: List[str], target_value: str) -> Optional[InputTuple]: for noun in range(100): for verb in range(100): custom_program = program.copy() custom_program[1] = noun custom_program[2] = verb parser = Parser(custom_program) parser.execute() output = parser.program[0] if output == target: return InputTuple(noun, verb) return None if __name__ == "__main__": program = load_input() target = "19690720" inputs = find_inputs(program, target) if inputs is None: print("No input found for target") else: print(100 * inputs.noun + inputs.verb)
coordinate_set = [] for y in range(y_size): for x in range(x_size): coordinate_set.append((x + x_pos, y + y_pos)) return coordinate_set def populate_grid(claims_data): for claim in claims_data.keys(): for coordinates in claims_data[claim]: grid[coordinates[1]][coordinates[0]].append(claim) def check_claims(claims_data): for k in claims_data.keys(): overlapped = False for coordinates in claims_data[k]: if len(grid[coordinates[1]][coordinates[0]]) > 1: overlapped = True break if overlapped == False: return k if __name__ == '__main__': data = part1.load_input() grid = [[[] for _ in range(1000)] for _ in range(1000)] claims_data = parse_claims(data) populate_grid(claims_data) print(check_claims(claims_data))
#! python3 import part1 if __name__ == '__main__': data = part1.load_input('day_2_input') testword_list = [] #for entry in data for entry in range(len(data)): #loop through every iteration of it #put them in a dict testwords = [] for x in range(len(data[entry])): testwords.append(data[entry][:x] + data[entry][x + 1:]) testword_list.append(testwords) for lst in range(len(testword_list)): for word in testword_list[lst]: for ex in range(lst + 1, len(testword_list)): if word in testword_list[ex]: print(word)
def test_run(self): filepath = Path(__file__).parent / "sample_input.txt" layout = load_input(filepath) sim = SeatingSimulation(layout) assert sim.run() == 37
from __future__ import annotations from part1 import load_input, step def find_sync_step(grid: list[list[int]], max_steps: int = 1000) -> int: for i in range(max_steps): grid, flashes = step(grid) if flashes == len(grid) * len(grid[0]): return i + 1 raise ValueError(f"Sync point not found within {max_steps} steps") if __name__ == "__main__": grid = load_input() sync_point = find_sync_step(grid, 1000) print(sync_point)
from collections import defaultdict from itertools import product from part1 import count_dangerous_areas, load_input, Line2D, Point2D def map_vent_density_full(lines: list[Line2D]) -> dict[Point2D, int]: vent_count: dict[Point2D, int] = defaultdict(lambda: 0) for line in lines: x_step = 1 if line.start.x <= line.end.x else -1 y_step = 1 if line.start.y <= line.end.y else -1 x_values = range(line.start.x, line.end.x + x_step, x_step) y_values = range(line.start.y, line.end.y + y_step, y_step) if line.is_diagonal: for x, y in zip(x_values, y_values): vent_count[Point2D(x, y)] += 1 else: for x, y in product(x_values, y_values): vent_count[Point2D(x, y)] += 1 return vent_count if __name__ == "__main__": lines = load_input() vents = map_vent_density_full(lines) danger_count = count_dangerous_areas(vents) print(danger_count)
def test_count_valid_passwords_sample_data(): passwords = load_input(Path("sample_input.txt")) assert count_valid_passwords(passwords) == 3
last = next_ return pairs def get_freqs_after_steps(template: list[str], recipes: dict[tuple[str, str], str], steps: int) -> dict[str, int]: pairs: dict[tuple[str, str], int] = to_pairs(template) first = template[0] for _ in range(steps): pairs = step_pairs(pairs, recipes) freqs: dict[str, int] = DefaultDict(lambda: 0) # To avoid counting twice, only count right item # Count first item on its own as this will only be on the left freqs[first] += 1 for (_, b), count in pairs.items(): freqs[b] += count return freqs if __name__ == "__main__": from datetime import datetime start = datetime.now() template, recipes = load_input() freqs = get_freqs_after_steps(template, recipes, 40) print(max(freqs.values()) - min(freqs.values())) end = datetime.now() print((end - start).total_seconds())
""" def simplify_risk(x): while x > 9: x -= 9 return x grid = [] for y in range(len(tile) * 5): y_tile = y // len(tile) source_y = y % len(tile) row = [] for x_tile in range(5): x_segment = [simplify_risk(x + x_tile + y_tile) for x in tile[source_y]] row.extend(x_segment) grid.append(row) return grid if __name__ == "__main__": from datetime import datetime start = datetime.now() tile = load_input() grid = generate_grid(tile) length = find_shortest_path(grid, 1000000) end = datetime.now() print(length) print((end - start).total_seconds())
current = "start" visited.append("start") for option in paths[current]: if option == "end": new_visited = visited.copy() new_visited.append("end") routes.append(new_visited) elif option == "start": continue elif second_small_used and option == option.lower( ) and option in visited: continue else: if option == option.lower() and option in visited: new_second_small_used = True else: new_second_small_used = second_small_used new_visited = visited.copy() new_visited.append(option) routes.extend( find_routes(paths, option, new_visited, new_second_small_used)) return routes if __name__ == "__main__": map_ = load_input() routes = find_routes(map_) print(len(routes))
from part1 import calc_minute_sleep_frequencies, load_input def list_guards(logs: List[Tuple[datetime, str]]) -> Set[str]: guards = set() for _, text in logs: shift_start_match = re.match(r"Guard (?P<guard>\S*) begins shift", text) if shift_start_match: guards.add(shift_start_match.groupdict()["guard"]) return guards if __name__ == "__main__": # filename = "input_sample.txt" filename = "input.txt" logs = load_input(filename) guards = list_guards(logs) # Dict of guard to (minute, times slept) guard_most_slept_minute: Dict[str, Tuple[int, int]] = {} for guard in guards: freqs = calc_minute_sleep_frequencies(logs, guard) guard_most_slept_minute[guard] = max(freqs.items(), key=lambda item: item[1]) most_common_guard_minute = max(guard_most_slept_minute.items(), key=lambda item: item[1][1]) guard, (minute, count) = most_common_guard_minute print( f"Guard {guard}, minute {minute}, times {count}. Answer {int(guard[1:])*minute}" )
def most_common(numbers: List[str]) -> str: count: Dict[str, int] = {} for number in numbers: count[number] = count.get(number, 0) + 1 return "1" if count.get("1", 0) >= count.get("0", 0) else "0" def calc_oxygen_rating(numbers: List[str]) -> str: return filter_numbers(numbers, most_common) def calculate_co2_rating(numbers: List[str]) -> str: def least_common(numbers: List[str]) -> str: count: Dict[str, int] = {} for number in numbers: count[number] = count.get(number, 0) + 1 return "0" if count.get("0", 0) <= count.get("1", 0) else "1" return filter_numbers(numbers, least_common) if __name__ == "__main__": input_ = load_input() oxygen_str = calc_oxygen_rating(input_) co2_string = calculate_co2_rating(input_) print(oxygen_str, co2_string) print(int(oxygen_str, 2), int(co2_string, 2)) print(int(oxygen_str, 2) * int(co2_string, 2))
elif type_ == 3: # Maximum return max(values) elif type_ == 5: # Greater than if values[0] > values[1]: return 1 return 0 elif type_ == 6: # Less than if values[0] < values[1]: return 1 return 0 elif type_ == 7: # Equal to if values[0] == values[1]: return 1 return 0 else: raise ValueError("Unrecognised/unexpected packet type") else: raise ValueError("Unrecognised packet type") if __name__ == "__main__": hex_str = load_input() bin_str = hexes_to_bin(hex_str) packets = split_packets(bin_str) answer = evaluate_packet(packets[0]) print(answer)