2023.03
This commit is contained in:
parent
514cbc2dfd
commit
366efe0b0d
3 changed files with 144 additions and 0 deletions
1
challenges/2023/03-gearRatios/README.md
Normal file
1
challenges/2023/03-gearRatios/README.md
Normal file
|
@ -0,0 +1 @@
|
|||
# [Day 3: Gear Ratios](https://adventofcode.com/2023/day/3)
|
135
challenges/2023/03-gearRatios/main.py
Normal file
135
challenges/2023/03-gearRatios/main.py
Normal file
|
@ -0,0 +1,135 @@
|
|||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def _debug(*args, **kwargs):
|
||||
kwargs["file"] = sys.stderr
|
||||
print(*args, **kwargs)
|
||||
|
||||
|
||||
Coordinate = tuple[int, int]
|
||||
Schematic = dict[Coordinate, str]
|
||||
|
||||
|
||||
def parse(instr: str) -> Schematic:
|
||||
res = {}
|
||||
|
||||
lines = instr.splitlines()
|
||||
max_x = len(lines[0])
|
||||
|
||||
for row_n, row in enumerate(lines):
|
||||
assert len(row) == max_x
|
||||
for col_n, char in enumerate(row):
|
||||
res[(col_n, row_n)] = char
|
||||
|
||||
return res
|
||||
|
||||
|
||||
DIRECTIONS = [(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1)]
|
||||
|
||||
|
||||
def apply_coord_delta(c: Coordinate, d: Coordinate) -> Coordinate:
|
||||
a, b = c
|
||||
e, f = d
|
||||
return a + e, b + f
|
||||
|
||||
|
||||
def seek_digits(
|
||||
sc: Schematic, start: Coordinate, delta: Coordinate
|
||||
) -> tuple[str, set[Coordinate]]:
|
||||
digits = ""
|
||||
coords = set()
|
||||
|
||||
cursor = start
|
||||
while True:
|
||||
cursor = apply_coord_delta(cursor, delta)
|
||||
val = sc.get(cursor, ".")
|
||||
if not val.isdigit():
|
||||
break
|
||||
coords.add(cursor)
|
||||
digits += val
|
||||
|
||||
return digits, coords
|
||||
|
||||
|
||||
def collect_digits_around(
|
||||
sc: Schematic, start: Coordinate
|
||||
) -> tuple[int, set[Coordinate]]:
|
||||
backward_digits, backward_coords = seek_digits(sc, start, (-1, 0))
|
||||
forward_digits, forward_coords = seek_digits(sc, start, (1, 0))
|
||||
|
||||
return (
|
||||
int("".join(reversed(backward_digits)) + sc[start] + forward_digits),
|
||||
backward_coords | forward_coords | set((start,)),
|
||||
)
|
||||
|
||||
|
||||
def one(inp: str):
|
||||
schematic = parse(inp)
|
||||
|
||||
consumed_numbers = set()
|
||||
acc = 0
|
||||
|
||||
for coord in schematic:
|
||||
if coord in consumed_numbers:
|
||||
continue
|
||||
|
||||
char = schematic[coord]
|
||||
|
||||
if not char.isdigit():
|
||||
continue
|
||||
|
||||
is_part_number = False
|
||||
for delta in DIRECTIONS:
|
||||
target = schematic.get(apply_coord_delta(coord, delta), ".")
|
||||
if not (target.isdigit() or target == "."):
|
||||
is_part_number = True
|
||||
break
|
||||
|
||||
if is_part_number:
|
||||
n, used_coords = collect_digits_around(schematic, coord)
|
||||
consumed_numbers = consumed_numbers | used_coords
|
||||
acc += int(n)
|
||||
|
||||
return acc
|
||||
|
||||
|
||||
def two(inp: str):
|
||||
schematic = parse(inp)
|
||||
acc = 0
|
||||
|
||||
for coord in schematic:
|
||||
char = schematic[coord]
|
||||
|
||||
if char != "*":
|
||||
continue
|
||||
|
||||
consumed_numbers = set()
|
||||
numbers = []
|
||||
|
||||
for delta in DIRECTIONS:
|
||||
test_coord = apply_coord_delta(coord, delta)
|
||||
if test_coord in consumed_numbers:
|
||||
continue
|
||||
if schematic.get(test_coord, ".").isdigit():
|
||||
n, c = collect_digits_around(schematic, test_coord)
|
||||
consumed_numbers = consumed_numbers | c
|
||||
numbers.append(n)
|
||||
|
||||
if len(numbers) == 2:
|
||||
# is gear!
|
||||
x, y = numbers
|
||||
acc += x * y
|
||||
|
||||
return acc
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2 or sys.argv[1] not in ["1", "2"]:
|
||||
print("Missing day argument", file=sys.stderr)
|
||||
os.exit(1)
|
||||
inp = sys.stdin.read().strip()
|
||||
if sys.argv[1] == "1":
|
||||
print(one(inp))
|
||||
else:
|
||||
print(two(inp))
|
8
challenges/2023/03-gearRatios/tests.json
Normal file
8
challenges/2023/03-gearRatios/tests.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"1": [
|
||||
{"res": "4361", "in": "467..114..\n...*......\n..35..633.\n......#...\n617*......\n.....+.58.\n..592.....\n......755.\n...$.*....\n.664.598.."}
|
||||
],
|
||||
"2": [
|
||||
{"res": "467835", "in": "467..114..\n...*......\n..35..633.\n......#...\n617*......\n.....+.58.\n..592.....\n......755.\n...$.*....\n.664.598.."}
|
||||
]
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue