2019 day 16 and 17 wip
This commit is contained in:
26
2019/d16.py
26
2019/d16.py
@@ -7,10 +7,7 @@ def part_1_with_numpy(data):
|
|||||||
def make_base_matrix(pattern, n):
|
def make_base_matrix(pattern, n):
|
||||||
xss = []
|
xss = []
|
||||||
for round in range(n):
|
for round in range(n):
|
||||||
xs = [
|
xs = [pattern[((i + 1) // (round + 1)) % len(pattern)] for i in range(n)]
|
||||||
pattern[((i + 1) // (round + 1)) % len(pattern)]
|
|
||||||
for i in range(n)
|
|
||||||
]
|
|
||||||
xss.append(xs)
|
xss.append(xs)
|
||||||
return np.array(xss)
|
return np.array(xss)
|
||||||
|
|
||||||
@@ -32,7 +29,7 @@ def phase(digits_in):
|
|||||||
i, out = 0, 0
|
i, out = 0, 0
|
||||||
while i < len(digits_in):
|
while i < len(digits_in):
|
||||||
pattern_i = ((i + 1) // (round + 1)) % len(pattern)
|
pattern_i = ((i + 1) // (round + 1)) % len(pattern)
|
||||||
out += (pattern[pattern_i] * digits_in[i])
|
out += pattern[pattern_i] * digits_in[i]
|
||||||
i += 1
|
i += 1
|
||||||
out = abs(out) % 10
|
out = abs(out) % 10
|
||||||
digits_out.append(out)
|
digits_out.append(out)
|
||||||
@@ -53,10 +50,12 @@ def phase_with_offset(digits_in, pattern, offset):
|
|||||||
pattern_i = ((i + 1) // (round + 1)) % len(pattern)
|
pattern_i = ((i + 1) // (round + 1)) % len(pattern)
|
||||||
pattern_value = pattern[pattern_i]
|
pattern_value = pattern[pattern_i]
|
||||||
if pattern_value != 0:
|
if pattern_value != 0:
|
||||||
out += pattern_value * sum(digits_in[i : min(i + 1 + round, len(digits_in))])
|
out += pattern_value * sum(
|
||||||
|
digits_in[i : min(i + 1 + round, len(digits_in))]
|
||||||
|
)
|
||||||
# for j in range(i, min(i + 1 + round, len(digits_in))):
|
# for j in range(i, min(i + 1 + round, len(digits_in))):
|
||||||
# out += (pattern_value * digits_in[j])
|
# out += (pattern_value * digits_in[j])
|
||||||
i += (round + 1)
|
i += round + 1
|
||||||
|
|
||||||
out = abs(out) % 10
|
out = abs(out) % 10
|
||||||
digits_out[round] = out
|
digits_out[round] = out
|
||||||
@@ -88,25 +87,26 @@ def part_1(data):
|
|||||||
# 2. The solution is not crazy. It will be rather obvious.
|
# 2. The solution is not crazy. It will be rather obvious.
|
||||||
# 3. 6_500_000 * 6_500_000 is definitely too much to brute force.
|
# 3. 6_500_000 * 6_500_000 is definitely too much to brute force.
|
||||||
# 4. Can we go from O(N^2) to O(N) somehow? Yes, that's what we have to do.
|
# 4. Can we go from O(N^2) to O(N) somehow? Yes, that's what we have to do.
|
||||||
# The whole point of FFT is to get from O(N^2) to O(N*log(N)). Now,
|
# The whole point of FFT is to get from O(N^2) to O(N*log(N)). Now,
|
||||||
# how exactly do we do that?
|
# how exactly do we do that?
|
||||||
#
|
#
|
||||||
# Ways to improve performance:
|
# Ways to improve performance:
|
||||||
#
|
#
|
||||||
# 1. Speed up `phase` significantly. Yes, but how?
|
# 1. Speed up `phase` significantly. Yes, but how?
|
||||||
# 2. Only compute a subset of the lists? - No!
|
# 2. Only compute a subset of the lists? - No!
|
||||||
# 3. Discover some kind of pattern? - No!
|
# 3. Discover some kind of pattern? - No!
|
||||||
#
|
#
|
||||||
# Assumptions:
|
# Assumptions:
|
||||||
#
|
#
|
||||||
# 1. I need every digit of the previous round. - False!
|
# 1. I need every digit of the previous round. - False!
|
||||||
# 2. I cannot just operate on a subset. - False!
|
# 2. I cannot just operate on a subset. - False!
|
||||||
#
|
#
|
||||||
# Non-approaches:
|
# Non-approaches:
|
||||||
#
|
#
|
||||||
# 1. Fancy recursive algorithm that selectively picks fields.
|
# 1. Fancy recursive algorithm that selectively picks fields.
|
||||||
# 2. Pattern detection or subset consideration.
|
# 2. Pattern detection or subset consideration.
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
data = get_data(__file__)
|
data = get_data(__file__)
|
||||||
# part_1_with_numpy(data)
|
# part_1_with_numpy(data)
|
||||||
|
|||||||
100
2019/d17.py
Normal file
100
2019/d17.py
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
from lib import get_data, str_to_ints, Grid2D, add2
|
||||||
|
from collections import defaultdict
|
||||||
|
from d9 import Amp
|
||||||
|
|
||||||
|
DIRS = [
|
||||||
|
(-1, 0),
|
||||||
|
(0, 1),
|
||||||
|
(1, 0),
|
||||||
|
(0, -1),
|
||||||
|
]
|
||||||
|
|
||||||
|
DIRCHAR = list("^>v<")
|
||||||
|
|
||||||
|
|
||||||
|
def find_path(g):
|
||||||
|
(pos,) = g.find("^><v")
|
||||||
|
assert g[pos] == "^"
|
||||||
|
|
||||||
|
to_visit = set(g.find("#"))
|
||||||
|
seen = defaultdict(int)
|
||||||
|
dir = DIRS[0] # up
|
||||||
|
seen[pos] = 1
|
||||||
|
|
||||||
|
def best_neighbor(pos):
|
||||||
|
best_nb = None
|
||||||
|
seen_count = 20
|
||||||
|
for nb in g.neighbors_ort(pos):
|
||||||
|
if nb in to_visit:
|
||||||
|
return nb
|
||||||
|
if nb in seen and seen[nb] < seen_count:
|
||||||
|
seen_count = seen[nb]
|
||||||
|
best_nb = nb
|
||||||
|
assert best_nb is not None
|
||||||
|
return best_nb
|
||||||
|
|
||||||
|
path = ""
|
||||||
|
while to_visit:
|
||||||
|
|
||||||
|
new_pos = add2(pos, dir)
|
||||||
|
if new_pos in to_visit or (new_pos in seen and seen[new_pos] < 2):
|
||||||
|
path += "F"
|
||||||
|
g[pos] = "#"
|
||||||
|
pos = new_pos
|
||||||
|
if pos in to_visit:
|
||||||
|
to_visit.remove(pos)
|
||||||
|
g[pos] = DIRCHAR[DIRS.index(dir)]
|
||||||
|
seen[pos] += 1
|
||||||
|
else:
|
||||||
|
best_nb = best_neighbor(pos)
|
||||||
|
while add2(pos, dir) != best_nb:
|
||||||
|
path += "R"
|
||||||
|
dir = DIRS[(DIRS.index(dir) + 1) % len(DIRS)]
|
||||||
|
g[pos] = DIRCHAR[DIRS.index(dir)]
|
||||||
|
g.print()
|
||||||
|
input()
|
||||||
|
print()
|
||||||
|
path = path.replace("RRR", "L")
|
||||||
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
def part_1(data):
|
||||||
|
xs = str_to_ints(data)
|
||||||
|
a = Amp(xs)
|
||||||
|
text = ""
|
||||||
|
while not a.done:
|
||||||
|
a.go()
|
||||||
|
while a.outputs:
|
||||||
|
o = a.pop()
|
||||||
|
text += chr(o)
|
||||||
|
|
||||||
|
result = 0
|
||||||
|
g = Grid2D(text)
|
||||||
|
for r in range(g.n_rows):
|
||||||
|
for c in range(g.n_cols):
|
||||||
|
nbs = g.neighbors_ort((r, c))
|
||||||
|
if (
|
||||||
|
g[(r, c)] == "#"
|
||||||
|
and len(nbs) == 4
|
||||||
|
and all([g[(nr, nc)] == "#" for nr, nc in nbs])
|
||||||
|
):
|
||||||
|
# g[(r, c)] = 'o'
|
||||||
|
result += r * c
|
||||||
|
print(result)
|
||||||
|
g.print()
|
||||||
|
path = find_path(g)
|
||||||
|
print(path)
|
||||||
|
|
||||||
|
# xs = str_to_ints(data)
|
||||||
|
# xs[0] = 2
|
||||||
|
# a = Amp(xs)
|
||||||
|
# a.go()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
data = get_data(__file__)
|
||||||
|
part_1(data)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -4,7 +4,7 @@ from lib import get_data, str_to_ints
|
|||||||
class Amp:
|
class Amp:
|
||||||
def __init__(self, xs):
|
def __init__(self, xs):
|
||||||
self.xs = list(xs)
|
self.xs = list(xs)
|
||||||
self.xs += [0 for _ in range(1000)]
|
self.xs += [0 for _ in range(10000)]
|
||||||
self.i = 0
|
self.i = 0
|
||||||
self.inputs = []
|
self.inputs = []
|
||||||
self.outputs = []
|
self.outputs = []
|
||||||
|
|||||||
Reference in New Issue
Block a user