60 lines
1.6 KiB
Python
60 lines
1.6 KiB
Python
from math import sqrt
|
|
|
|
from tools.aoc import AOCDay
|
|
from typing import Any
|
|
|
|
|
|
def fire(velX: int, velY: int, minX: int, maxX: int, minY: int, maxY: int) -> (bool, int):
|
|
highY, posX, posY = 0, velX, velY
|
|
while not posX > maxX and not posY < minY:
|
|
if velX > 0:
|
|
velX -= 1
|
|
elif posX < minX:
|
|
break
|
|
velY -= 1
|
|
|
|
posX += velX
|
|
posY += velY
|
|
if posY > highY:
|
|
highY = posY
|
|
|
|
hit = minX <= posX - velX <= maxX and minY <= posY - velY <= maxY
|
|
return hit, highY if hit else minY
|
|
|
|
|
|
class Day(AOCDay):
|
|
inputs = [
|
|
[
|
|
(45, "test_input17"),
|
|
(5151, "input17")
|
|
],
|
|
[
|
|
(112, "test_input17"),
|
|
(968, "input17")
|
|
]
|
|
]
|
|
|
|
def getBoundaries(self) -> (int, int, int, int):
|
|
_, xRange, yRange = self.getInput().split("=")
|
|
minX, maxX = map(int, xRange[:-3].split(".."))
|
|
minY, maxY = map(int, yRange.split(".."))
|
|
return minX, maxX, minY, maxY
|
|
|
|
def part1(self) -> Any:
|
|
minX, maxX, minY, maxY = self.getBoundaries()
|
|
return max(fire(x, y, minX, maxX, minY, maxY)[1] for x in range(maxX) for y in range(abs(minY)))
|
|
|
|
def part2(self) -> Any:
|
|
minX, maxX, minY, maxY = self.getBoundaries()
|
|
hitCounter = 0
|
|
for x in range(int(sqrt(maxX)), maxX + 1):
|
|
for y in range(minY, abs(minY)):
|
|
hitCounter += fire(x, y, minX, maxX, minY, maxY)[0]
|
|
|
|
return hitCounter
|
|
|
|
|
|
if __name__ == '__main__':
|
|
day = Day(2021, 17)
|
|
day.run(verbose=True)
|