Skip to content

Commit

Permalink
Solutions day 7 and 8 from 2024 (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
mkopec87 authored Dec 9, 2024
1 parent d2d533b commit 0d5ff15
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 0 deletions.
59 changes: 59 additions & 0 deletions src/2024/07/2024_07.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import dataclasses
import operator
from itertools import product
from typing import List

from src.utils.data import load_data
from src.utils.submission import submit_or_print


@dataclasses.dataclass
class Equation:
target: int
values: List[int]

def possible(self, operators):
for combination in product(operators, repeat=len(self.values) - 1):
current = self.values[0]
for i, op in enumerate(combination, start=1):
current = op(current, self.values[i])
if current > self.target:
break
if current == self.target:
return True
return False


def main(debug: bool) -> None:
input_data = load_data(debug)

equations = parse_input(input_data)

# part 1
operators = [operator.add, operator.mul]
result_part1 = sum([e.target for e in equations if e.possible(operators)])

# part 2
def concat(a, b):
return int(str(a) + str(b))

operators = [operator.add, operator.mul, concat]
result_part2 = sum([e.target for e in equations if e.possible(operators)])

submit_or_print(result_part1, result_part2, debug)


def parse_input(input_data: str) -> List[Equation]:
equations = []
for line in input_data.splitlines():
s = line.split(":")
target = int(s[0])
values = [int(v) for v in s[1].strip().split(" ")]
equations.append(Equation(target=target, values=values))
return equations


if __name__ == "__main__":
debug_mode = True
# debug_mode = False
main(debug_mode)
6 changes: 6 additions & 0 deletions src/2024/07/sample_input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
1: 1
7: 99 11
123: 1 3 56
99: 11 1 9
100: 10 10 80
1090: 10 10 80
100 changes: 100 additions & 0 deletions src/2024/08/2024_08.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import dataclasses
import math
from collections import defaultdict
from itertools import combinations
from typing import Dict, Set, Tuple

from src.utils.data import load_data
from src.utils.submission import submit_or_print


@dataclasses.dataclass
class Point:
x: int
y: int

def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)

def __sub__(self, other):
return Point(self.x - other.x, self.y - other.y)

def __hash__(self):
return hash(tuple([self.x, self.y]))

def __eq__(self, other: "Point"):
return (self.x == other.x) and (self.y == other.y)

def direction(self):
gcd = math.gcd(self.x, self.y)
return Point(self.x // gcd, self.y // gcd)

def within_bounds(self, shape):
return 0 <= self.x < shape.x and 0 <= self.y < shape.y


def main(debug: bool) -> None:
input_data = load_data(debug)

letter_to_antennas, shape = parse_input(input_data)

antinodes = antinodes_part1(letter_to_antennas, shape)
result_part1 = len(antinodes)

antinodes = antinodes_part2(letter_to_antennas, shape)
result_part2 = len(antinodes)

submit_or_print(result_part1, result_part2, debug)


def parse_input(input_data: str) -> Tuple[Dict[str, Set[Point]], Point]:
letter_to_antennas = defaultdict(set)
lines = input_data.splitlines()
for x, line in enumerate(lines):
for y, ch in enumerate(line):
if ch != ".":
letter_to_antennas[ch].add(Point(x, y))
shape = Point(len(lines), len(lines[0]))
return letter_to_antennas, shape


def antinodes_part1(
letter_to_antennas: Dict[str, Set[Point]], shape: Point
) -> Set[Point]:
antinodes = set()
for letter, antennas in letter_to_antennas.items():
for antenna1, antenna2 in combinations(antennas, 2):
diff = antenna1 - antenna2
resonance1 = antenna2 - diff
resonance2 = antenna1 + diff
for p in [resonance1, resonance2]:
if p.within_bounds(shape):
antinodes.add(p)
return antinodes


def antinodes_part2(
letter_to_antennas: Dict[str, Set[Point]], shape: Point
) -> Set[Point]:
antinodes = set()
for letter, antennas in letter_to_antennas.items():
for antenna1, antenna2 in combinations(antennas, 2):
diff = (antenna1 - antenna2).direction()

p = antenna1
while p.within_bounds(shape):
antinodes.add(p)
p = p + diff

p = antenna1
while p.within_bounds(shape):
antinodes.add(p)
p = p - diff

return antinodes


if __name__ == "__main__":
debug_mode = True
# debug_mode = False
main(debug_mode)
4 changes: 4 additions & 0 deletions src/2024/08/sample_input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
............
...a....A...
.....A......
.......00...

0 comments on commit 0d5ff15

Please sign in to comment.