2022-14
Signed-off-by: AKP <tom@tdpain.net>
This commit is contained in:
parent
8e65ed458b
commit
63cff023cc
7 changed files with 169 additions and 1 deletions
1
challenges/2022/14-regolithReservoir/README.md
Normal file
1
challenges/2022/14-regolithReservoir/README.md
Normal file
|
@ -0,0 +1 @@
|
|||
# [Day 14: Regolith Reservoir](https://adventofcode.com/2022/day/14)
|
15
challenges/2022/14-regolithReservoir/benchmark.json
Normal file
15
challenges/2022/14-regolithReservoir/benchmark.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"day": 14,
|
||||
"dir": "challenges/2022/14-regolithReservoir",
|
||||
"implementations": {
|
||||
"Python": {
|
||||
"part.1.avg": 0.052977256774902344,
|
||||
"part.1.max": 0.059580087661743164,
|
||||
"part.1.min": 0.04468560218811035,
|
||||
"part.2.avg": 3.079384412765503,
|
||||
"part.2.max": 3.293449640274048,
|
||||
"part.2.min": 2.7332167625427246
|
||||
}
|
||||
},
|
||||
"numRuns": 25
|
||||
}
|
17
challenges/2022/14-regolithReservoir/info.json
Normal file
17
challenges/2022/14-regolithReservoir/info.json
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"inputFile": "input.txt",
|
||||
"testCases": {
|
||||
"one": [
|
||||
{
|
||||
"input": "498,4 -> 498,6 -> 496,6\n503,4 -> 502,4 -> 502,9 -> 494,9\n",
|
||||
"expected": "24"
|
||||
}
|
||||
],
|
||||
"two": [
|
||||
{
|
||||
"input": "498,4 -> 498,6 -> 496,6\n503,4 -> 502,4 -> 502,9 -> 494,9\n",
|
||||
"expected": "93"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
130
challenges/2022/14-regolithReservoir/py/__init__.py
Normal file
130
challenges/2022/14-regolithReservoir/py/__init__.py
Normal file
|
@ -0,0 +1,130 @@
|
|||
from enum import Enum
|
||||
from typing import *
|
||||
from aocpy import BaseChallenge
|
||||
|
||||
|
||||
class State(Enum):
|
||||
EMPTY = None
|
||||
WALL = 1
|
||||
SAND = 2
|
||||
|
||||
|
||||
Vector = Tuple[int, int]
|
||||
Scan = Dict[Vector, State]
|
||||
|
||||
|
||||
def parse(instr: str) -> Tuple[Scan, Vector, Vector]:
|
||||
res = {}
|
||||
|
||||
for line in instr.strip().splitlines():
|
||||
points: List[Vector] = []
|
||||
for x in line.split("->"):
|
||||
p = x.split(",")
|
||||
points.append((int(p[0]), int(p[1])))
|
||||
|
||||
for i in range(len(points) - 1):
|
||||
next_i = i + 1
|
||||
dx = points[next_i][0] - points[i][0]
|
||||
dy = points[next_i][1] - points[i][1]
|
||||
|
||||
# If either dx or dy is positive, that means its going down or left respectively
|
||||
|
||||
assert dx == 0 or dy == 0
|
||||
|
||||
if dx == 0:
|
||||
f = lambda x, y: x + y
|
||||
if dy < 0:
|
||||
f = lambda x, y: x - y
|
||||
|
||||
for j in range(abs(dy) + 1):
|
||||
res[(points[i][0], f(points[i][1], j))] = State.WALL
|
||||
else:
|
||||
f = lambda x, y: x + y
|
||||
if dx < 0:
|
||||
f = lambda x, y: x - y
|
||||
|
||||
for j in range(abs(dx) + 1):
|
||||
res[(f(points[i][0], j), points[i][1])] = State.WALL
|
||||
|
||||
keys = res.keys()
|
||||
min_x = min(keys, key=lambda x: x[0])[0]
|
||||
max_x = max(keys, key=lambda x: x[0])[0]
|
||||
min_y = min(keys, key=lambda x: x[1])[1]
|
||||
max_y = max(keys, key=lambda x: x[1])[1]
|
||||
|
||||
return res, (min_x, min_y), (max_x, max_y)
|
||||
|
||||
|
||||
def is_out_of_bounds(v: Vector, min_v: Vector, max_v: Vector) -> bool:
|
||||
return not ((min_v[0] <= v[0] <= max_v[0]) and (0 <= v[1] <= max_v[1]))
|
||||
|
||||
|
||||
class Challenge(BaseChallenge):
|
||||
|
||||
@staticmethod
|
||||
def one(instr: str) -> int:
|
||||
inp, min_pos, max_pos = parse(instr)
|
||||
|
||||
cursor = (500, 0)
|
||||
grains = 0
|
||||
|
||||
while not is_out_of_bounds(cursor, min_pos, max_pos):
|
||||
x, y = cursor
|
||||
|
||||
if inp.get((x, y + 1)) is None:
|
||||
cursor = (x, y + 1)
|
||||
elif inp.get((x, y + 1)) == State.WALL or inp.get((x, y + 1)) == State.SAND:
|
||||
if inp.get((x - 1, y + 1)) is None:
|
||||
cursor = (x - 1, y + 1)
|
||||
elif inp.get((x + 1, y + 1)) is None:
|
||||
cursor = (x + 1, y + 1)
|
||||
else:
|
||||
inp[cursor] = State.SAND
|
||||
grains += 1
|
||||
cursor = (500, 0)
|
||||
else:
|
||||
inp[cursor] = State.SAND
|
||||
grains += 1
|
||||
cursor = (500, 0)
|
||||
|
||||
return grains
|
||||
|
||||
@staticmethod
|
||||
def two(instr: str) -> int:
|
||||
inp, min_pos, max_pos = parse(instr)
|
||||
|
||||
max_pos = (max_pos[0], max_pos[1] + 2)
|
||||
|
||||
cursor = (500, 0)
|
||||
grains = 0
|
||||
|
||||
def get(k: Vector):
|
||||
if k[1] == max_pos[1]:
|
||||
return State.WALL
|
||||
|
||||
return inp.get(k)
|
||||
|
||||
while True:
|
||||
x, y = cursor
|
||||
|
||||
if get((x, y + 1)) is None:
|
||||
cursor = (x, y + 1)
|
||||
elif get((x, y + 1)) == State.WALL or get((x, y + 1)) == State.SAND:
|
||||
if get((x - 1, y + 1)) is None:
|
||||
cursor = (x - 1, y + 1)
|
||||
elif get((x + 1, y + 1)) is None:
|
||||
cursor = (x + 1, y + 1)
|
||||
else:
|
||||
inp[cursor] = State.SAND
|
||||
grains += 1
|
||||
if cursor == (500, 0):
|
||||
break
|
||||
cursor = (500, 0)
|
||||
else:
|
||||
inp[cursor] = State.SAND
|
||||
grains += 1
|
||||
if cursor == (500, 0):
|
||||
break
|
||||
cursor = (500, 0)
|
||||
|
||||
return grains
|
|
@ -24,4 +24,8 @@ Solutions to the [2022 Advent of Code](https://adventofcode.com/2022).
|
|||
| 08 - Treetop Tree House | ★ ★ | [Python](08-treetopTreeHouse/py) | Magical coordinate dictionary tuple things do be magical. |
|
||||
| 09 - Rope Bridge | ★ ★ | [Python](09-ropeBridge/py), [Nim](09-ropeBridge/nim) | Does this count as this year's first cellular automata? |
|
||||
| 10 - Cathode-Ray Tube | ★ ★ | [Python](10-cathodeRayTube/py) | A nasty problem with a nasty solution and nasty outputs that mess with my framework. |
|
||||
| 11 - Monkey in the Middle | ★ ★ | [Python](11-monkeyInTheMiddle/py) | Return of Advent of Maths! |
|
||||
| 12 - Hill Climbing Algorithm | ☆ ☆ | | |
|
||||
| 13 - Distress Signal | ☆ ☆ | | |
|
||||
| 14 - Regolith Reservoir | ★ ★ | [Python](14-regolithReservoir/py) | Simulating falling sand |
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 52 KiB |
|
@ -38,7 +38,8 @@ while True:
|
|||
res = run()
|
||||
except Exception as e:
|
||||
err = f"{type(e)}: {e}"
|
||||
# err = f"{type(e)}: {e}\n{''.join(traceback.format_tb(e.__traceback__))}"
|
||||
import traceback
|
||||
err = f"{type(e)}: {e}\n{''.join(traceback.format_tb(e.__traceback__))}"
|
||||
end_time = time.time()
|
||||
|
||||
running_time = end_time-start_time
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue