2019 day 16 wip
This commit is contained in:
137
2019/d16.py
137
2019/d16.py
@@ -1,8 +1,32 @@
|
|||||||
from lib import get_data
|
from lib import get_data
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
|
|
||||||
def phase(digits_in, pattern):
|
def part_1_with_numpy(data):
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
def make_base_matrix(pattern, n):
|
||||||
|
xss = []
|
||||||
|
for round in range(n):
|
||||||
|
xs = [
|
||||||
|
pattern[((i + 1) // (round + 1)) % len(pattern)]
|
||||||
|
for i in range(n)
|
||||||
|
]
|
||||||
|
xss.append(xs)
|
||||||
|
return np.array(xss)
|
||||||
|
|
||||||
|
pattern = [0, 1, 0, -1]
|
||||||
|
input = int(data.strip())
|
||||||
|
v = np.array(list(map(int, str(input))))
|
||||||
|
m = make_base_matrix(pattern, len(v))
|
||||||
|
func = np.vectorize(lambda x: abs(x) % 10)
|
||||||
|
|
||||||
|
for _ in range(100):
|
||||||
|
v = func(np.dot(m, v))
|
||||||
|
print("".join(map(str, v[:8].tolist())))
|
||||||
|
|
||||||
|
|
||||||
|
def phase(digits_in):
|
||||||
|
pattern = [0, 1, 0, -1]
|
||||||
digits_out = []
|
digits_out = []
|
||||||
for round in range(len(digits_in)):
|
for round in range(len(digits_in)):
|
||||||
i, out = 0, 0
|
i, out = 0, 0
|
||||||
@@ -14,87 +38,78 @@ def phase(digits_in, pattern):
|
|||||||
digits_out.append(out)
|
digits_out.append(out)
|
||||||
return digits_out
|
return digits_out
|
||||||
|
|
||||||
def make_base_matrix(pattern, n):
|
|
||||||
xss = []
|
|
||||||
for round in range(n):
|
|
||||||
xs = [
|
|
||||||
pattern[((i + 1) // (round + 1)) % len(pattern)]
|
|
||||||
for i in range(n)
|
|
||||||
]
|
|
||||||
xss.append(xs)
|
|
||||||
return np.array(xss)
|
|
||||||
|
|
||||||
# for round in range(len(digits_in)):
|
def phase_with_offset(digits_in, pattern, offset):
|
||||||
# i, out = 0, 0
|
digits_out = digits_in.copy()
|
||||||
# while i < len(digits_in):
|
for round in range(offset, len(digits_in)):
|
||||||
# pattern_i = ((i + 1) // (round + 1)) % len(pattern)
|
i, out = 0, 0
|
||||||
|
print(round)
|
||||||
|
|
||||||
|
pattern_value = pattern[((i + 1) // (round + 1)) % len(pattern)]
|
||||||
|
if pattern_value == 0:
|
||||||
|
i += round
|
||||||
|
|
||||||
|
while i < len(digits_in):
|
||||||
|
pattern_i = ((i + 1) // (round + 1)) % len(pattern)
|
||||||
|
pattern_value = pattern[pattern_i]
|
||||||
|
if pattern_value != 0:
|
||||||
|
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))):
|
||||||
|
# out += (pattern_value * digits_in[j])
|
||||||
|
i += (round + 1)
|
||||||
|
|
||||||
|
out = abs(out) % 10
|
||||||
|
digits_out[round] = out
|
||||||
|
|
||||||
|
return digits_out
|
||||||
|
|
||||||
def phase(matrix, vector):
|
|
||||||
return matrix * vector
|
|
||||||
|
|
||||||
def part_1(data):
|
def part_1(data):
|
||||||
pattern = [0, 1, 0, -1]
|
pattern = [0, 1, 0, -1]
|
||||||
|
|
||||||
input = int(data.strip())
|
input = list(map(int, (data.strip())))
|
||||||
v = np.array(list(map(int, str(input))))
|
|
||||||
m = make_base_matrix(pattern, len(v))
|
|
||||||
func = np.vectorize(lambda x: abs(x) % 10)
|
|
||||||
|
|
||||||
for _ in range(100):
|
for _ in range(100):
|
||||||
v = func(np.dot(m, v))
|
input = phase_with_offset(input, pattern, 0)
|
||||||
print("".join(map(str, v[:8].tolist())))
|
|
||||||
|
|
||||||
input = int(data.strip())
|
|
||||||
# input = 12345678
|
|
||||||
v = np.array(list(map(int, str(input))) * 10000)
|
|
||||||
print(len(v), v.shape)
|
|
||||||
return
|
|
||||||
m = make_base_matrix(pattern, len(v))
|
|
||||||
print(m.shape)
|
|
||||||
func = np.vectorize(lambda x: abs(x) % 10)
|
|
||||||
|
|
||||||
for i in range(100):
|
|
||||||
print(i)
|
|
||||||
v = func(np.dot(m, v))
|
|
||||||
print("".join(map(str, v[:8].tolist())))
|
|
||||||
|
|
||||||
return
|
|
||||||
for _ in range(100):
|
|
||||||
input = phase(input, pattern)
|
|
||||||
print("".join(map(str, input[:8])))
|
print("".join(map(str, input[:8])))
|
||||||
|
|
||||||
input = int(data.strip())
|
input = list(map(int, (data.strip()))) * 10_000
|
||||||
input = list(map(int, str(input)))
|
offset = int("".join(map(str, input[:7]))) - 200
|
||||||
offset = int("".join(map(str, input[:7])))
|
|
||||||
print(len(input))
|
|
||||||
input = input * 10_000
|
|
||||||
print(len(input))
|
|
||||||
|
|
||||||
for i in range(100):
|
for i in range(100):
|
||||||
print(i)
|
print(i)
|
||||||
input = phase(input, pattern)
|
input = phase_with_offset(input, pattern, offset)
|
||||||
|
print(input)
|
||||||
|
|
||||||
r = []
|
return
|
||||||
for i in range(offset, offset + 8):
|
|
||||||
r.append(input[i])
|
|
||||||
|
|
||||||
print("".join(map(str, r)))
|
|
||||||
|
|
||||||
|
# What do I know?
|
||||||
|
#
|
||||||
|
# 1. There is a solution. Other people have solved it.
|
||||||
|
# 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.
|
||||||
|
# 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,
|
||||||
|
# how exactly do we do that?
|
||||||
|
#
|
||||||
# Ways to improve performance:
|
# Ways to improve performance:
|
||||||
#
|
#
|
||||||
# 1. Speed up `phase` significantly.
|
# 1. Speed up `phase` significantly. Yes, but how?
|
||||||
# 2. Only compute a subset of the lists?
|
# 2. Only compute a subset of the lists? - No!
|
||||||
# 3. Discover some kind of pattern?
|
# 3. Discover some kind of pattern? - No!
|
||||||
#
|
#
|
||||||
# Assumptions:
|
# Assumptions:
|
||||||
#
|
#
|
||||||
# 1. I need every digit of the previous round.
|
# 1. I need every digit of the previous round. - False!
|
||||||
# 2. I cannot just operate on a subset.
|
# 2. I cannot just operate on a subset. - False!
|
||||||
# 3.
|
#
|
||||||
|
# Non-approaches:
|
||||||
|
#
|
||||||
|
# 1. Fancy recursive algorithm that selectively picks fields.
|
||||||
|
# 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(data)
|
part_1(data)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user