aboutsummaryrefslogtreecommitdiff
path: root/2021/17/puzzles.py
blob: 30fb3474f6fff85f1d574fc9c1fb25a29fcdeb93 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/usr/bin/env python3

import re
from itertools import product
from math import inf
from typing import NamedTuple, Optional


class Range(NamedTuple):
	minx: int
	maxx: int
	miny: int
	maxy: int


def fire(r: Range, dy: int, dx: int) -> Optional[int]:
	x, y = 0, 0
	h = -inf
	while x <= r.maxx and y >= r.miny:
		x += dx
		y += dy

		if dx > 0:
			dx -= 1
		elif dx < 0:
			dx += 1
		dy -= 1
		h = max(h, y)

		if r.minx <= x <= r.maxx and r.miny <= y <= r.maxy:
			return h
	return None


def main() -> None:
	with open("input", "r", encoding="utf-8") as f:
		m = re.split(r"target area: x=(\d+)..(\d+), y=(-?\d+)..(-?\d+)", f.read())
	r = Range(*tuple(map(int, m[1:-1])))

	xr = max(abs(r.minx), abs(r.maxx))
	yr = max(abs(r.miny), abs(r.maxy))

	heights = tuple(
		filter(
			lambda h: h != None,
			(fire(r, x, y) for x, y in product(range(-yr, yr + 1), range(-xr, xr + 1))),
		)
	)
	# START PART 1
	print(max(heights))
	# END PART 1 START PART 2
	print(len(heights))
	# END PART 2


if __name__ == "__main__":
	main()