diff --git a/day6/data.py b/day6/data.py new file mode 100644 index 0000000..c51b918 --- /dev/null +++ b/day6/data.py @@ -0,0 +1,13 @@ +from dataclasses import dataclass + + +@dataclass +class Race: + time: int + record: int + + def length_for_button_press(self, duration: int) -> int: + length = 0 + for i in range(duration, self.time): + length += duration + return length diff --git a/day6/part1.py b/day6/part1.py new file mode 100755 index 0000000..3fb039d --- /dev/null +++ b/day6/part1.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3.11 +import math +import re +from typing import List + +from data import Race + + +def extract(input_file: str) -> List[Race]: + races = [] + with open(input_file) as input: + times = re.match("Time:((?:\s+\d+)+)", input.readline()) + times = list(map(int, re.split("\s+", times.group(1).lstrip()))) + distances = re.match("Distance:((?:\s+\d+)+)", input.readline()) + distances = list(map(int, re.split("\s+", distances.group(1).lstrip()))) + if len(times) == len(distances): + for idx in range(len(times)): + r = Race(time=times[idx], record=distances[idx]) + races.append(r) + else: + raise Exception("Times and Distances are not the same length") + return races + + +input_file = "input.txt" +races = extract(input_file) +record_beatings = [0 for r in races] + + +for idx, race in enumerate(races): + lengths = [] + for i in range(race.time): + lengths.append(race.length_for_button_press(i)) + record_beatings[idx] = len(list(filter(lambda length: length > race.record, lengths))) +print(record_beatings) +print(math.prod(record_beatings)) diff --git a/day6/part2.py b/day6/part2.py new file mode 100755 index 0000000..5406b10 --- /dev/null +++ b/day6/part2.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3.11 +import re +from data import Race + + +def extract(input_file: str) -> Race: + with open(input_file) as input: + time = re.match("Time: ((?:\s+\d+)+)", input.readline()) + time = int(re.sub("\s+", "", time.group(1))) + distance = re.match("Distance: ((?:\s+\d+)+)", input.readline()) + distance = int(re.sub("\s+", "", distance.group(1))) + return Race(time=time, record=distance) + + +def find_boundary(race: Race, start: int, end: int, nrange: int, reverse: bool = False) -> int: + print(race, start, end, nrange, reverse) + step = nrange if not reverse else -nrange + if nrange == 1: + for i in range(start, end + 1, step): + if race.length_for_button_press(i) > race.record: + return i + boundary = start + for i in range(start, end + 1, step): + boundary = i + if race.length_for_button_press(i) > race.record: + return find_boundary(race, boundary - step, boundary, int(nrange / 10), reverse) + + +input_file = "input.txt" +race = extract(input_file) + +start = end = 0 +step = 1 +while step < race.time: + step *= 10 +step /= 10 +print(step) +start = find_boundary(race, 0, race.time, int(step)) +print(start) +end = find_boundary(race, race.time, start, int(step), True) + + +print(end - start + 1)