Signed-off-by: AKP <tom@tdpain.net>
This commit is contained in:
akp 2022-12-14 12:13:00 +00:00
parent 8e65ed458b
commit 63cff023cc
No known key found for this signature in database
GPG key ID: AA5726202C8879B7
7 changed files with 169 additions and 1 deletions

View file

@ -0,0 +1 @@
# [Day 14: Regolith Reservoir](https://adventofcode.com/2022/day/14)

View 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
}

View 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"
}
]
}
}

View 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

View file

@ -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

Before After
Before After

View file

@ -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