Solve 2017 day 14 to 17.
This commit is contained in:
72
2017/d14.py
Normal file
72
2017/d14.py
Normal file
@@ -0,0 +1,72 @@
|
||||
from lib import Grid2D
|
||||
from d10 import part_2 as hash
|
||||
|
||||
|
||||
def to_bin(x):
|
||||
assert len(x) == 1
|
||||
xv = int(x, 16)
|
||||
c = 1
|
||||
r = ""
|
||||
for _ in range(4):
|
||||
if c & xv > 0:
|
||||
r = "1" + r
|
||||
else:
|
||||
r = "0" + r
|
||||
c = (c << 1)
|
||||
return r
|
||||
|
||||
def to_bits(xs):
|
||||
r = ""
|
||||
for x in xs:
|
||||
r += to_bin(x)
|
||||
return r
|
||||
|
||||
def part_1(data):
|
||||
r = 0
|
||||
for i in range(128):
|
||||
s = f"{data}-{i}"
|
||||
x = hash(s)
|
||||
b = to_bits(x)
|
||||
r += b.count("1")
|
||||
print(r)
|
||||
|
||||
|
||||
def part_2(data):
|
||||
grid = ""
|
||||
for i in range(128):
|
||||
s = f"{data}-{i}"
|
||||
x = hash(s)
|
||||
grid += to_bits(x)
|
||||
grid += "\n"
|
||||
|
||||
g = Grid2D(grid)
|
||||
|
||||
one_group_count = 0
|
||||
seen_ones = set()
|
||||
all_ones = g.find("1")
|
||||
for c in all_ones:
|
||||
if c in seen_ones:
|
||||
continue
|
||||
one_group_count += 1
|
||||
|
||||
current_group = [c]
|
||||
while current_group:
|
||||
c = current_group.pop()
|
||||
if c in seen_ones:
|
||||
continue
|
||||
seen_ones.add(c)
|
||||
|
||||
for nb in g.neighbors_ort(c):
|
||||
if g[nb] == "1":
|
||||
current_group.append(nb)
|
||||
print(one_group_count)
|
||||
|
||||
|
||||
def main():
|
||||
data = open(0).read().strip()
|
||||
part_1(data)
|
||||
part_2(data)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
59
2017/d15.py
Normal file
59
2017/d15.py
Normal file
@@ -0,0 +1,59 @@
|
||||
from lib import str_to_int
|
||||
|
||||
|
||||
def part_1(data):
|
||||
fa = 16807
|
||||
fb = 48271
|
||||
m = 2147483647
|
||||
|
||||
xs = []
|
||||
for line in data.splitlines():
|
||||
xs.append(str_to_int(line))
|
||||
a, b = xs
|
||||
|
||||
c = 0
|
||||
for _ in range(40_000_000):
|
||||
a = (a * fa) % m
|
||||
b = (b * fb) % m
|
||||
if (a & 0xffff) == (b & 0xffff):
|
||||
c += 1
|
||||
print(c)
|
||||
|
||||
|
||||
def gen(a, f, m, d):
|
||||
while True:
|
||||
a = (a * f) % m
|
||||
if a % d == 0:
|
||||
yield a
|
||||
|
||||
|
||||
def part_2(data):
|
||||
fa = 16807
|
||||
fb = 48271
|
||||
m = 2147483647
|
||||
|
||||
xs = []
|
||||
for line in data.splitlines():
|
||||
xs.append(str_to_int(line))
|
||||
a, b = xs
|
||||
|
||||
xs = gen(a, fa, m, 4)
|
||||
ys = gen(b, fb, m, 8)
|
||||
|
||||
c = 0
|
||||
for _ in range(5_000_000):
|
||||
a = next(xs)
|
||||
b = next(ys)
|
||||
if (a & 0xffff) == (b & 0xffff):
|
||||
c += 1
|
||||
print(c)
|
||||
|
||||
|
||||
def main():
|
||||
data = open(0).read().strip()
|
||||
part_1(data)
|
||||
part_2(data)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
60
2017/d16.py
Normal file
60
2017/d16.py
Normal file
@@ -0,0 +1,60 @@
|
||||
from lib import LETTERS_LOWER, str_to_int, str_to_ints
|
||||
|
||||
|
||||
def one_cycle(xs, insts):
|
||||
for inst in insts:
|
||||
if inst.startswith("s"):
|
||||
v = str_to_int(inst)
|
||||
if v != 0:
|
||||
xs = xs[-v:] + xs[:len(xs) - v]
|
||||
elif inst.startswith("x"):
|
||||
a, b = str_to_ints(inst)
|
||||
xs[a], xs[b] = xs[b], xs[a]
|
||||
elif inst.startswith("p"):
|
||||
la, lb = inst[1], inst[3]
|
||||
a, b = xs.index(la), xs.index(lb)
|
||||
xs[a], xs[b] = xs[b], xs[a]
|
||||
else:
|
||||
assert False
|
||||
return xs
|
||||
|
||||
|
||||
def part_1(data):
|
||||
xs = list(LETTERS_LOWER[:16])
|
||||
insts = data.split(",")
|
||||
xs = one_cycle(xs, insts)
|
||||
r = "".join(xs)
|
||||
print(r)
|
||||
|
||||
|
||||
def part_2(data):
|
||||
repeat = 10**9
|
||||
xs = list(LETTERS_LOWER[:16])
|
||||
insts = data.split(",")
|
||||
cycle = 0
|
||||
seen = {}
|
||||
for i in range(repeat):
|
||||
xs = one_cycle(xs, insts)
|
||||
xst = tuple(xs)
|
||||
if not xst in seen:
|
||||
seen[xst] = i
|
||||
else:
|
||||
cycle = (i - seen[xst])
|
||||
break
|
||||
|
||||
xs = list(LETTERS_LOWER[:16])
|
||||
repeat %= cycle
|
||||
for i in range(repeat):
|
||||
xs = one_cycle(xs, insts)
|
||||
r = "".join(xs)
|
||||
print(r)
|
||||
|
||||
|
||||
def main():
|
||||
data = open(0).read().strip()
|
||||
part_1(data)
|
||||
part_2(data)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
39
2017/d17.py
Normal file
39
2017/d17.py
Normal file
@@ -0,0 +1,39 @@
|
||||
def part_1(data):
|
||||
target = 2017
|
||||
steps = int(data)
|
||||
xs = [0]
|
||||
i = 0
|
||||
for n in range(1, target + 1):
|
||||
i = (i + steps) % len(xs)
|
||||
xs.insert(i + 1, n)
|
||||
i += 1
|
||||
|
||||
for j in range(len(xs)):
|
||||
if xs[j] == target:
|
||||
print(xs[j + 1])
|
||||
return
|
||||
|
||||
|
||||
def part_2(data, m=50_000_000):
|
||||
steps = int(data)
|
||||
len_xs = 1
|
||||
last_zero = None
|
||||
i = 0
|
||||
for n in range(1, m + 1):
|
||||
i = (i + steps) % len_xs
|
||||
if i == 0:
|
||||
last_zero = n
|
||||
len_xs += 1
|
||||
i += 1
|
||||
return last_zero
|
||||
|
||||
def main():
|
||||
data = open(0).read().strip()
|
||||
part_1(data)
|
||||
assert part_2(data, 1000) == 531
|
||||
assert part_2(data, 10000) == 2616
|
||||
print(part_2(data))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user