2024-12-02 - Red-Nosed Reports
(original .ipynb)
Day 2 puzzle input is a list of sequences of integers which represent a series of level readings mine is here). Part 1 involves determining how series of readings (lines of input) are "safe" (no reading is any other than 1-3 higher or lower than the previous, and readings are only ever increasing or decreasing). Part 2 involves doing the same but if removing any one element causes the series to satisfy the rules.
puzzle_input_str = open("./puzzle_input/day2.txt").read() test_input_str = """7 6 4 2 1 1 2 7 8 9 9 7 6 2 1 1 3 2 4 5 8 6 4 4 1 1 3 6 7 9""" def pairwise(iterable): # need to upgrade Python on server, no pairwise in 3.9 :-O iterator = iter(iterable) a = next(iterator, None) for b in iterator: yield a, b a = b def parse_line(line_str): return [int(s) for s in line_str.split(" ")] def valid_report(report): level_differences = [x-y for x,y in pairwise(report)] all_valid = all(abs(diff) >= 1 and abs(diff) <= 3 for diff in level_differences) all_increasing = all(diff > 0 for diff in level_differences) all_decreasing = all(diff < 0 for diff in level_differences) return all_valid and (all_increasing or all_decreasing) def part_one(input_str): reports = [parse_line(line) for line in input_str.splitlines()] valid_reports = [report for report in reports if valid_report(report)] return len(valid_reports) assert 2 == part_one(test_input_str) print("part one:", part_one(puzzle_input_str))
part one: 559
def potentially_valid_report(report): for i in range(len(report)): if valid_report(report[:i] + report[i+1:]): return True return False def part_two(input_str): reports = [parse_line(line) for line in input_str.splitlines()] valid_reports = [report for report in reports if potentially_valid_report(report)] return len(valid_reports) assert 4 == part_two(test_input_str) print("part two:", part_two(puzzle_input_str))
part two: 601