import matrix import shared import itertools import functools def is_increasing(sequence): return all(sequence[i] < sequence[i+1] for i in range(len(sequence) - 1)) def is_decreasing(sequence): return all(sequence[i] > sequence[i+1] for i in range(len(sequence) - 1)) def parse_line(row): diffs = [] for previous, current in zip(row, row[1:]): diff = current - previous diffs.append(diff) diff = abs(diff) if diff >= 1 and diff <= 3: continue return 0, diffs if not(is_increasing(row) or is_decreasing(row)): return 0, diffs return 1, diffs # @shared.profile def part1(rows): rows = [list(map(int, row.split())) for row in rows] safe = 0 for row in rows: check, _ = parse_line(row) safe += check print(safe) def remove_tolerance(row, diffs): mdiff = max(map(abs, diffs)) try: idx = diffs.index(mdiff) except ValueError: idx = diffs.index(-1 * mdiff) row.pop(idx) return row # @shared.profile def part2(rows): rows = [list(map(int, row.split())) for row in rows] safe = 0 for row in rows: check, diffs = parse_line(row) if check == 0: row = remove_tolerance(row, diffs) check, _ = parse_line(row) safe += check print(safe) def main(): rows = [row for row in shared.load_rows(2)] with shared.elapsed_timer() as elapsed: part1(rows) print("🕒", elapsed()) rows = [row for row in shared.load_rows(2, True)] with shared.elapsed_timer() as elapsed: part2(rows) print(706, 754) print("🕒", elapsed()) if __name__ == "__main__": main()