[py] Port 2018_06

This commit is contained in:
Joscha 2022-12-06 15:29:18 +01:00
parent a06dcab3ec
commit d01f1ccff3
4 changed files with 123 additions and 131 deletions

View file

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

View file

@ -1,6 +0,0 @@
1, 1
1, 6
8, 3
3, 4
5, 5
8, 9

View file

@ -2,7 +2,7 @@ import sys
import argparse
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 .y2021 import d14
from .y2022 import d01, d02, d03, d04, d05, d06
@ -13,6 +13,7 @@ DAYS = {
"2018_03": y2018.d03.solve,
"2018_04": y2018.d04.solve,
"2018_05": y2018.d05.solve,
"2018_06": y2018.d06.solve,
"2020_10": y2020.d10.solve,
"2021_14": y2021.d14.solve,
"2022_01": y2022.d01.solve,

121
py/aoc/y2018/d06.py Normal file
View 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}")