python: Submit Python solutions
This commit is contained in:
parent
9e01e0dd90
commit
87fdcce197
7 changed files with 351 additions and 0 deletions
48
python/day07.py
Normal file
48
python/day07.py
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
import fileinput
|
||||||
|
import re
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
network = {}
|
||||||
|
reverse = defaultdict(list)
|
||||||
|
|
||||||
|
for line in fileinput.input():
|
||||||
|
parent, children = line.strip().split(" contain ")
|
||||||
|
parent = parent[:-5]
|
||||||
|
children = children.rstrip(".").split(", ")
|
||||||
|
children = [
|
||||||
|
child.rstrip("s")[:-4].split(" ", 1)
|
||||||
|
for child in children
|
||||||
|
if "no other" not in child
|
||||||
|
]
|
||||||
|
children = [(int(n), c) for n, c in children]
|
||||||
|
|
||||||
|
network[parent] = children
|
||||||
|
for n, child in children:
|
||||||
|
reverse[child].append((n, parent))
|
||||||
|
|
||||||
|
reverse = dict(reverse)
|
||||||
|
|
||||||
|
shiny_gold_bags = set()
|
||||||
|
stack = ["shiny gold"]
|
||||||
|
while stack:
|
||||||
|
color = stack.pop()
|
||||||
|
if color not in reverse:
|
||||||
|
continue
|
||||||
|
for _, parent in reverse[color]:
|
||||||
|
stack.append(parent)
|
||||||
|
shiny_gold_bags.add(parent)
|
||||||
|
|
||||||
|
print("part 1:", len(shiny_gold_bags))
|
||||||
|
|
||||||
|
part2 = 0
|
||||||
|
stack = [(1, "shiny gold")]
|
||||||
|
while stack:
|
||||||
|
n, color = stack.pop()
|
||||||
|
part2 += n
|
||||||
|
|
||||||
|
children = network[color]
|
||||||
|
for m, child in children:
|
||||||
|
stack.append((n * m, child))
|
||||||
|
part2 -= 1
|
||||||
|
|
||||||
|
print("part 2:", part2)
|
22
python/day09-a.py
Normal file
22
python/day09-a.py
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import fileinput
|
||||||
|
import itertools
|
||||||
|
|
||||||
|
N = 25
|
||||||
|
|
||||||
|
numbers = []
|
||||||
|
for line in fileinput.input():
|
||||||
|
numbers.append(int(line))
|
||||||
|
|
||||||
|
for i in range(N, len(numbers)):
|
||||||
|
found = False
|
||||||
|
for j in numbers[i - N:i]:
|
||||||
|
for k in numbers[i - N:i]:
|
||||||
|
if j == k:
|
||||||
|
continue
|
||||||
|
if j + k == numbers[i]:
|
||||||
|
found = True
|
||||||
|
if not found:
|
||||||
|
print(numbers[i])
|
||||||
|
break
|
||||||
|
|
||||||
|
|
22
python/day09-b.py
Normal file
22
python/day09-b.py
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import fileinput
|
||||||
|
import itertools
|
||||||
|
import sys
|
||||||
|
|
||||||
|
N = 25
|
||||||
|
|
||||||
|
numbers = []
|
||||||
|
for line in fileinput.input():
|
||||||
|
numbers.append(int(line))
|
||||||
|
|
||||||
|
for i in range(N, len(numbers)):
|
||||||
|
target = 25918798
|
||||||
|
#target=127
|
||||||
|
for j in range(i - N,i):
|
||||||
|
for k in range(j+ 1, i):
|
||||||
|
nn = numbers[j:k]
|
||||||
|
if sum(nn) == target:
|
||||||
|
print(max(nn) + min(nn))
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
38
python/day10.py
Normal file
38
python/day10.py
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import fileinput
|
||||||
|
import itertools
|
||||||
|
from collections import deque
|
||||||
|
|
||||||
|
adapters = [0]
|
||||||
|
for line in fileinput.input():
|
||||||
|
adapters.append(int(line))
|
||||||
|
adapters.sort()
|
||||||
|
adapters.append(adapters[-1] + 3)
|
||||||
|
|
||||||
|
one = 0
|
||||||
|
three = 0
|
||||||
|
|
||||||
|
for (fr, to) in zip(adapters[:-1], adapters[1:]):
|
||||||
|
if to - fr == 1:
|
||||||
|
one += 1
|
||||||
|
elif to - fr == 3:
|
||||||
|
three += 1
|
||||||
|
print(fr, to)
|
||||||
|
|
||||||
|
print(one, three, one * three)
|
||||||
|
paths = [0] * len(adapters)
|
||||||
|
paths[0] = 1
|
||||||
|
|
||||||
|
ways = 1
|
||||||
|
for i, value in enumerate(adapters[:-1]):
|
||||||
|
try:
|
||||||
|
if adapters[i + 1] <= value + 3:
|
||||||
|
paths[i + 1] += paths[i]
|
||||||
|
if adapters[i + 2] <= value + 3:
|
||||||
|
paths[i + 2] += paths[i]
|
||||||
|
if adapters[i + 3] <= value + 3:
|
||||||
|
paths[i + 3] += paths[i]
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
print(paths)
|
||||||
|
print(paths[-1])
|
118
python/day11.py
Normal file
118
python/day11.py
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
import fileinput
|
||||||
|
from pprint import pprint
|
||||||
|
from copy import deepcopy
|
||||||
|
|
||||||
|
layout = []
|
||||||
|
for line in fileinput.input():
|
||||||
|
if line.strip():
|
||||||
|
layout.append(list(line.strip()))
|
||||||
|
|
||||||
|
part1 = -1
|
||||||
|
old_layout = deepcopy(layout)
|
||||||
|
row_length = len(old_layout[0])
|
||||||
|
|
||||||
|
while True:
|
||||||
|
new_layout = [[None] * len(row) for row in old_layout]
|
||||||
|
for y in range(len(old_layout)):
|
||||||
|
for x in range(len(old_layout[0])):
|
||||||
|
if old_layout[y][x] == ".":
|
||||||
|
new_layout[y][x] = old_layout[y][x]
|
||||||
|
continue
|
||||||
|
|
||||||
|
count = sum(
|
||||||
|
(
|
||||||
|
x >= 1 and old_layout[y][x - 1] == "#",
|
||||||
|
x < row_length - 1 and old_layout[y][x + 1] == "#",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if y >= 1:
|
||||||
|
count += sum(
|
||||||
|
(
|
||||||
|
x >= 1 and old_layout[y - 1][x - 1] == "#",
|
||||||
|
old_layout[y - 1][x] == "#",
|
||||||
|
x < row_length - 1 and old_layout[y - 1][x + 1] == "#",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if y < len(layout) - 1:
|
||||||
|
count += sum(
|
||||||
|
(
|
||||||
|
x >= 1 and old_layout[y + 1][x - 1] == "#",
|
||||||
|
old_layout[y + 1][x] == "#",
|
||||||
|
x < row_length - 1 and old_layout[y + 1][x + 1] == "#",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if count == 0:
|
||||||
|
new_layout[y][x] = "#"
|
||||||
|
elif count >= 4:
|
||||||
|
new_layout[y][x] = "L"
|
||||||
|
else:
|
||||||
|
new_layout[y][x] = old_layout[y][x]
|
||||||
|
|
||||||
|
new_part1 = sum(sum(s == "#" for s in row) for row in new_layout)
|
||||||
|
if part1 == new_part1:
|
||||||
|
break
|
||||||
|
part1 = new_part1
|
||||||
|
|
||||||
|
old_layout = new_layout
|
||||||
|
|
||||||
|
print(part1)
|
||||||
|
|
||||||
|
|
||||||
|
part2 = -1
|
||||||
|
old_layout = deepcopy(layout)
|
||||||
|
|
||||||
|
|
||||||
|
def get(x, y, dx, dy):
|
||||||
|
try:
|
||||||
|
x += dx
|
||||||
|
y += dy
|
||||||
|
while old_layout[y][x] == ".":
|
||||||
|
if x < 0 or y < 0:
|
||||||
|
raise IndexError
|
||||||
|
x += dx
|
||||||
|
y += dy
|
||||||
|
except:
|
||||||
|
return "."
|
||||||
|
|
||||||
|
return old_layout[y][x]
|
||||||
|
|
||||||
|
|
||||||
|
while True:
|
||||||
|
new_layout = [[None] * len(row) for row in old_layout]
|
||||||
|
for y in range(1, len(old_layout) - 1):
|
||||||
|
for x in range(1, len(old_layout[0]) - 1):
|
||||||
|
if old_layout[y][x] == ".":
|
||||||
|
new_layout[y][x] = old_layout[y][x]
|
||||||
|
continue
|
||||||
|
|
||||||
|
count = sum(
|
||||||
|
(
|
||||||
|
get(x, y, -1, -1) == "#",
|
||||||
|
get(x, y, -1, 0) == "#",
|
||||||
|
get(x, y, -1, 1) == "#",
|
||||||
|
get(x, y, 0, -1) == "#",
|
||||||
|
get(x, y, 0, 1) == "#",
|
||||||
|
get(x, y, 1, -1) == "#",
|
||||||
|
get(x, y, 1, 0) == "#",
|
||||||
|
get(x, y, 1, 1) == "#",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if count == 0:
|
||||||
|
new_layout[y][x] = "#"
|
||||||
|
elif count >= 5:
|
||||||
|
new_layout[y][x] = "L"
|
||||||
|
else:
|
||||||
|
new_layout[y][x] = old_layout[y][x]
|
||||||
|
|
||||||
|
new_part2 = sum(sum(s == "#" for s in row) for row in new_layout)
|
||||||
|
if part2 == new_part2:
|
||||||
|
break
|
||||||
|
part2 = new_part2
|
||||||
|
|
||||||
|
old_layout = new_layout
|
||||||
|
|
||||||
|
print(part2)
|
48
python/day13.py
Normal file
48
python/day13.py
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
import fileinput
|
||||||
|
|
||||||
|
input = fileinput.input()
|
||||||
|
|
||||||
|
arrival = int(next(input))
|
||||||
|
buses = [None if bus == "x" else int(bus) for bus in next(input).split(",")]
|
||||||
|
print(arrival, buses)
|
||||||
|
|
||||||
|
remainders = [-(arrival % (-bus)) if bus else float("inf") for bus in buses]
|
||||||
|
print(remainders)
|
||||||
|
|
||||||
|
print(
|
||||||
|
"Part 1:",
|
||||||
|
min(enumerate(buses), key=lambda x: remainders[x[0]])[1] * min(remainders),
|
||||||
|
)
|
||||||
|
|
||||||
|
def combine(a_period, a_offset, b_period, b_offset):
|
||||||
|
gcd, s, _ = egcd(a_period, b_period)
|
||||||
|
diff = a_offset - b_offset
|
||||||
|
diff_quot, dif_rem = divmod(diff, gcd)
|
||||||
|
assert(dif_rem == 0)
|
||||||
|
|
||||||
|
combined_period = a_period // gcd * b_period
|
||||||
|
combined_offset = (a_offset - s * diff_quot * a_period) % combined_period
|
||||||
|
return combined_period, combined_offset
|
||||||
|
|
||||||
|
def egcd(a, b):
|
||||||
|
r_, r = a, b
|
||||||
|
s_, s = 1, 0
|
||||||
|
t_, t = 0, 1
|
||||||
|
while r:
|
||||||
|
quot, rem = divmod(r_, r)
|
||||||
|
r_, r = r, rem
|
||||||
|
s_, s = s, (s_ - quot * s)
|
||||||
|
t_, t = t, (t_ - quot * t)
|
||||||
|
return r_, s_, t_
|
||||||
|
|
||||||
|
period = 1
|
||||||
|
offset = 0
|
||||||
|
|
||||||
|
for i, bus in enumerate(buses):
|
||||||
|
if bus is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
period, offset = combine(period, offset, bus, i)
|
||||||
|
print(i, bus, period, offset)
|
||||||
|
|
||||||
|
print(-offset % period)
|
55
python/day14.py
Normal file
55
python/day14.py
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import fileinput
|
||||||
|
from pprint import pprint
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
mem = {}
|
||||||
|
for line in fileinput.input():
|
||||||
|
l, r = line.strip().split(" = ")
|
||||||
|
if l == "mask":
|
||||||
|
and_mask = int(r.replace("X", "1"), base=2)
|
||||||
|
or_mask = int(r.replace("X", "0"), base=2)
|
||||||
|
else:
|
||||||
|
value = int(r)
|
||||||
|
value &= and_mask
|
||||||
|
value |= or_mask
|
||||||
|
mem[int(l[4:-1])] = value
|
||||||
|
|
||||||
|
print(sum(mem.values()))
|
||||||
|
|
||||||
|
def recurse(s: str) -> List[str]:
|
||||||
|
x = s.find("X")
|
||||||
|
if x == -1:
|
||||||
|
return [s]
|
||||||
|
|
||||||
|
s0 = s[:x] + '0' + s[x + 1:]
|
||||||
|
s1 = s[:x] + '1' + s[x + 1:]
|
||||||
|
|
||||||
|
return [*recurse(s0), *recurse(s1)]
|
||||||
|
|
||||||
|
mem = {}
|
||||||
|
for line in fileinput.input():
|
||||||
|
l, r = line.strip().split(" = ")
|
||||||
|
|
||||||
|
if l == "mask":
|
||||||
|
mask = r
|
||||||
|
or_mask = int(r.replace("X", "0"), base=2)
|
||||||
|
|
||||||
|
floatings = recurse(r.replace("0", "_").replace("1", "_"))
|
||||||
|
and_masks = [int(v.replace("_", "1"), 2) for v in floatings]
|
||||||
|
or_masks = [int(v.replace("_", "0"), 2) for v in floatings]
|
||||||
|
|
||||||
|
assert(len(and_masks) == 2 ** r.count("X"))
|
||||||
|
assert(len(or_masks) == 2 ** r.count("X"))
|
||||||
|
else:
|
||||||
|
orig_address = int(l[4:-1])
|
||||||
|
orig_address |= or_mask
|
||||||
|
|
||||||
|
for (and_, or_) in zip(and_masks, or_masks):
|
||||||
|
address = orig_address
|
||||||
|
address &= and_
|
||||||
|
address |= or_
|
||||||
|
mem[address] = int(r)
|
||||||
|
assert(address >= 0)
|
||||||
|
|
||||||
|
assert(not [k for k in mem.keys() if k < 0])
|
||||||
|
print(sum(mem.values()))
|
Loading…
Reference in a new issue