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