Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b87b64d
commit ec70933
Showing
5 changed files
with
343 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import sys | ||
from collections import defaultdict, namedtuple | ||
|
||
Point = namedtuple("Point", ["x", "y"]) | ||
|
||
|
||
def mh_dist(p1, p2): | ||
return abs(p1.x - p2.x) + abs(p1.y - p2.y) | ||
|
||
|
||
with open(sys.argv[1]) as f: | ||
points = [ | ||
Point(*tuple(int(c) for c in l.strip().split(","))) for l in f.readlines() | ||
] | ||
|
||
SIZE = 360 | ||
|
||
|
||
def find_closest_point(points, x, y): | ||
dists = {} | ||
for p in points: | ||
dists[p] = mh_dist(p, Point(x, y)) | ||
|
||
# Check if there's a single closest point or multiple. | ||
point, min_ = min(dists.items(), key=lambda x: x[1]) | ||
for p, dist in dists.items(): | ||
if dist == min_ and point != p: | ||
# Found multiple closest points, return None | ||
return None | ||
return point | ||
|
||
|
||
lt10000 = 0 | ||
grid = [[None for _ in range(SIZE)] for _ in range(SIZE)] | ||
for y, r in enumerate(grid): | ||
for x, c in enumerate(r): | ||
closest = find_closest_point(points, x, y) | ||
mh_dist_sum = 0 | ||
for pi, p in enumerate(points): | ||
mh_dist_sum += mh_dist(p, Point(x, y)) | ||
if p.x == x and p.y == y or closest and closest == p: | ||
# Mark each grid point with the closest point. | ||
grid[y][x] = p | ||
if mh_dist_sum < 10000: | ||
lt10000 += 1 | ||
|
||
|
||
def find_inf(grid): | ||
inf = set() | ||
for y, r in enumerate(grid): | ||
for x, c in enumerate(r): | ||
# Regions are infinite if they are at one edge of the grid. | ||
if y == 0 or x == 0 or y == SIZE - 1 or x == SIZE - 1: | ||
inf.add(c) | ||
return inf | ||
|
||
|
||
# Iterate through grid and count region sizes which are not infinite. | ||
not_inf = set(points) - find_inf(grid) | ||
sizes = defaultdict(int) | ||
for r in grid: | ||
for c in r: | ||
for p in not_inf: | ||
if p == c: | ||
sizes[p] += 1 | ||
|
||
print(max(sizes.items(), key=lambda x: x[1])) | ||
|
||
|
||
# | ||
# Part 2 | ||
print(lt10000) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# Slightly faster implementation | ||
import sys | ||
from collections import namedtuple | ||
|
||
Point = namedtuple("Point", ["x", "y"]) | ||
SIZE = 360 | ||
|
||
with open(sys.argv[1]) as f: | ||
points = [Point(*(int(c) for c in l.strip().split(","))) for l in f.readlines()] | ||
|
||
|
||
def _find_closest(points, x, y): | ||
dists = {} | ||
for p in points: | ||
dists[p] = abs(p.x - x) + abs(p.y - y) | ||
|
||
# Check if there's a single closest point or multiple. | ||
point, min_ = min(dists.items(), key=lambda x: x[1]) | ||
for p, dist in dists.items(): | ||
if dist == min_ and point != p: | ||
# Found multiple closest points, return None | ||
return None | ||
return point | ||
|
||
|
||
def _is_inf(region): | ||
for x, y in region: | ||
if x == 0 or y == 0 or y == SIZE - 1 or x == SIZE - 1: | ||
return True | ||
return False | ||
|
||
|
||
grid = {p: set() for p in points} | ||
grid[None] = set() | ||
for x in range(SIZE): | ||
for y in range(SIZE): | ||
closest = _find_closest(points, x, y) | ||
grid[closest].add((x, y)) | ||
|
||
not_inf = set(p for p, c in grid.items() if not _is_inf(c)) | ||
print(max(len(grid[p]) for p in not_inf)) | ||
|
||
|
||
lt10000 = 0 | ||
for x in range(SIZE): | ||
for y in range(SIZE): | ||
mh_dists = sum(abs(p.x - x) + abs(p.y - y) for p in points) | ||
if mh_dists < 10000: | ||
lt10000 += 1 | ||
print(lt10000) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
181, 47 | ||
337, 53 | ||
331, 40 | ||
137, 57 | ||
200, 96 | ||
351, 180 | ||
157, 332 | ||
113, 101 | ||
285, 55 | ||
189, 188 | ||
174, 254 | ||
339, 81 | ||
143, 61 | ||
131, 155 | ||
239, 334 | ||
357, 291 | ||
290, 89 | ||
164, 149 | ||
248, 73 | ||
311, 190 | ||
54, 217 | ||
285, 268 | ||
354, 113 | ||
318, 191 | ||
182, 230 | ||
156, 252 | ||
114, 232 | ||
159, 299 | ||
324, 280 | ||
152, 155 | ||
295, 293 | ||
194, 214 | ||
252, 345 | ||
233, 172 | ||
272, 311 | ||
230, 82 | ||
62, 160 | ||
275, 96 | ||
335, 215 | ||
185, 347 | ||
134, 272 | ||
58, 113 | ||
112, 155 | ||
220, 83 | ||
153, 244 | ||
279, 149 | ||
302, 167 | ||
185, 158 | ||
72, 91 | ||
264, 67 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import copy | ||
import sys | ||
import re | ||
from collections import defaultdict | ||
|
||
RE_IN = re.compile(r"^Step (.).*step (.).*$") | ||
|
||
|
||
nodes = set() | ||
graph = defaultdict(list) | ||
with open(sys.argv[1]) as f: | ||
for line in f: | ||
m = RE_IN.match(line) | ||
assert m is not None | ||
graph[m.group(2)].append(m.group(1)) | ||
nodes.add(m.group(1)) | ||
nodes.add(m.group(2)) | ||
|
||
|
||
def _find_available_nodes(nodes, graph): | ||
return [n for n in sorted(nodes) if not graph[n]] | ||
|
||
|
||
def part1(nodes, graph): | ||
order = [] | ||
while nodes: | ||
n = _find_available_nodes(nodes, graph)[0] | ||
order.append(n) | ||
nodes.remove(n) | ||
for child, parent in graph.items(): | ||
if n in parent: | ||
graph[child].remove(n) | ||
return "".join(order) | ||
|
||
|
||
print(part1(set(nodes), copy.deepcopy(graph))) | ||
|
||
# | ||
# Part 2 | ||
WORKERS = 5 | ||
DURATION = 60 | ||
|
||
|
||
def part2(nodes, graph): | ||
second = 0 | ||
start = defaultdict(int) | ||
|
||
working = [] | ||
while nodes or working: | ||
for n in working: | ||
if second >= start[n] + DURATION + (ord(n) - ord("A") + 1): | ||
working.remove(n) | ||
for ch, parents in graph.items(): | ||
if n in parents: | ||
graph[ch].remove(n) | ||
nodes.remove(n) | ||
|
||
ns = _find_available_nodes(nodes, graph) | ||
candidates = set(ns) - set(working) if len(working) < WORKERS else {} | ||
for n in candidates: | ||
if n not in working: | ||
start[n] = second | ||
working.append(n) | ||
|
||
second += 1 | ||
|
||
return second - 1 | ||
|
||
|
||
print(part2(nodes, graph)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
Step C must be finished before step P can begin. | ||
Step V must be finished before step Q can begin. | ||
Step T must be finished before step X can begin. | ||
Step B must be finished before step U can begin. | ||
Step Z must be finished before step O can begin. | ||
Step P must be finished before step I can begin. | ||
Step D must be finished before step G can begin. | ||
Step A must be finished before step Y can begin. | ||
Step R must be finished before step O can begin. | ||
Step J must be finished before step E can begin. | ||
Step N must be finished before step S can begin. | ||
Step X must be finished before step H can begin. | ||
Step F must be finished before step L can begin. | ||
Step S must be finished before step I can begin. | ||
Step W must be finished before step Q can begin. | ||
Step H must be finished before step K can begin. | ||
Step K must be finished before step Q can begin. | ||
Step E must be finished before step L can begin. | ||
Step Q must be finished before step O can begin. | ||
Step U must be finished before step G can begin. | ||
Step L must be finished before step O can begin. | ||
Step Y must be finished before step G can begin. | ||
Step G must be finished before step I can begin. | ||
Step M must be finished before step I can begin. | ||
Step I must be finished before step O can begin. | ||
Step A must be finished before step N can begin. | ||
Step H must be finished before step O can begin. | ||
Step T must be finished before step O can begin. | ||
Step H must be finished before step U can begin. | ||
Step A must be finished before step I can begin. | ||
Step B must be finished before step R can begin. | ||
Step V must be finished before step T can begin. | ||
Step H must be finished before step M can begin. | ||
Step C must be finished before step A can begin. | ||
Step B must be finished before step G can begin. | ||
Step L must be finished before step Y can begin. | ||
Step T must be finished before step J can begin. | ||
Step A must be finished before step R can begin. | ||
Step X must be finished before step L can begin. | ||
Step B must be finished before step L can begin. | ||
Step A must be finished before step F can begin. | ||
Step K must be finished before step O can begin. | ||
Step W must be finished before step M can begin. | ||
Step Z must be finished before step N can begin. | ||
Step Z must be finished before step S can begin. | ||
Step R must be finished before step K can begin. | ||
Step Q must be finished before step L can begin. | ||
Step G must be finished before step O can begin. | ||
Step F must be finished before step Y can begin. | ||
Step V must be finished before step H can begin. | ||
Step E must be finished before step I can begin. | ||
Step W must be finished before step Y can begin. | ||
Step U must be finished before step I can begin. | ||
Step F must be finished before step K can begin. | ||
Step M must be finished before step O can begin. | ||
Step Z must be finished before step H can begin. | ||
Step X must be finished before step S can begin. | ||
Step J must be finished before step O can begin. | ||
Step B must be finished before step I can begin. | ||
Step F must be finished before step H can begin. | ||
Step D must be finished before step U can begin. | ||
Step E must be finished before step M can begin. | ||
Step Z must be finished before step X can begin. | ||
Step P must be finished before step L can begin. | ||
Step W must be finished before step H can begin. | ||
Step C must be finished before step D can begin. | ||
Step A must be finished before step X can begin. | ||
Step Q must be finished before step I can begin. | ||
Step R must be finished before step Y can begin. | ||
Step B must be finished before step A can begin. | ||
Step N must be finished before step L can begin. | ||
Step H must be finished before step G can begin. | ||
Step Y must be finished before step M can begin. | ||
Step L must be finished before step G can begin. | ||
Step G must be finished before step M can begin. | ||
Step Z must be finished before step R can begin. | ||
Step S must be finished before step Q can begin. | ||
Step P must be finished before step J can begin. | ||
Step V must be finished before step J can begin. | ||
Step J must be finished before step I can begin. | ||
Step J must be finished before step X can begin. | ||
Step W must be finished before step O can begin. | ||
Step B must be finished before step F can begin. | ||
Step R must be finished before step M can begin. | ||
Step V must be finished before step S can begin. | ||
Step H must be finished before step E can begin. | ||
Step E must be finished before step U can begin. | ||
Step R must be finished before step W can begin. | ||
Step X must be finished before step Q can begin. | ||
Step N must be finished before step G can begin. | ||
Step T must be finished before step I can begin. | ||
Step L must be finished before step M can begin. | ||
Step H must be finished before step I can begin. | ||
Step U must be finished before step M can begin. | ||
Step C must be finished before step H can begin. | ||
Step P must be finished before step H can begin. | ||
Step J must be finished before step F can begin. | ||
Step A must be finished before step O can begin. | ||
Step X must be finished before step M can begin. | ||
Step H must be finished before step L can begin. | ||
Step W must be finished before step K can begin. |