Add 2021-05 in Python
Signed-off-by: AKU <tom@tdpain.net>
This commit is contained in:
parent
f23452873c
commit
390aef52f6
5 changed files with 133 additions and 0 deletions
23
challenges/2021/05-hydrothermalVenture/README.md
Normal file
23
challenges/2021/05-hydrothermalVenture/README.md
Normal file
|
@ -0,0 +1,23 @@
|
|||
# [Day 5: Hydrothermal Venture](https://adventofcode.com/2021/day/5)
|
||||
|
||||
### Part one
|
||||
|
||||
* Parse input and output a list of pairs of points.
|
||||
* Remove diagonal lines by filtering the list using the condition that `p1.x == p2.x or p1.y == p2.y`
|
||||
* Count overlapping points
|
||||
* Create a dictionary that uses the point coordinate as a key and contains an integer `n` for each key
|
||||
* Iterate over each line in the input, adding 1 to `n` for each coordinate in the line
|
||||
* The coordinates were founid by computing the x and y deltas between the two points that made up the line
|
||||
* The sign of the deltas determines the direction we step in
|
||||
* We then step through each point in the line based on the step directions until the final point is encountered
|
||||
* Iterate over all keys in the dictionary and count every point where `n > 1`
|
||||
|
||||
### Part two
|
||||
|
||||
The same as part one, but without the list filtering step.
|
||||
|
||||
---
|
||||
|
||||
Involved literal napkin maths.
|
||||
|
||||

|
17
challenges/2021/05-hydrothermalVenture/info.json
Normal file
17
challenges/2021/05-hydrothermalVenture/info.json
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"inputFile": "input.txt",
|
||||
"testCases": {
|
||||
"one": [
|
||||
{
|
||||
"input": "0,9 -> 5,9\n8,0 -> 0,8\n9,4 -> 3,4\n2,2 -> 2,1\n7,0 -> 7,4\n6,4 -> 2,0\n0,9 -> 2,9\n3,4 -> 1,4\n0,0 -> 8,8\n5,5 -> 8,2\n",
|
||||
"expected": "5"
|
||||
}
|
||||
],
|
||||
"two": [
|
||||
{
|
||||
"input": "0,9 -> 5,9\n8,0 -> 0,8\n9,4 -> 3,4\n2,2 -> 2,1\n7,0 -> 7,4\n6,4 -> 2,0\n0,9 -> 2,9\n3,4 -> 1,4\n0,0 -> 8,8\n5,5 -> 8,2\n",
|
||||
"expected": "12"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
BIN
challenges/2021/05-hydrothermalVenture/napkinmath.jpg
Normal file
BIN
challenges/2021/05-hydrothermalVenture/napkinmath.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 275 KiB |
92
challenges/2021/05-hydrothermalVenture/py/__init__.py
Normal file
92
challenges/2021/05-hydrothermalVenture/py/__init__.py
Normal file
|
@ -0,0 +1,92 @@
|
|||
import time
|
||||
from typing import Tuple, List, Generator
|
||||
from aocpy import BaseChallenge
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Point:
|
||||
x: int
|
||||
y: int
|
||||
|
||||
def __init__(self, p: str):
|
||||
x, y = p.split(",")
|
||||
self.x = int(x)
|
||||
self.y = int(y)
|
||||
|
||||
def as_tuple(self) -> Tuple[int, int]:
|
||||
return (self.x, self.y)
|
||||
|
||||
|
||||
Line = Tuple[Point, Point]
|
||||
|
||||
|
||||
def parse(instr: str) -> List[Line]:
|
||||
o = []
|
||||
for line in instr.strip().splitlines():
|
||||
p1, p2 = line.split(" -> ")
|
||||
o.append((Point(p1), Point(p2)))
|
||||
return o
|
||||
|
||||
|
||||
def remove_diagonal_lines(lines: List[Line]):
|
||||
return list(
|
||||
filter(
|
||||
lambda line: line[0].x == line[1].x or line[0].y == line[1].y,
|
||||
lines,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def iterate_points(line: Line) -> Generator[Point, None, None]:
|
||||
p1, p2 = line
|
||||
delta_x = p2.x - p1.x
|
||||
delta_y = p2.y - p1.y
|
||||
|
||||
x_step = 0
|
||||
y_step = 0
|
||||
|
||||
if delta_x > 0:
|
||||
x_step = 1
|
||||
elif delta_x < 0:
|
||||
x_step = -1
|
||||
|
||||
if delta_y > 0:
|
||||
y_step = 1
|
||||
elif delta_y < 0:
|
||||
y_step = -1
|
||||
|
||||
last_point = p1
|
||||
yield p1
|
||||
while last_point != p2:
|
||||
np = Point(f"{last_point.x+x_step},{last_point.y+y_step}")
|
||||
yield np
|
||||
last_point = np
|
||||
|
||||
|
||||
def count_overlapping_points(lines: List[Line]) -> int:
|
||||
areas = {}
|
||||
for line in lines:
|
||||
for point in iterate_points(line):
|
||||
t = point.as_tuple()
|
||||
areas[t] = areas.get(t, 0) + 1
|
||||
|
||||
number_overlaps = 0
|
||||
for point in areas:
|
||||
if areas[point] > 1:
|
||||
number_overlaps += 1
|
||||
|
||||
return number_overlaps
|
||||
|
||||
|
||||
class Challenge(BaseChallenge):
|
||||
@staticmethod
|
||||
def one(instr: str) -> int:
|
||||
lines = parse(instr)
|
||||
lines = remove_diagonal_lines(lines)
|
||||
return count_overlapping_points(lines)
|
||||
|
||||
@staticmethod
|
||||
def two(instr: str) -> int:
|
||||
lines = parse(instr)
|
||||
return count_overlapping_points(lines)
|
|
@ -14,5 +14,6 @@ Solutions to the [2021 Advent of Code](https://adventofcode.com/2021).
|
|||
| 02 - Dive! | Complete | [Python](02-dive/py), [Go](02-dive/go) | Have this set of instructions and do something sensible with it. |
|
||||
| 03 - Binary Diagnostic | Complete | [Python](03-binaryDiagnostic/py), [Nim](03-binaryDiagnostic/nim) | Bit twiddling aplenty! |
|
||||
| 04 - Giant Squid | Complete | [Python](04-giantSquid/py) | B-I-N-G-O, B-I-N-G-O, B-I-N-G-O and Bingo was his name-o! |
|
||||
| 05 - Hydrothermal Venture | Complete | [Python](05-hydrothermalVenture/py) | Pointy. |
|
||||
|
||||
<!-- PARSE END -->
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue