Signed-off-by: AKP <tom@tdpain.net>
This commit is contained in:
akp 2022-12-23 15:11:07 +00:00
parent 7dafc1ee82
commit b22f34cdc6
No known key found for this signature in database
GPG key ID: AA5726202C8879B7
6 changed files with 212 additions and 24 deletions

View file

@ -0,0 +1 @@
# [Day 23: Unstable Diffusion](https://adventofcode.com/2022/day/23)

View file

@ -0,0 +1,15 @@
{
"day": 23,
"dir": "challenges/2022/23-unstableDiffusion",
"implementations": {
"Python": {
"part.1.avg": 0.5044037818908691,
"part.1.max": 0.6002228260040283,
"part.1.min": 0.4217519760131836,
"part.2.avg": 39.05081315040589,
"part.2.max": 41.361868143081665,
"part.2.min": 38.02052927017212
}
},
"numRuns": 5
}

View file

@ -0,0 +1,25 @@
{
"inputFile": "input.txt",
"testCases": {
"one": [
{
"input": ".....\n..##.\n..#..\n.....\n..##.\n.....",
"expected": "25"
},
{
"input": "....#..\n..###.#\n#...#.#\n.#...##\n#.###..\n##.#.##\n.#..#..\n",
"expected": "110"
}
],
"two": [
{
"input": ".....\n..##.\n..#..\n.....\n..##.\n.....",
"expected": "4"
},
{
"input": "....#..\n..###.#\n#...#.#\n.#...##\n#.###..\n##.#.##\n.#..#..\n",
"expected": "20"
}
]
}
}

View file

@ -0,0 +1,146 @@
from __future__ import annotations
from typing import *
from aocpy import BaseChallenge, Vector, min_max
from enum import Enum
class CellState(Enum):
OCCUPIED = "#"
EMPTY = "."
class Direction(Enum):
NORTH = (0, -1)
EAST = (1, 0)
SOUTH = (0, 1)
WEST = (-1, 0)
ADJACENT_POSITIONS = [
(0, -1),
(1, -1),
(1, 0),
(1, 1),
(0, 1),
(-1, 1),
(-1, 0),
(-1, -1),
]
CHECK_POSITIONS = {
Direction.NORTH.value: [Direction.NORTH.value, (1, -1), (-1, -1)],
Direction.EAST.value: [Direction.EAST.value, (1, 1), (1, -1)],
Direction.SOUTH.value: [Direction.SOUTH.value, (1, 1), (-1, 1)],
Direction.WEST.value: [Direction.WEST.value, (-1, 1), (-1, -1)],
}
Crater = Dict[Vector, CellState]
def parse(instr: str) -> Crater:
res: Crater = {}
for y, line in enumerate(instr.strip().splitlines()):
for x, char in enumerate(line):
if char == CellState.OCCUPIED.value:
res[Vector(x, y)] = CellState.OCCUPIED
return res
def step(state: Crater, directions: List[Tuple[int, int]]) -> bool:
next_moves: Dict[Vector, List[Vector]] = {}
for elf in state:
for direction in directions:
has_any_adjacent = False
for adj_pos in ADJACENT_POSITIONS:
if elf + adj_pos in state:
has_any_adjacent = True
break
if not has_any_adjacent:
break
is_avail = True
for check_pos in CHECK_POSITIONS[direction.value]:
if elf + check_pos in state:
is_avail = False
break
if is_avail:
pos = elf + direction.value
x = next_moves.get(pos, [])
x.append(elf)
next_moves[pos] = x
break
for target_pos in next_moves:
if len(next_moves[target_pos]) != 1:
continue
state[target_pos] = CellState.OCCUPIED
del state[next_moves[target_pos][0]]
return len(next_moves) != 0
def print_crater(cr: Crater):
for y in range(-2, -2 + 12):
for x in range(-3, -3 + 14):
print(cr[(x, y)].value if (x, y) in cr else ".", end="")
print()
print("________________", flush=True)
def calc_open_area(state: Crater) -> int:
min_x, max_x = min_max(p.x for p in state)
min_y, max_y = min_max(p.y for p in state)
max_x += 1
max_y += 1
return ((max_x - min_x) * (max_y - min_y)) - len(state)
class Challenge(BaseChallenge):
@staticmethod
def one(instr: str) -> int:
inp = parse(instr)
directions = [
Direction.NORTH,
Direction.SOUTH,
Direction.WEST,
Direction.EAST,
]
for _ in range(10):
step(inp, directions)
directions.append(directions.pop(0))
return calc_open_area(inp)
@staticmethod
def two(instr: str) -> int:
inp = parse(instr)
directions = [
Direction.NORTH,
Direction.SOUTH,
Direction.WEST,
Direction.EAST,
]
n = 0
while True:
did_something_move = step(inp, directions)
n += 1
if not did_something_move:
break
directions.append(directions.pop(0))
return n

View file

@ -14,27 +14,28 @@ The red dotted line denotes 15 seconds.
<!-- ★ ☆ -->
| Day | Status | Solutions | Notes |
| ----------------------------------- | ------------------ | ---------- | ------ |
| 01 - Calorie Counting | ★ ★ | [Python](01-calorieCounting/py/__init__.py), [Nim](01-calorieCounting/nim/challenge.nim), [Java](01-calorieCounting/java/src) | Summing numbers |
| 02 - Rock Paper Scissors | ★ ★ | [Python](02-rockPaperScissors/py/__init__.py), [Nim](02-rockPaperScissors/nim/challenge.nim) | Programmatically playing Rock Paper Scissors |
| 03 - Rucksack Reorganization | ★ ★ | [Python](03-rucksackReorganization/py/__init__.py), [Nim](03-rucksackReorganization/nim/challenge.nim) | Sets and intersections |
| 04 - Camp Cleanup | ★ ★ | [Python](04-campCleanup/py/__init__.py), [Nim](04-campCleanup/nim/challenge.nim) | More sets and more intersections! |
| 05 - Supply Stacks | ★ ★ | [Python](05-supplyStacks/py/__init__.py), [Nim](05-supplyStacks/nim/challenge.nim) | Believe it or not, this one involved stacks. |
| 06 - Tuning Trouble | ★ ★ | [Python](06-tuningTrouble/py/__init__.py), [Nim](06-tuningTrouble/nim/challenge.nim) | This is the first year I've not repeatedly forgotten about the existence of sets, and it's coming in quite handy. |
| 07 - No Space Left On Device | ★ ★ | [Python](07-noSpaceLeftOnDevice/py/__init__.py) | Turns out that fake file systems are prone to very subtle and infuriating bugs. |
| 08 - Treetop Tree House | ★ ★ | [Python](08-treetopTreeHouse/py/__init__.py) | Magical coordinate dictionary tuple things do be magical. |
| 09 - Rope Bridge | ★ ★ | [Python](09-ropeBridge/py/__init__.py), [Nim](09-ropeBridge/nim/challenge.nim) | Does this count as this year's first cellular automata? |
| 10 - Cathode-Ray Tube | ★ ★ | [Python](10-cathodeRayTube/py/__init__.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/__init__.py) | Return of Advent of Maths! |
| 12 - Hill Climbing Algorithm | ★ ★ | [Python](12-hillClimbingAlgorithm/py/__init__.py) | Iiiiiiiiiiiiiiiit's Djikstra's! |
| 13 - Distress Signal | ★ ★ | [Python](13-distressSignal/py/__init__.py) | Sorting some weird pairs of values with weird rules |
| 14 - Regolith Reservoir | ★ ★ | [Python](14-regolithReservoir/py/__init__.py) | Simulating falling sand |
| 15 - Beacon Exclusion Zone | ★ ★ | [Python](15-beaconExclusionZone/py/__init__.py) | Searching through a 4000000^2 size grid for a literal single empty spot |
| 16 - Proboscidea Volcanium | ★ ★ | [Python](16-proboscideaVolcanium/py/__init__.py) | Nasty combinatorics |
| 17 - Pyroclastic Flow | ★ ★ | [Python](17-pyroclasticFlow/py/__init__.py) | Detecting cycles in a large amount of knock-off Tetris. |
| 18 - Boiling Boulders | ★ ★ | [Python](18-boilingBoulders/py/__init__.py) | Finding the surface area of a shape specified by a list of unit cubes. |
| 19 - Not Enough Minerals | ★ ★ | [Python](19-notEnoughMinerals/py/__init__.py) | Finding the most effective sequence of operations to complete a specific task. |
| 20 - Grove Positioning System | ★ ★ | [Python](20-grovePositioningSystem/py/__init__.py) | My hell is lined with circular sequences. |
| 21 - Monkey Math | ★ ★ | [Python](21-monkeyMath/py/__init__.py) | Trees of math with a fairly satisfying solution :D |
| 22 - Monkey Map | ★ ★ | [Python](22-monkeyMap/py/__init__.py) | Please never ever make me trace a path around a 3D shape in two dimensions ever again |
| Day | Status | Solutions | Notes |
|-------------------------------|--------|-------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|
| 01 - Calorie Counting | ★ ★ | [Python](01-calorieCounting/py/__init__.py), [Nim](01-calorieCounting/nim/challenge.nim), [Java](01-calorieCounting/java/src) | Summing numbers |
| 02 - Rock Paper Scissors | ★ ★ | [Python](02-rockPaperScissors/py/__init__.py), [Nim](02-rockPaperScissors/nim/challenge.nim) | Programmatically playing Rock Paper Scissors |
| 03 - Rucksack Reorganization | ★ ★ | [Python](03-rucksackReorganization/py/__init__.py), [Nim](03-rucksackReorganization/nim/challenge.nim) | Sets and intersections |
| 04 - Camp Cleanup | ★ ★ | [Python](04-campCleanup/py/__init__.py), [Nim](04-campCleanup/nim/challenge.nim) | More sets and more intersections! |
| 05 - Supply Stacks | ★ ★ | [Python](05-supplyStacks/py/__init__.py), [Nim](05-supplyStacks/nim/challenge.nim) | Believe it or not, this one involved stacks. |
| 06 - Tuning Trouble | ★ ★ | [Python](06-tuningTrouble/py/__init__.py), [Nim](06-tuningTrouble/nim/challenge.nim) | This is the first year I've not repeatedly forgotten about the existence of sets, and it's coming in quite handy. |
| 07 - No Space Left On Device | ★ ★ | [Python](07-noSpaceLeftOnDevice/py/__init__.py) | Turns out that fake file systems are prone to very subtle and infuriating bugs. |
| 08 - Treetop Tree House | ★ ★ | [Python](08-treetopTreeHouse/py/__init__.py) | Magical coordinate dictionary tuple things do be magical. |
| 09 - Rope Bridge | ★ ★ | [Python](09-ropeBridge/py/__init__.py), [Nim](09-ropeBridge/nim/challenge.nim) | Does this count as this year's first cellular automata? |
| 10 - Cathode-Ray Tube | ★ ★ | [Python](10-cathodeRayTube/py/__init__.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/__init__.py) | Return of Advent of Maths! |
| 12 - Hill Climbing Algorithm | ★ ★ | [Python](12-hillClimbingAlgorithm/py/__init__.py) | Iiiiiiiiiiiiiiiit's Djikstra's! |
| 13 - Distress Signal | ★ ★ | [Python](13-distressSignal/py/__init__.py) | Sorting some weird pairs of values with weird rules |
| 14 - Regolith Reservoir | ★ ★ | [Python](14-regolithReservoir/py/__init__.py) | Simulating falling sand |
| 15 - Beacon Exclusion Zone | ★ ★ | [Python](15-beaconExclusionZone/py/__init__.py) | Searching through a 4000000^2 size grid for a literal single empty spot |
| 16 - Proboscidea Volcanium | ★ ★ | [Python](16-proboscideaVolcanium/py/__init__.py) | Nasty combinatorics |
| 17 - Pyroclastic Flow | ★ ★ | [Python](17-pyroclasticFlow/py/__init__.py) | Detecting cycles in a large amount of knock-off Tetris. |
| 18 - Boiling Boulders | ★ ★ | [Python](18-boilingBoulders/py/__init__.py) | Finding the surface area of a shape specified by a list of unit cubes. |
| 19 - Not Enough Minerals | ★ ★ | [Python](19-notEnoughMinerals/py/__init__.py) | Finding the most effective sequence of operations to complete a specific task. |
| 20 - Grove Positioning System | ★ ★ | [Python](20-grovePositioningSystem/py/__init__.py) | My hell is lined with circular sequences. |
| 21 - Monkey Math | ★ ★ | [Python](21-monkeyMath/py/__init__.py) | Trees of math with a fairly satisfying solution :D |
| 22 - Monkey Map | ★ ★ | [Python](22-monkeyMap/py/__init__.py) | Please never ever make me trace a path around a 3D shape in two dimensions ever again |
| 23 - Unstable Diffusion | ★ ★ | [Python](23-unstableDiffusion/py/__init__.py) | I <3 Cellular automata |

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Before After
Before After