[py] Port 2018_06
This commit is contained in:
parent
a06dcab3ec
commit
d01f1ccff3
4 changed files with 123 additions and 131 deletions
|
|
@ -1,124 +0,0 @@
|
||||||
import sys
|
|
||||||
|
|
||||||
# PART 1
|
|
||||||
|
|
||||||
def load_coords(filename):
|
|
||||||
coords = []
|
|
||||||
with open(filename, "r") as f:
|
|
||||||
for line in f:
|
|
||||||
x, y = line[:-1].split(", ")
|
|
||||||
x, y = int(x), int(y)
|
|
||||||
coords.append((x, y))
|
|
||||||
return coords
|
|
||||||
|
|
||||||
class Voronoi:
|
|
||||||
def __init__(self, min_x, min_y, max_x, max_y):
|
|
||||||
self.min_x = min_x
|
|
||||||
self.min_y = min_y
|
|
||||||
self.max_x = max_x
|
|
||||||
self.max_y = max_y
|
|
||||||
|
|
||||||
self.cells = {}
|
|
||||||
|
|
||||||
def add(self, pos_x, pos_y):
|
|
||||||
for x in range(self.min_x, self.max_x + 1):
|
|
||||||
for y in range(self.min_y, self.max_y + 1):
|
|
||||||
self.add_to_cell(pos_x, pos_y, x, y)
|
|
||||||
print(f"Added ({pos_x}, {pos_y})")
|
|
||||||
|
|
||||||
def add_to_cell(self, pos_x, pos_y, cell_x, cell_y):
|
|
||||||
pos = (pos_x, pos_y)
|
|
||||||
cell = (cell_x, cell_y)
|
|
||||||
dist = abs(pos_x - cell_x) + abs(pos_y - cell_y)
|
|
||||||
|
|
||||||
if cell in self.cells:
|
|
||||||
cdist, cpos = self.cells[cell]
|
|
||||||
if dist < cdist:
|
|
||||||
self.cells[cell] = (dist, pos)
|
|
||||||
elif dist == cdist and cpos is not None:
|
|
||||||
self.cells[cell] = (dist, None)
|
|
||||||
# else: pass
|
|
||||||
else:
|
|
||||||
self.cells[cell] = (dist, pos)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_coords(cls, coords):
|
|
||||||
xs = [x for x, _ in coords]
|
|
||||||
ys = [y for _, y in coords]
|
|
||||||
|
|
||||||
voro = cls(min(xs), min(ys), max(xs), max(ys))
|
|
||||||
for x, y in coords:
|
|
||||||
voro.add(x, y)
|
|
||||||
|
|
||||||
return voro
|
|
||||||
|
|
||||||
def find_ignore(self):
|
|
||||||
ignore = set()
|
|
||||||
for x in range(self.min_x, self.max_x + 1):
|
|
||||||
_, pos1 = self.cells.get((x, self.min_y))
|
|
||||||
_, pos2 = self.cells.get((x, self.max_y))
|
|
||||||
ignore.add(pos1)
|
|
||||||
ignore.add(pos2)
|
|
||||||
for y in range(self.min_y, self.max_y + 1):
|
|
||||||
_, pos1 = self.cells.get((self.min_x, y))
|
|
||||||
_, pos2 = self.cells.get((self.max_x, y))
|
|
||||||
ignore.add(pos1)
|
|
||||||
ignore.add(pos2)
|
|
||||||
return ignore
|
|
||||||
|
|
||||||
def find_largest(self):
|
|
||||||
ignore = self.find_ignore()
|
|
||||||
|
|
||||||
count = {}
|
|
||||||
for x in range(self.min_x + 1, self.max_x):
|
|
||||||
for y in range(self.min_y + 1, self.max_y):
|
|
||||||
_, pos = self.cells.get((x, y))
|
|
||||||
if pos not in ignore:
|
|
||||||
count[pos] = count.get(pos, 0) + 1
|
|
||||||
|
|
||||||
return max(count.values())
|
|
||||||
|
|
||||||
# PART 2
|
|
||||||
|
|
||||||
class Nearest:
|
|
||||||
def __init__(self, coords):
|
|
||||||
self.coords = coords
|
|
||||||
|
|
||||||
xs = [x for x, _ in self.coords]
|
|
||||||
ys = [y for _, y in self.coords]
|
|
||||||
|
|
||||||
self.min_x = min(xs)
|
|
||||||
self.min_y = min(ys)
|
|
||||||
self.max_x = max(xs)
|
|
||||||
self.max_y = max(ys)
|
|
||||||
|
|
||||||
def find(self):
|
|
||||||
cells = set()
|
|
||||||
|
|
||||||
for x in range(self.min_x, self.max_x + 1):
|
|
||||||
for y in range(self.min_y, self.max_y + 1):
|
|
||||||
if self.evaluate(x, y):
|
|
||||||
cells.add((x, y))
|
|
||||||
|
|
||||||
return len(cells)
|
|
||||||
|
|
||||||
def evaluate(self, pos_x, pos_y):
|
|
||||||
pos = (pos_x, pos_y)
|
|
||||||
dist = 0
|
|
||||||
for x, y in self.coords:
|
|
||||||
dist += abs(pos_x - x) + abs(pos_y - y)
|
|
||||||
return dist < 10000
|
|
||||||
|
|
||||||
def main(filename):
|
|
||||||
print(f"Solutions for {filename}")
|
|
||||||
coords = load_coords(filename)
|
|
||||||
voro = Voronoi.from_coords(coords)
|
|
||||||
largest = voro.find_largest()
|
|
||||||
print(f"Part 1: {largest}")
|
|
||||||
nearest = Nearest(coords)
|
|
||||||
largest_2 = nearest.find()
|
|
||||||
print(f"Part 2: {largest_2}")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
for filename in sys.argv[1:]:
|
|
||||||
main(filename)
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
1, 1
|
|
||||||
1, 6
|
|
||||||
8, 3
|
|
||||||
3, 4
|
|
||||||
5, 5
|
|
||||||
8, 9
|
|
||||||
|
|
@ -2,7 +2,7 @@ import sys
|
||||||
import argparse
|
import argparse
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from .y2018 import d01, d02, d03, d04, d05
|
from .y2018 import d01, d02, d03, d04, d05, d06
|
||||||
from .y2020 import d10
|
from .y2020 import d10
|
||||||
from .y2021 import d14
|
from .y2021 import d14
|
||||||
from .y2022 import d01, d02, d03, d04, d05, d06
|
from .y2022 import d01, d02, d03, d04, d05, d06
|
||||||
|
|
@ -13,6 +13,7 @@ DAYS = {
|
||||||
"2018_03": y2018.d03.solve,
|
"2018_03": y2018.d03.solve,
|
||||||
"2018_04": y2018.d04.solve,
|
"2018_04": y2018.d04.solve,
|
||||||
"2018_05": y2018.d05.solve,
|
"2018_05": y2018.d05.solve,
|
||||||
|
"2018_06": y2018.d06.solve,
|
||||||
"2020_10": y2020.d10.solve,
|
"2020_10": y2020.d10.solve,
|
||||||
"2021_14": y2021.d14.solve,
|
"2021_14": y2021.d14.solve,
|
||||||
"2022_01": y2022.d01.solve,
|
"2022_01": y2022.d01.solve,
|
||||||
|
|
|
||||||
121
py/aoc/y2018/d06.py
Normal file
121
py/aoc/y2018/d06.py
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
# PART 1
|
||||||
|
|
||||||
|
|
||||||
|
def load_coords(inputstr):
|
||||||
|
coords = []
|
||||||
|
for line in inputstr.splitlines():
|
||||||
|
x, y = line.split(", ")
|
||||||
|
x, y = int(x), int(y)
|
||||||
|
coords.append((x, y))
|
||||||
|
return coords
|
||||||
|
|
||||||
|
|
||||||
|
class Voronoi:
|
||||||
|
def __init__(self, min_x, min_y, max_x, max_y):
|
||||||
|
self.min_x = min_x
|
||||||
|
self.min_y = min_y
|
||||||
|
self.max_x = max_x
|
||||||
|
self.max_y = max_y
|
||||||
|
|
||||||
|
self.cells = {}
|
||||||
|
|
||||||
|
def add(self, pos_x, pos_y):
|
||||||
|
for x in range(self.min_x, self.max_x + 1):
|
||||||
|
for y in range(self.min_y, self.max_y + 1):
|
||||||
|
self.add_to_cell(pos_x, pos_y, x, y)
|
||||||
|
# print(f"Added ({pos_x}, {pos_y})")
|
||||||
|
|
||||||
|
def add_to_cell(self, pos_x, pos_y, cell_x, cell_y):
|
||||||
|
pos = (pos_x, pos_y)
|
||||||
|
cell = (cell_x, cell_y)
|
||||||
|
dist = abs(pos_x - cell_x) + abs(pos_y - cell_y)
|
||||||
|
|
||||||
|
if cell in self.cells:
|
||||||
|
cdist, cpos = self.cells[cell]
|
||||||
|
if dist < cdist:
|
||||||
|
self.cells[cell] = (dist, pos)
|
||||||
|
elif dist == cdist and cpos is not None:
|
||||||
|
self.cells[cell] = (dist, None)
|
||||||
|
# else: pass
|
||||||
|
else:
|
||||||
|
self.cells[cell] = (dist, pos)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_coords(cls, coords):
|
||||||
|
xs = [x for x, _ in coords]
|
||||||
|
ys = [y for _, y in coords]
|
||||||
|
|
||||||
|
voro = cls(min(xs), min(ys), max(xs), max(ys))
|
||||||
|
for x, y in coords:
|
||||||
|
voro.add(x, y)
|
||||||
|
|
||||||
|
return voro
|
||||||
|
|
||||||
|
def find_ignore(self):
|
||||||
|
ignore = set()
|
||||||
|
for x in range(self.min_x, self.max_x + 1):
|
||||||
|
_, pos1 = self.cells.get((x, self.min_y))
|
||||||
|
_, pos2 = self.cells.get((x, self.max_y))
|
||||||
|
ignore.add(pos1)
|
||||||
|
ignore.add(pos2)
|
||||||
|
for y in range(self.min_y, self.max_y + 1):
|
||||||
|
_, pos1 = self.cells.get((self.min_x, y))
|
||||||
|
_, pos2 = self.cells.get((self.max_x, y))
|
||||||
|
ignore.add(pos1)
|
||||||
|
ignore.add(pos2)
|
||||||
|
return ignore
|
||||||
|
|
||||||
|
def find_largest(self):
|
||||||
|
ignore = self.find_ignore()
|
||||||
|
|
||||||
|
count = {}
|
||||||
|
for x in range(self.min_x + 1, self.max_x):
|
||||||
|
for y in range(self.min_y + 1, self.max_y):
|
||||||
|
_, pos = self.cells.get((x, y))
|
||||||
|
if pos not in ignore:
|
||||||
|
count[pos] = count.get(pos, 0) + 1
|
||||||
|
|
||||||
|
return max(count.values())
|
||||||
|
|
||||||
|
|
||||||
|
# PART 2
|
||||||
|
|
||||||
|
|
||||||
|
class Nearest:
|
||||||
|
def __init__(self, coords):
|
||||||
|
self.coords = coords
|
||||||
|
|
||||||
|
xs = [x for x, _ in self.coords]
|
||||||
|
ys = [y for _, y in self.coords]
|
||||||
|
|
||||||
|
self.min_x = min(xs)
|
||||||
|
self.min_y = min(ys)
|
||||||
|
self.max_x = max(xs)
|
||||||
|
self.max_y = max(ys)
|
||||||
|
|
||||||
|
def find(self):
|
||||||
|
cells = set()
|
||||||
|
|
||||||
|
for x in range(self.min_x, self.max_x + 1):
|
||||||
|
for y in range(self.min_y, self.max_y + 1):
|
||||||
|
if self.evaluate(x, y):
|
||||||
|
cells.add((x, y))
|
||||||
|
|
||||||
|
return len(cells)
|
||||||
|
|
||||||
|
def evaluate(self, pos_x, pos_y):
|
||||||
|
pos = (pos_x, pos_y)
|
||||||
|
dist = 0
|
||||||
|
for x, y in self.coords:
|
||||||
|
dist += abs(pos_x - x) + abs(pos_y - y)
|
||||||
|
return dist < 10000
|
||||||
|
|
||||||
|
|
||||||
|
def solve(inputstr):
|
||||||
|
coords = load_coords(inputstr)
|
||||||
|
voro = Voronoi.from_coords(coords)
|
||||||
|
largest = voro.find_largest()
|
||||||
|
print(f"Part 1: {largest}")
|
||||||
|
nearest = Nearest(coords)
|
||||||
|
largest_2 = nearest.find()
|
||||||
|
print(f"Part 2: {largest_2}")
|
||||||
Loading…
Add table
Add a link
Reference in a new issue