rename stuff
This commit is contained in:
1 parent
7c3d439f6e
commit
97ddc36b62
325 files changed
+85
No files matched your search
@@ -0,0 +1,20 @@
|
||||
with open(r"C:\Users\Maya\Desktop\Uni\WS_2021\AoC\input01") as f:
|
||||
lines = f.readlines()
|
||||
|
||||
# make ints out of strings
|
||||
numbers = ([0] * (len(lines) + 1))
|
||||
for n in range(0, len(lines)):
|
||||
numbers[n] = int(lines[n])
|
||||
|
||||
# challenge 1
|
||||
for i in range(0, len(numbers)):
|
||||
for j in range(i + 1, len(numbers)):
|
||||
if numbers[i] + numbers[j] == 2020:
|
||||
print(numbers[i] * numbers[j])
|
||||
|
||||
# challenge 2
|
||||
for i in range(0, len(numbers)):
|
||||
for j in range(i+1, len(numbers)):
|
||||
for k in range(j+1, len(numbers)):
|
||||
if numbers[i] + numbers[j] + numbers[k] == 2020:
|
||||
print(numbers[i] * numbers[j] * numbers[k])
|
||||
@@ -0,0 +1,49 @@
|
||||
|
||||
import re
|
||||
|
||||
|
||||
# decode line into bounds and letter and password
|
||||
def decode_line(l):
|
||||
groups = re.compile(r"(?P<lower>\d+)-(?P<higher>\d+) (?P<letter>\w): (?P<pwd>\w+)").search(l)
|
||||
return groups
|
||||
|
||||
|
||||
# check if valid with certain number of chars
|
||||
def check_if_valid(lower, higher, letter, pwd):
|
||||
if int(lower) <= pwd.count(letter) <= int(higher):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
# check if valid with chars on places
|
||||
def check_if_valid2(lower, higher, letter, pwd):
|
||||
# both = line.split(": ")
|
||||
# cond = both[0].split(" ")
|
||||
# times = cond[0].split("-")
|
||||
# lower = int(times[0])
|
||||
# higher = int(times[1])
|
||||
# letter = cond[1]
|
||||
# pwd = (both[1])[:-1]
|
||||
if (pwd[int(lower) - 1] == letter) != (pwd[int(higher) - 1] == letter):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
with open(r"C:\Users\Maya\Desktop\Uni\WS_2021\AoC\input02") as f:
|
||||
lines = f.readlines()
|
||||
|
||||
# count for challenge 1
|
||||
i = 0
|
||||
for line in lines:
|
||||
if check_if_valid(*decode_line(line).groups()):
|
||||
i += 1
|
||||
print(i)
|
||||
|
||||
# count for challenge 2
|
||||
i = 0
|
||||
for line in lines:
|
||||
if check_if_valid2(*decode_line(line).groups()):
|
||||
i += 1
|
||||
print(i)
|
||||
@@ -0,0 +1,41 @@
|
||||
|
||||
|
||||
# count trees when going 1 down and 2 right
|
||||
def tree_count(ls):
|
||||
x = 0
|
||||
trees = 0
|
||||
for y, line in enumerate(ls):
|
||||
if line[x] == '#':
|
||||
trees += 1
|
||||
x = (x + 3) % (len(line) - 1)
|
||||
return trees
|
||||
|
||||
|
||||
# count trees when going dx right and dy down
|
||||
def tree_count2(ls, dx, dy):
|
||||
x = 0
|
||||
y = 0
|
||||
trees = 0
|
||||
while True:
|
||||
try:
|
||||
if ls[y][x] == '#':
|
||||
trees += 1
|
||||
x = (x + dx) % (len(ls[y]) - 1)
|
||||
y = y + dy
|
||||
except IndexError:
|
||||
break
|
||||
return trees
|
||||
|
||||
|
||||
with open(r"C:\Users\Maya\Desktop\Uni\WS_2021\AoC\input03") as f:
|
||||
lines = f.readlines()
|
||||
|
||||
# Count trees on way down
|
||||
print(tree_count(lines))
|
||||
|
||||
# Multiply trees on different slopes
|
||||
print(tree_count2(lines, 1, 1) *
|
||||
tree_count2(lines, 3, 1) *
|
||||
tree_count2(lines, 5, 1) *
|
||||
tree_count2(lines, 7, 1) *
|
||||
tree_count2(lines, 1, 2))
|
||||
@@ -0,0 +1,78 @@
|
||||
import re
|
||||
|
||||
|
||||
# Valid Passport if all fields on it
|
||||
def valid_passport(line):
|
||||
# Must contain "byr:", "pid:", "iyr:". "eyr:", "hgt:" "hcl:" und "ecl:"
|
||||
contains = ["byr:", "pid:", "iyr:", "eyr:", "hgt:", "hcl:", "ecl:"]
|
||||
return all(i in line for i in contains)
|
||||
|
||||
|
||||
# Bene's function for height
|
||||
def valid_height(height):
|
||||
match = re.compile(r"(\d+)(cm|in)").search(height)
|
||||
if match is None: return False
|
||||
num, unit = match.groups()
|
||||
if unit == 'cm': return 150 <= int(num) <= 193
|
||||
if unit == 'in': return 59 <= int(num) <= 76
|
||||
return False
|
||||
|
||||
|
||||
# Valid passport if fields also contain fitting values
|
||||
def valid_passport2(line):
|
||||
# Must contain "byr:", "pid:", "iyr:". "eyr:", "hgt:" "hcl:" und "ecl:"
|
||||
contains = ["byr:", "pid:", "iyr:", "eyr:", "hgt:", "hcl:", "ecl:"]
|
||||
if all(i in line for i in contains):
|
||||
groups = re.compile(r"(?P<key>\w+):(?P<value>\S+)")
|
||||
for (key, value) in groups.findall(line):
|
||||
if key == "byr":
|
||||
if not (len(value) == 4 and (1920 <= int(value) <= 2002)):
|
||||
return False
|
||||
elif key == "iyr":
|
||||
if not (len(value) == 4 and (2010 <= int(value) <= 2020)):
|
||||
return False
|
||||
elif key == "eyr":
|
||||
if not (len(value) == 4 and (2020 <= int(value) <= 2030)):
|
||||
return False
|
||||
elif key == "hgt":
|
||||
pattern1 = re.compile(r"(1[5-8][0-9]|19[0-3])cm")
|
||||
pattern2 = re.compile(r"(59|6[0-9]|7[0-6])in")
|
||||
if not valid_height(value):
|
||||
return False
|
||||
elif key == "hcl":
|
||||
pattern = re.compile(r"#([0-9]|[a-f]){6}")
|
||||
if not pattern.match(value):
|
||||
return False
|
||||
elif key == "ecl":
|
||||
if value not in ["amb", "blu", "brn", "gry", "grn", "hzl", "oth"]:
|
||||
return False
|
||||
elif key == "pid":
|
||||
pattern = re.compile(r"\d{9}")
|
||||
if not (pattern.match(value) and len(value) == 9):
|
||||
return False
|
||||
else:
|
||||
if not key == "cid":
|
||||
return False
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
with open(r"C:\Users\Maya\Desktop\Uni\WS_2021\AoC\input04") as f:
|
||||
lines = f.read()
|
||||
lines = lines.replace("\n\n", '\t').replace("\n", " ").split("\t")
|
||||
|
||||
sum(valid_passport(p) for p in lines)
|
||||
|
||||
# count for challenge 1
|
||||
count = 0
|
||||
for l in lines:
|
||||
if valid_passport(l):
|
||||
count += 1
|
||||
print(count)
|
||||
|
||||
# count for challenge 2
|
||||
count2 = 0
|
||||
for l in lines:
|
||||
if valid_passport2(l):
|
||||
count2 += 1
|
||||
print(count2)
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
|
||||
# Get ID
|
||||
def to_binary(line):
|
||||
line = line.replace('B', '1').replace('F', '0').replace('R', '1').replace('L', '0')
|
||||
return int(line, 2)
|
||||
|
||||
|
||||
with open(r"C:\Users\Maya\Desktop\Uni\WS_2021\AoC\input05") as f:
|
||||
lines = f.readlines()
|
||||
nums = [to_binary(line) for line in lines]
|
||||
|
||||
# Find biggest seat-ID
|
||||
print(max(nums))
|
||||
|
||||
# Find missing seat-ID
|
||||
for num in nums:
|
||||
if (num in nums) and (num+2 in nums) and (num+1 not in nums):
|
||||
print(num+1)
|
||||
|
||||
for i in range(min(nums), max(nums)+1):
|
||||
if i not in nums:
|
||||
print(i)
|
||||
@@ -0,0 +1,32 @@
|
||||
|
||||
|
||||
# count answers in that group
|
||||
def count_answers(line):
|
||||
my_list = list(line)
|
||||
my_set = set(my_list)
|
||||
length = len(my_set)
|
||||
return length
|
||||
|
||||
|
||||
# count which answers were answered by all
|
||||
def count_answers_all(group):
|
||||
answers = group.split('\n')
|
||||
|
||||
z = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
|
||||
'u', 'v', 'w', 'x', 'y', 'z'}
|
||||
intersect = z.intersection(* [set(answer) for answer in answers if answer != ''])
|
||||
return len(intersect)
|
||||
|
||||
|
||||
with open(r"C:\Users\Maya\Desktop\Uni\WS_2021\AoC\input06") as f:
|
||||
lines = f.read()
|
||||
|
||||
# count answered letters
|
||||
lines1 = lines.replace("\n\n", '\t').replace("\n", "").split("\t")
|
||||
count = sum(count_answers(l) for l in lines1)
|
||||
print(count)
|
||||
|
||||
# count answered by all
|
||||
groups = lines.split("\n\n")
|
||||
count2 = sum(count_answers_all(g) for g in groups)
|
||||
print(count2)
|
||||
@@ -0,0 +1,61 @@
|
||||
import re
|
||||
|
||||
|
||||
# find colours and the colours it can contain
|
||||
def parse(l):
|
||||
group = re.compile(r"(?P<colour>.*?) bags contain").search(l)
|
||||
group2 = re.compile(r"(?P<number>\d+) (?P<colour>.*?) bag").findall(l)
|
||||
return group.group(1), group2
|
||||
|
||||
|
||||
# count what a bag of given colour can contain
|
||||
def containments(colour):
|
||||
if colour not in dic:
|
||||
memo[colour] = 0
|
||||
|
||||
if colour in memo:
|
||||
return memo[colour]
|
||||
|
||||
total = 0
|
||||
for (x, y) in dic[colour]:
|
||||
total += int(x) * containments(y)
|
||||
memo[colour] = total
|
||||
return total
|
||||
|
||||
|
||||
# count number of bags, that can be contained
|
||||
def number_bags(colour):
|
||||
if colour not in dic:
|
||||
memo2[colour] = 0
|
||||
|
||||
if colour in memo2:
|
||||
return memo2[colour]
|
||||
|
||||
total = 0
|
||||
for (x,y) in dic[colour]:
|
||||
total += int(x) + int(x) * number_bags(y)
|
||||
memo2[colour] = total
|
||||
return total
|
||||
|
||||
|
||||
with open(r"C:\Users\Maya\Desktop\Uni\WS_2021\AoC\input07") as f:
|
||||
lines = f.readlines()
|
||||
|
||||
# make dictionary with the values
|
||||
dic = {}
|
||||
for line in lines:
|
||||
key, value = parse(line)
|
||||
dic[key] = value
|
||||
|
||||
# for challenge 1
|
||||
memo = {"shiny gold": 1}
|
||||
|
||||
count = 0
|
||||
for key in dic.keys():
|
||||
if containments(key) > 0:
|
||||
count += 1
|
||||
print(count-1)
|
||||
|
||||
# print for challenge 2
|
||||
memo2 = {}
|
||||
print(number_bags("shiny gold"))
|
||||
@@ -0,0 +1,55 @@
|
||||
import re
|
||||
|
||||
|
||||
def decode(line):
|
||||
groups = re.compile(r"(?P<op>\w\w\w) (?P<value>[+|-]\d+)").search(line)
|
||||
return groups
|
||||
|
||||
|
||||
def run(dict):
|
||||
line = 0
|
||||
acc = 0
|
||||
while True:
|
||||
(x, y) = dict[line]
|
||||
if x == 'stop':
|
||||
return acc
|
||||
if x == 'nop':
|
||||
dict[line] = ('stop', y)
|
||||
line += 1
|
||||
if x == 'acc':
|
||||
dict[line] = ('stop', y)
|
||||
acc += int(y)
|
||||
line += 1
|
||||
if x == 'jmp':
|
||||
dict[line] = ('stop', y)
|
||||
line = line + int(y)
|
||||
if line > 632:
|
||||
return acc
|
||||
|
||||
|
||||
with open(r"C:\Users\Maya\Desktop\Uni\WS_2021\AoC\input08") as f:
|
||||
lines = f.readlines()
|
||||
|
||||
memo = {}
|
||||
|
||||
for n, line in enumerate(lines):
|
||||
memo[n] = decode(line).groups()
|
||||
|
||||
(x, y) = memo[405]
|
||||
if memo[405] == ('nop', y):
|
||||
memo[405] = ('jmp', y)
|
||||
elif memo[405] == ('jmp', y):
|
||||
memo[405] = ('nop', y)
|
||||
|
||||
print(run(memo))
|
||||
|
||||
for line in memo:
|
||||
for n, l in enumerate(lines):
|
||||
memo[n] = decode(l).groups()
|
||||
(a, b) = memo[line]
|
||||
if memo[line] == ('nop', b):
|
||||
memo[line] = ('jmp', b)
|
||||
elif memo[line] == ('jmp', b):
|
||||
memo[line] = ('nop', b)
|
||||
if run(memo) == 'here':
|
||||
print(line)
|
||||
@@ -0,0 +1,39 @@
|
||||
|
||||
|
||||
# check if a number is valid (2 in the previous 25 numbers add up to it)
|
||||
def check_if_valid(prev, num):
|
||||
for i in prev:
|
||||
for j in prev:
|
||||
if i + j == num:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
# find a continuous list of numbers that add up to the weakness found earlier
|
||||
def find_sum(num):
|
||||
for d in range(0, len(lines)):
|
||||
for e in range(d, len(lines)):
|
||||
if sum(lines[d:e]) == num and len(lines[d:e]) > 1:
|
||||
return lines[d:e]
|
||||
|
||||
|
||||
with open(r"C:\Users\Maya\Desktop\Uni\WS_2021\AoC\input09") as f:
|
||||
lines = f.readlines()
|
||||
|
||||
# convert ti integers
|
||||
for (a, l) in enumerate(lines):
|
||||
lines[a] = int(l)
|
||||
|
||||
# find weakness
|
||||
weakness = 0
|
||||
|
||||
for k in range(25, len(lines)-1):
|
||||
if not check_if_valid(lines[(k-25):k], lines[k]):
|
||||
weakness = lines[k]
|
||||
break
|
||||
|
||||
# challenge 1 print
|
||||
print(weakness)
|
||||
|
||||
# challenge 2 print
|
||||
print(min(find_sum(weakness)) + max(find_sum(weakness)))
|
||||
@@ -0,0 +1,58 @@
|
||||
|
||||
|
||||
def adapter_chain(adapts):
|
||||
jolt1 = 0
|
||||
jolt3 = 1
|
||||
for i in range(1, len(adapts)):
|
||||
if adapts[i-1] - adapts[i] == 1:
|
||||
jolt1 += 1
|
||||
elif adapts[i-1] - adapts[i] == 3:
|
||||
jolt3 += 1
|
||||
else:
|
||||
print(adapts[i] - adapts[i-1])
|
||||
return jolt1 * jolt3
|
||||
|
||||
|
||||
def memo(f):
|
||||
memo = {}
|
||||
|
||||
def f2(x):
|
||||
if x not in memo:
|
||||
memo[x] = f(x)
|
||||
return memo[x]
|
||||
|
||||
return f2
|
||||
|
||||
|
||||
@memo
|
||||
def combinations(i):
|
||||
j = 0
|
||||
if i == max(nums):
|
||||
return 1
|
||||
if i+1 in nums:
|
||||
j += combinations(i+1)
|
||||
if i+2 in nums:
|
||||
j += combinations(i+2)
|
||||
if i+3 in nums:
|
||||
j += combinations(i+3)
|
||||
return j
|
||||
|
||||
|
||||
with open(r"C:\Users\Maya\Desktop\Uni\WS_2021\AoC\input10") as f:
|
||||
lines = f.readlines()
|
||||
|
||||
# convert to integers
|
||||
nums = [int(line) for line in lines]
|
||||
nums.append(0)
|
||||
nums.sort()
|
||||
|
||||
nums.reverse()
|
||||
|
||||
print(adapter_chain(nums))
|
||||
|
||||
nums.append(nums[-1] + 3)
|
||||
nums.reverse()
|
||||
|
||||
|
||||
|
||||
print(combinations(0))
|
||||
@@ -0,0 +1,141 @@
|
||||
|
||||
from copy import deepcopy
|
||||
|
||||
|
||||
def test(array, x, y):
|
||||
test = []
|
||||
if not x-1 < 0:
|
||||
try:
|
||||
test.append(array[x-1][y])
|
||||
except IndexError:
|
||||
pass
|
||||
try:
|
||||
test.append(array[x - 1][y + 1])
|
||||
except IndexError:
|
||||
pass
|
||||
try:
|
||||
test.append(array[x - 1][y - 1])
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
try:
|
||||
test.append(array[x][y-1])
|
||||
except IndexError:
|
||||
pass
|
||||
try:
|
||||
test.append(array[x + 1][y - 1])
|
||||
except IndexError:
|
||||
pass
|
||||
try:
|
||||
test.append(array[x + 1][y])
|
||||
except IndexError:
|
||||
pass
|
||||
try:
|
||||
test.append(array[x][y + 1])
|
||||
except IndexError:
|
||||
pass
|
||||
try:
|
||||
test.append(array[x + 1][y + 1])
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
return test
|
||||
|
||||
|
||||
def occupy_seats(array):
|
||||
second = deepcopy(array)
|
||||
changes = 0
|
||||
for x in range(0, len(array)):
|
||||
for y in range(0, len(array[x])):
|
||||
tests = test(array, x, y)
|
||||
d = tests.count('#')
|
||||
|
||||
if array[x][y] == 'L' and d == 0:
|
||||
second[x][y] = '#'
|
||||
changes += 1
|
||||
|
||||
if array[x][y] == "#" and d > 3:
|
||||
second[x][y] = 'L'
|
||||
changes += 1
|
||||
|
||||
return changes, second
|
||||
|
||||
|
||||
def oob(space, y, x):
|
||||
if y < 0: return True
|
||||
if y >= len(space): return True
|
||||
if x < 0: return True
|
||||
if x >= len(space[y]): return True
|
||||
return False
|
||||
|
||||
|
||||
def visible_seats(space, y, x):
|
||||
dirs = [(y, x) for x in [0, 1, -1] for y in [0, 1, -1]]
|
||||
neighbors = []
|
||||
for a, b in dirs:
|
||||
if a == 0 and b == 0: continue
|
||||
step = 1
|
||||
|
||||
def pos():
|
||||
return (step * a + y, step * b + x)
|
||||
|
||||
while (not oob(space, *pos())):
|
||||
loc = space[pos()[0]][pos()[1]]
|
||||
if loc == "L" or loc == "#":
|
||||
neighbors.append(loc)
|
||||
break
|
||||
step += 1
|
||||
return neighbors
|
||||
|
||||
|
||||
def occupy_seats2(array):
|
||||
second = deepcopy(array)
|
||||
changes = 0
|
||||
for x in range(0, len(array)):
|
||||
for y in range(0, len(array[x])):
|
||||
d = visible_seats(array, x, y).count('#')
|
||||
|
||||
if array[x][y] == 'L' and d == 0:
|
||||
second[x][y] = '#'
|
||||
changes += 1
|
||||
|
||||
if array[x][y] == "#" and d > 4:
|
||||
second[x][y] = 'L'
|
||||
changes += 1
|
||||
|
||||
return changes, second
|
||||
|
||||
|
||||
with open(r"C:\Users\Maya\Desktop\Uni\WS_2021\AoC\input11") as f:
|
||||
lines = f.readlines()
|
||||
|
||||
for i in range(0, len(lines)):
|
||||
lines[i] = list(lines[i])
|
||||
|
||||
lines2 = deepcopy(lines)
|
||||
|
||||
while True:
|
||||
c, lines = occupy_seats(lines)
|
||||
if c == 0:
|
||||
break
|
||||
|
||||
count = 0
|
||||
|
||||
for line in lines:
|
||||
count += line.count('#')
|
||||
|
||||
print(count)
|
||||
|
||||
while True:
|
||||
c, lines2 = occupy_seats2(lines2)
|
||||
print(c)
|
||||
if c == 0:
|
||||
break
|
||||
|
||||
count2 = 0
|
||||
|
||||
for line in lines2:
|
||||
count2 += line.count('#')
|
||||
|
||||
print(count2)
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
import re
|
||||
|
||||
|
||||
def parse(l):
|
||||
group = re.compile(r"(?P<dir>\w)(?P<int>\d+)").findall(l)
|
||||
return group[0]
|
||||
|
||||
|
||||
def move_ship(direction, amount, east, north, facing):
|
||||
array = ['N', 'E', 'S', 'W']
|
||||
amount = int(amount)
|
||||
if direction == 'F':
|
||||
direction = facing
|
||||
if direction == 'N':
|
||||
north += amount
|
||||
if direction == 'S':
|
||||
north -= amount
|
||||
if direction == 'E':
|
||||
east += amount
|
||||
if direction == 'W':
|
||||
east -= amount
|
||||
if direction == 'L':
|
||||
pos = array.index(facing)
|
||||
pos2 = amount // 90
|
||||
facing = array[pos - pos2]
|
||||
if direction == 'R':
|
||||
pos = array.index(facing)
|
||||
pos2 = amount // 90
|
||||
facing = array[(pos + pos2) % 4]
|
||||
|
||||
return east, north, facing
|
||||
|
||||
|
||||
def move_ship_waypoint(direction, amount, ship, waypoint):
|
||||
amount = int(amount)
|
||||
if direction == 'F':
|
||||
ship += waypoint*amount
|
||||
if direction == 'N':
|
||||
waypoint += amount * (0+1j)
|
||||
if direction == 'S':
|
||||
waypoint += amount * (0-1j)
|
||||
if direction == 'E':
|
||||
waypoint += amount * (1+0j)
|
||||
if direction == 'W':
|
||||
waypoint += amount * (-1+0j)
|
||||
if direction == 'L':
|
||||
waypoint = waypoint * 1j**(amount // 90)
|
||||
if direction == 'R':
|
||||
waypoint = waypoint * (-1j)**(amount // 90)
|
||||
|
||||
return ship, waypoint
|
||||
|
||||
|
||||
with open(r"C:\Users\Maya\Desktop\Uni\WS_2021\AoC\input12") as f:
|
||||
lines = f.readlines()
|
||||
|
||||
# make dictionary with the values
|
||||
directions = []
|
||||
for line in lines:
|
||||
directions.append(parse(line))
|
||||
|
||||
# current position [east / west, north / south, facing]
|
||||
current = [0, 0, 'E']
|
||||
|
||||
for dire in directions:
|
||||
current = move_ship(*dire, *current)
|
||||
|
||||
print(abs(current[0]) + abs(current[1]))
|
||||
|
||||
ship_position = 0+0j
|
||||
waypoint_position = 10+1j
|
||||
|
||||
for dire in directions:
|
||||
ship_position, waypoint_position = move_ship_waypoint(*dire, ship_position, waypoint_position)
|
||||
|
||||
print(abs(ship_position.real) + abs(ship_position.imag))
|
||||
@@ -0,0 +1,54 @@
|
||||
from numpy import prod
|
||||
|
||||
|
||||
def find_earliest_bus(start, buses):
|
||||
i = start
|
||||
next = 0
|
||||
for time in buses:
|
||||
if time == 'x':
|
||||
pass
|
||||
elif int(time) - start % int(time) < i:
|
||||
i = int(time) - (start % int(time))
|
||||
next = int(time)
|
||||
return next * i
|
||||
|
||||
|
||||
def time_to_bus(start, bus):
|
||||
i = -start % bus
|
||||
return i
|
||||
|
||||
|
||||
def find_earliest_timestamp(timestamps):
|
||||
dict = {}
|
||||
for i in range(0, len(timestamps)):
|
||||
if timestamps[i] == 'x':
|
||||
pass
|
||||
else:
|
||||
line = int(timestamps[i])
|
||||
dict[line] = i
|
||||
|
||||
t = 0
|
||||
kgV = 1
|
||||
for bus, wait in dict.items():
|
||||
while not time_to_bus(t, bus) == (wait % bus):
|
||||
t += kgV
|
||||
kgV = kgV * bus
|
||||
return t
|
||||
|
||||
#for n in range(1352008337, 1000000000000000000):
|
||||
# ar = [(n + dict[b]) % b == 0 for b in dict.keys()]
|
||||
# if False not in ar:
|
||||
# return n
|
||||
# print(n)
|
||||
|
||||
|
||||
with open(r"C:\Users\Maya\Desktop\Uni\WS_2021\AoC\input13") as f:
|
||||
lines = f.readlines()
|
||||
lines[0] = int(lines[0])
|
||||
lines[1] = lines[1].split(",")
|
||||
|
||||
print(find_earliest_bus(lines[0], lines[1]))
|
||||
|
||||
print(find_earliest_timestamp(lines[1]))
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
|
||||
import re
|
||||
|
||||
|
||||
def decode_line(line):
|
||||
mask = re.search(r"mask = (?P<mask>[1 | 0 | X]{36})", line)
|
||||
mem = re.search(r"mem\[(?P<address>\d+)] = (?P<value>\d+)", line)
|
||||
if mask:
|
||||
return 'm', mask.group('mask')
|
||||
if mem:
|
||||
return mem.group('address', 'value')
|
||||
|
||||
|
||||
def to_int(num):
|
||||
new = 0
|
||||
for j in range(0, len(num)):
|
||||
if num[j] == '1':
|
||||
new += 2**(len(num) - j - 1)
|
||||
return new
|
||||
|
||||
|
||||
def comb(num, mas):
|
||||
num = f'{num:036b}'
|
||||
mas = list(mas)
|
||||
num = list(num)
|
||||
for i in range(0, len(num)):
|
||||
if mas[i] == '0':
|
||||
num[i] = '0'
|
||||
if mas[i] == '1':
|
||||
num[i] = '1'
|
||||
|
||||
return to_int(num)
|
||||
|
||||
|
||||
def execute(arg, val):
|
||||
if arg == 'm':
|
||||
global mask
|
||||
mask = val
|
||||
else:
|
||||
memory[arg] = comb(int(val), mask)
|
||||
|
||||
|
||||
|
||||
def comb_address(num, mas):
|
||||
mas = list(mas)
|
||||
m = to_int(mas)
|
||||
|
||||
x = ['0'] * 36
|
||||
for i in range(0, len(mas)):
|
||||
if mas[i] == 'X':
|
||||
x[i] = '1'
|
||||
x = to_int(x)
|
||||
|
||||
num = num & ~x
|
||||
comb = 0
|
||||
|
||||
for y in range(0, 2**mask.count('X')):
|
||||
yield comb | num | m
|
||||
comb = ((comb | ~x) + 1) & x
|
||||
|
||||
|
||||
def execute_v2(arg, val):
|
||||
if arg == 'm':
|
||||
global mask
|
||||
mask = val
|
||||
else:
|
||||
for ad in comb_address(int(arg), mask):
|
||||
memory2[ad] = int(val)
|
||||
|
||||
|
||||
with open(r"C:\Users\Maya\Desktop\Uni\WS_2021\AoC\input14") as f:
|
||||
lines = f.readlines()
|
||||
|
||||
dec = [decode_line(l) for l in lines]
|
||||
|
||||
memory = {}
|
||||
|
||||
mask = 0
|
||||
|
||||
for d in dec:
|
||||
execute(*d)
|
||||
|
||||
print(sum(memory.values()))
|
||||
|
||||
memory2 = {}
|
||||
|
||||
mask = 0
|
||||
|
||||
for d in dec:
|
||||
execute_v2(*d)
|
||||
|
||||
print(sum(memory2.values()))
|
||||
@@ -0,0 +1,19 @@
|
||||
def next(num, turn, memo):
|
||||
if num not in memo:
|
||||
memo[num] = (0, turn)
|
||||
return 0
|
||||
memo[num] = (memo[num][1], turn)
|
||||
return memo[num][1] - memo[num][0]
|
||||
|
||||
|
||||
def solve(input, target):
|
||||
memo, n = {}, input[-1]
|
||||
for i, j in enumerate(input):
|
||||
memo[j] = (0, i)
|
||||
for t in range(len(input)-1, target-1):
|
||||
n = next(n, t, memo)
|
||||
return n
|
||||
|
||||
|
||||
print(solve([16, 12, 1, 0, 15, 7, 11], 2020))
|
||||
print(solve([16, 12, 1, 0, 15, 7, 11], 30000000))
|
||||
@@ -0,0 +1,87 @@
|
||||
import re
|
||||
|
||||
|
||||
def decode_lines(l):
|
||||
rules = re.compile(r"(?P<rule>\w+ ?\w+): (?P<lb1>\d+)-(?P<ub1>\d+) or (?P<lb2>\d+)-(?P<ub2>\d+)").findall(l)
|
||||
my_ticket = re.compile(r"your ticket:\n(?P<ticket>\d+[,\d+]+)").search(l)
|
||||
nearby_tickets = re.compile(r"\n(?P<ticket>\d+[,\d+]+)").findall(l)
|
||||
|
||||
return rules, my_ticket.group('ticket'), nearby_tickets[1:]
|
||||
|
||||
|
||||
def is_valid(ticket):
|
||||
|
||||
count = 0
|
||||
|
||||
for value in ticket:
|
||||
valid = False
|
||||
for rule in rules:
|
||||
if int(rule[1]) <= int(value) <= int(rule[2]) or int(rule[3]) <= int(value) <= int(rule[4]):
|
||||
valid = True
|
||||
if not valid:
|
||||
count += int(value)
|
||||
return count
|
||||
|
||||
|
||||
def find_rule(rule):
|
||||
for i in range(0, len(nt[0])):
|
||||
valid = True
|
||||
for ticket in nt:
|
||||
value = ticket[i]
|
||||
if not (int(rule[1]) <= int(value) <= int(rule[2]) or int(rule[3]) <= int(value) <= int(rule[4])):
|
||||
valid = False
|
||||
if valid: yield i
|
||||
|
||||
|
||||
with open(r"C:\Users\Maya\Desktop\Uni\WS_2021\AoC\input16") as f:
|
||||
lines = f.readlines()
|
||||
lines = "".join(lines)
|
||||
|
||||
rules, mine, nearby = decode_lines(lines)
|
||||
|
||||
nt = [tick.split(',') for tick in nearby]
|
||||
|
||||
mine = mine.split(',')
|
||||
print(mine)
|
||||
|
||||
scanning_error = 0
|
||||
for ticket in nt:
|
||||
scanning_error += is_valid(ticket)
|
||||
|
||||
print(scanning_error)
|
||||
|
||||
for ticket in nt:
|
||||
if is_valid(ticket) > 0:
|
||||
nt.remove(ticket)
|
||||
|
||||
for ticket in nt:
|
||||
if is_valid(ticket) > 0:
|
||||
nt.remove(ticket)
|
||||
|
||||
mem = {}
|
||||
for rule in rules:
|
||||
mem[rule[0]] = [False] * 20
|
||||
for r in find_rule(rule):
|
||||
mem[rule[0]][r] = True
|
||||
|
||||
rulebook = {}
|
||||
|
||||
while True:
|
||||
if len(rulebook) == 15: break
|
||||
for i in range(0, 20):
|
||||
count = 0
|
||||
for rule, value in mem.items():
|
||||
if value[i]:
|
||||
count += 1
|
||||
if count == 1:
|
||||
for rule, value in mem.items():
|
||||
if value[i]:
|
||||
rulebook[i] = rule
|
||||
mem.pop(rule)
|
||||
print(rule)
|
||||
break
|
||||
|
||||
print(rulebook)
|
||||
|
||||
print(int(mine[19])*int(mine[17])*int(mine[11])*int(mine[8])*int(mine[10])*int(mine[0]))
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
from copy import deepcopy
|
||||
from termcolor import colored
|
||||
|
||||
|
||||
def show(array):
|
||||
for z in range(0, len(array)):
|
||||
print(colored('\nz = ' + str(z), 'yellow'))
|
||||
for i in range(0, len(array[z])):
|
||||
print(colored(''.join(array[z][i]), 'blue'))
|
||||
|
||||
|
||||
def show4(array):
|
||||
for w in range(0, len(array)):
|
||||
print(colored('\nw = ' + str(w), 'magenta'))
|
||||
for z in range(0, len(array[w])):
|
||||
print(colored('\nz = ' + str(z), 'yellow'))
|
||||
for i in range(0, len(array[w][z])):
|
||||
print(colored(''.join(array[w][z][i]), 'blue'))
|
||||
|
||||
|
||||
def oob(space, z, y, x):
|
||||
if z < 0: return True
|
||||
if z >= len(space): return True
|
||||
if y < 0: return True
|
||||
if y >= len(space[z]): return True
|
||||
if x < 0: return True
|
||||
if x >= len(space[z][y]): return True
|
||||
return False
|
||||
|
||||
|
||||
def oob4(space, w, z, y, x):
|
||||
if w < 0: return True
|
||||
if w >= len(space): return True
|
||||
if z < 0: return True
|
||||
if z >= len(space[w]): return True
|
||||
if y < 0: return True
|
||||
if y >= len(space[w][z]): return True
|
||||
if x < 0: return True
|
||||
if x >= len(space[w][z][y]): return True
|
||||
return False
|
||||
|
||||
|
||||
def neighbors(space, z, y, x):
|
||||
dirs = [(z, y, x) for x in [0, 1, -1] for y in [0, 1, -1] for z in [0, 1, -1]]
|
||||
dirs.remove((0, 0, 0))
|
||||
for d in dirs:
|
||||
if not oob(space, z+d[0], y+d[1], x+d[2]):
|
||||
yield space[z+d[0]][y+d[1]][x+d[2]]
|
||||
|
||||
|
||||
def neighbors4(space, w, z, y, x):
|
||||
dirs = [(w, z, y, x) for x in [0, 1, -1] for y in [0, 1, -1] for z in [0, 1, -1] for w in [0, 1, -1]]
|
||||
dirs.remove((0, 0, 0, 0))
|
||||
for d in dirs:
|
||||
if not oob4(space, w+d[0], z+d[1], y+d[2], x+d[3]):
|
||||
yield space[w+d[0]][z+d[1]][y+d[2]][x+d[3]]
|
||||
|
||||
|
||||
def step(array):
|
||||
next = deepcopy(array)
|
||||
for z in range(0, len(array)):
|
||||
for y in range(0, len(array[z])):
|
||||
for x in range(0, len(array[z][y])):
|
||||
c = [i for i in neighbors(array, z, y, x)].count('#')
|
||||
if array[z][y][x] == '#' and not (c == 2 or c == 3):
|
||||
next[z][y][x] = '.'
|
||||
if array[z][y][x] == '.' and c == 3:
|
||||
next[z][y][x] = '#'
|
||||
return next
|
||||
|
||||
|
||||
def step4(array):
|
||||
next = deepcopy(array)
|
||||
for w in range(0, len(array)):
|
||||
for z in range(0, len(array[w])):
|
||||
for y in range(0, len(array[w][z])):
|
||||
for x in range(0, len(array[w][z][y])):
|
||||
c = [i for i in neighbors4(array, w, z, y, x)].count('#')
|
||||
if array[w][z][y][x] == '#' and not (c == 2 or c == 3):
|
||||
next[w][z][y][x] = '.'
|
||||
if array[w][z][y][x] == '.' and c == 3:
|
||||
next[w][z][y][x] = '#'
|
||||
return next
|
||||
|
||||
|
||||
with open(r"C:\Users\Maya\Desktop\Uni\WS_2021\AoC\input17") as f:
|
||||
lines = f.readlines()
|
||||
lines = [list(l) for l in lines]
|
||||
empty = [[['.' for i in range(20)] for j in range(20)] for k in range(13)]
|
||||
for i in range(0, 8):
|
||||
for j in range(0, 8):
|
||||
empty[6][j+6][i+6] = lines[j][i]
|
||||
show(empty)
|
||||
|
||||
for i in range(0, 6):
|
||||
print(colored('\n\nstep: ' + str(i+1) + '\n', 'red'))
|
||||
empty = step(empty)
|
||||
show(empty)
|
||||
|
||||
count = 0
|
||||
for i in range(0, 13):
|
||||
for j in range(0, 20):
|
||||
count += empty[i][j].count('#')
|
||||
print(colored(count, 'cyan'))
|
||||
|
||||
hypercube = [[[['.' for i in range(20)] for j in range(20)] for k in range(13)] for l in range(13)]
|
||||
for i in range(0, 8):
|
||||
for j in range(0, 8):
|
||||
hypercube[6][6][j+6][i+6] = lines[j][i]
|
||||
|
||||
for i in range(0, 6):
|
||||
print(colored('\n\nstep: ' + str(i + 1) + '\n', 'red'))
|
||||
hypercube = step4(hypercube)
|
||||
show4(hypercube)
|
||||
|
||||
count4 = 0
|
||||
for i in range(0, 13):
|
||||
for j in range(0, 13):
|
||||
for k in range(0, 20):
|
||||
count4 += hypercube[i][j][k].count('#')
|
||||
|
||||
print(colored(count4, 'cyan'))
|
||||
@@ -0,0 +1,23 @@
|
||||
import ast
|
||||
|
||||
|
||||
class RewriteName(ast.NodeTransformer):
|
||||
|
||||
def visit_Mult(self, node):
|
||||
return ast.Add()
|
||||
|
||||
def visit_Sub(self, node):
|
||||
return ast.Mult()
|
||||
|
||||
|
||||
def evaluate(line):
|
||||
line = line.replace("*", "-")[:-1]
|
||||
line = line.replace("+", "*")
|
||||
new = RewriteName().visit(ast.parse(line, mode='eval'))
|
||||
return eval(compile(new, '<string>', 'eval'))
|
||||
|
||||
|
||||
with open(r"C:\Users\Maya\Desktop\Uni\WS_2021\AoC\input18") as f:
|
||||
lines = f.readlines()
|
||||
print(evaluate(lines[0]))
|
||||
print(sum([evaluate(l) for l in lines]))
|
||||
Executable
+60
@@ -0,0 +1,60 @@
|
||||
import re
|
||||
|
||||
|
||||
def memo(f):
|
||||
memo = {}
|
||||
|
||||
def f2(x):
|
||||
if x not in memo:
|
||||
memo[x] = f(x)
|
||||
return memo[x]
|
||||
|
||||
return f2
|
||||
|
||||
|
||||
def parse(l):
|
||||
srules = re.compile(r"(?P<rule>\d+): (?P<num1>\d+)\n").findall(l)
|
||||
rules = re.compile(r"(?P<rule>\d+): (?P<num1>\d+) (?P<num2>\d+)\n").findall(l)
|
||||
wrules = re.compile(r"(?P<rule>\d+): \"(?P<body>\w)\"\n").findall(l)
|
||||
crules = re.compile(r"(?P<rule>\d+): (?P<num11>\d+) (?P<num12>\d+) \| (?P<num21>\d+) (?P<num22>\d+)\n").findall(l)
|
||||
csrules = re.compile(r"(?P<rule>\d+): (?P<num11>\d+) \| (?P<num21>\d+)\n").findall(l)
|
||||
messages = re.compile(r"(?P<message>\w+)\n").findall(l)
|
||||
return rules, wrules, crules, srules, csrules, messages
|
||||
|
||||
|
||||
def check_if_valid(message):
|
||||
return 0
|
||||
|
||||
|
||||
@memo
|
||||
def build_regex(rule):
|
||||
if dict[rule] == 'a' or dict[rule] == 'b':
|
||||
return dict[rule]
|
||||
if type(dict[rule]) == int:
|
||||
return build_regex(dict[rule])
|
||||
s = "("
|
||||
for i, r in enumerate(dict[rule]):
|
||||
if i == 2:
|
||||
s += ")|("
|
||||
s += build_regex(r)
|
||||
return s + ")"
|
||||
|
||||
|
||||
with open(r"C:\Users\Maya\Desktop\Uni\WS_2021\AoC\input19") as f:
|
||||
lines = f.readlines()
|
||||
lines = "".join(lines)
|
||||
r, w, c, s, messages = parse(lines)
|
||||
rules = r + w + c + s
|
||||
dict = {}
|
||||
for rule in rules:
|
||||
if len(rule) == 2:
|
||||
try: dict[int(rule[0])] = int(rule[1])
|
||||
except ValueError: dict[int(rule[0])] = rule[1]
|
||||
if len(rule) == 3:
|
||||
dict[int(rule[0])] = int(rule[1]), int(rule[2])
|
||||
if len(rule) == 5:
|
||||
dict[int(rule[0])] = int(rule[1]), int(rule[2]), int(rule[3]), int(rule[4])
|
||||
|
||||
print(dict)
|
||||
print(build_regex(0))
|
||||
print(sum([check_if_valid(m) for m in messages]))
|
||||
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import re
|
||||
|
||||
def parse_rules(lines):
|
||||
rules = {}
|
||||
for line in lines:
|
||||
rule, pattern = line.split(':')
|
||||
alternatives = pattern.split('|')
|
||||
rules[int(rule)] = [a.strip(' ').split(' ') for a in alternatives]
|
||||
return rules
|
||||
|
||||
def memo(f):
|
||||
mem = {}
|
||||
def helper(x):
|
||||
if x not in mem: mem[x] = f(x)
|
||||
return mem[x]
|
||||
return helper
|
||||
|
||||
@memo
|
||||
def expr(rule):
|
||||
if rule == 8:
|
||||
return expr(42) + '+'
|
||||
if rule == 11:
|
||||
return '(?:' + expr(42) + '(?=a*(\1?+b)b*(\2?+c)))+\1' + expr(31) + ')'
|
||||
global rules
|
||||
if type(rule) is str:
|
||||
try: rule = int(rule)
|
||||
except ValueError: return rule[1]
|
||||
pattern = rules[rule]
|
||||
res = ["".join(expr(dep) for dep in alt) for alt in pattern]
|
||||
if len(res) == 1: return res[0]
|
||||
return "(" + "|".join(res) + ")"
|
||||
|
||||
if __name__ == '__main__':
|
||||
rules, messages = open(sys.argv[1]).read().split('\n\n')
|
||||
rules = parse_rules(rules.split('\n'))
|
||||
count = 0
|
||||
messages = messages.split("\n")
|
||||
for m in messages:
|
||||
if bool(re.match('^' + expr(0) + '$', m)):
|
||||
count += 1
|
||||
print(count)
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
from termcolor import colored
|
||||
|
||||
def show(tile):
|
||||
for line in tile:
|
||||
print(colored(''.join(line), 'blue'))
|
||||
print('\n')
|
||||
|
||||
def fliph(tile):
|
||||
next = ['n'] * 10
|
||||
for i in range(0,len(tile)):
|
||||
next[i] = tile[len(tile)-i-1]
|
||||
return next
|
||||
|
||||
def flipv(tile):
|
||||
for i in range(0, len(tile)):
|
||||
tile[i] = tile[i][::-1]
|
||||
return tile
|
||||
|
||||
def rotate(tile):
|
||||
next = [['o' for i in range(len(tile[0]))] for j in range(len(tile))]
|
||||
for i in range(0, len(tile)):
|
||||
for j in range(0, len(tile[1])):
|
||||
next[len(tile[1])-j-1][i] = tile[i][j]
|
||||
return next
|
||||
|
||||
def options(tile):
|
||||
return [tile,
|
||||
fliph(tiles[t]),
|
||||
rotate(tiles[t]),
|
||||
rotate(rotate(tiles[t])),
|
||||
rotate(rotate(rotate(tiles[t]))),
|
||||
fliph(rotate(tiles[t])),
|
||||
fliph(rotate(rotate(tiles[t]))),
|
||||
fliph(rotate(rotate(rotate(tiles[t]))))]
|
||||
|
||||
if __name__ == '__main__':
|
||||
tilestrings = open(sys.argv[1]).read().split('\n\n')
|
||||
tiles = {}
|
||||
for tile in tilestrings:
|
||||
tid, *data = tile.split('\n')
|
||||
try:
|
||||
tid = tid.rstrip(':').split(' ')[1]
|
||||
except IndexError: continue
|
||||
grid = [[c for c in line] for line in data if len(line) >= 1]
|
||||
tiles[int(tid)] = grid
|
||||
for t in tiles:
|
||||
print(colored(str(t), 'red'))
|
||||
|
||||
|
||||
Executable
+101
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import numpy as np
|
||||
|
||||
def toBits(l): return sum(int(b=='#') * (2**i) for i,b in enumerate(l))
|
||||
def allSides(tile):
|
||||
a,b,c,d = tile[0, : ], tile[-1, : ], tile[:, 0], tile[:, -1]
|
||||
e,f,g,h = tile[0, ::-1], tile[-1, ::-1], tile[::-1, 0], tile[::-1, -1]
|
||||
return [a,b,c,d,e,f,g,h]
|
||||
|
||||
def comb(tile):
|
||||
return [tile,
|
||||
np.fliplr(tile),
|
||||
np.rot90(tile),
|
||||
np.rot90(np.rot90(tile)),
|
||||
np.rot90(np.rot90(np.rot90(tile))),
|
||||
np.fliplr(np.rot90(tile)),
|
||||
np.fliplr(np.rot90(np.rot90(tile))),
|
||||
np.fliplr(np.rot90(np.rot90(np.rot90(tile))))]
|
||||
|
||||
def getRight(tile): return toBits(tile[:,-1])
|
||||
def getLeft(tile): return toBits(tile[:,0])
|
||||
def getBot(tile): return toBits(tile[-1,:])
|
||||
def getTop(tile): return toBits(tile[0,:])
|
||||
|
||||
def matchRight(tile1, tile2):
|
||||
for t in comb(tile2):
|
||||
if getRight(tile1) == getLeft(t):
|
||||
return t
|
||||
|
||||
def matchBot(tile1, tile2):
|
||||
for t in comb(tile2):
|
||||
if getBot(tile1) == getTop(t):
|
||||
return t
|
||||
|
||||
if __name__ == '__main__':
|
||||
tilestrings = open(sys.argv[1]).read().split('\n\n')
|
||||
tiles = {}
|
||||
for tile in tilestrings:
|
||||
tid, *data = tile.split('\n')
|
||||
try:
|
||||
tid = tid.rstrip(':').split(' ')[1]
|
||||
except IndexError: continue
|
||||
grid = [[c for c in line] for line in data if len(line) >= 1]
|
||||
tiles[int(tid)] = np.array(grid)
|
||||
|
||||
sides = {}
|
||||
for tid, tile in tiles.items():
|
||||
for x in allSides(tile):
|
||||
bits = toBits(x)
|
||||
if bits not in sides: sides[bits] = []
|
||||
sides[bits].append(tid)
|
||||
sides = {k:v for k,v in sorted(sides.items(), key=lambda i: len(i[1]))}
|
||||
|
||||
singles = {}
|
||||
for bits, xs in sides.items():
|
||||
if len(xs) == 1:
|
||||
singles[xs[0]] = []
|
||||
for sid in singles.keys():
|
||||
matches = [x for side in allSides(tiles[sid]) for x in sides[toBits(side)]]
|
||||
singles[sid] = list(dict.fromkeys(matches))
|
||||
prod = 1
|
||||
corner = None
|
||||
for sid, single in singles.items():
|
||||
if len(single) < 4:
|
||||
prod *= sid
|
||||
corner = sid
|
||||
picture = [[None for x in range(12)] for x in range(12)]
|
||||
|
||||
matches = list(dict.fromkeys([x for side in allSides(tiles[corner]) for x in sides[toBits(side)]]))
|
||||
matches.remove(corner)
|
||||
for t in comb(tiles[corner]):
|
||||
x, y = matches
|
||||
x, y = tiles[x], tiles[y]
|
||||
if matchRight(t,x) is not None and matchBot(t,y) is not None:
|
||||
tiles[corner] = t
|
||||
break
|
||||
if matchRight(t,y) is not None and matchBot(t,x) is not None:
|
||||
tiles[corner] = t
|
||||
break
|
||||
picture[0][0] = corner
|
||||
for i, p in enumerate(picture[0]):
|
||||
s = sides[getRight(tiles[p])]
|
||||
s.remove(p)
|
||||
if len(s) > 0:
|
||||
tiles[s[0]] = matchRight(tiles[p], tiles[s[0]])
|
||||
picture[0][i+1] = s[0]
|
||||
for j in range(1, len(picture)):
|
||||
z = sides[getBot(tiles[p])]
|
||||
z.remove(p)
|
||||
if len(z) > 0:
|
||||
tiles[z[0]] = matchBot(tiles[p], tiles[z[0]])
|
||||
picture[j][i] = z[0]
|
||||
p = z[0]
|
||||
print(picture)
|
||||
pic = [[None for x in range(12)] for x in range(12)]
|
||||
for i in range(len(picture)):
|
||||
for j in range(len(picture[0])):
|
||||
pic[i][j] = tiles[picture[i][j]]
|
||||
print(pic)
|
||||
Executable
+130
@@ -0,0 +1,130 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import numpy as np
|
||||
#import matplotlib.pyplot as plt
|
||||
|
||||
def toBits(l): return sum(int(b=='#') * (2**i) for i,b in enumerate(l))
|
||||
def allSides(tile):
|
||||
a,b,c,d = tile[0, : ], tile[-1, : ], tile[:, 0], tile[:, -1]
|
||||
e,f,g,h = tile[0, ::-1], tile[-1, ::-1], tile[::-1, 0], tile[::-1, -1]
|
||||
return [a,b,c,d,e,f,g,h]
|
||||
|
||||
def comb(tile):
|
||||
return [tile,
|
||||
np.fliplr(tile),
|
||||
np.rot90(tile),
|
||||
np.rot90(np.rot90(tile)),
|
||||
np.rot90(np.rot90(np.rot90(tile))),
|
||||
np.fliplr(np.rot90(tile)),
|
||||
np.fliplr(np.rot90(np.rot90(tile))),
|
||||
np.fliplr(np.rot90(np.rot90(np.rot90(tile))))]
|
||||
|
||||
def getRight(tile): return toBits(tile[:,-1])
|
||||
def getLeft(tile): return toBits(tile[:,0])
|
||||
def getBot(tile): return toBits(tile[-1,:])
|
||||
def getTop(tile): return toBits(tile[0,:])
|
||||
|
||||
def matchRight(tile1, tile2):
|
||||
for t in comb(tile2):
|
||||
if getRight(tile1) == getLeft(t): return t
|
||||
def matchBot(tile1, tile2):
|
||||
for t in comb(tile2):
|
||||
if getBot(tile1) == getTop(t): return t
|
||||
|
||||
def parse_data(strings):
|
||||
tiles = {}
|
||||
for tile in strings:
|
||||
tid, *data = tile.split('\n')
|
||||
try: tid = tid.rstrip(':').split(' ')[1]
|
||||
except IndexError: continue
|
||||
grid = [[c for c in line] for line in data if len(line) >= 1]
|
||||
tiles[int(tid)] = np.array(grid)
|
||||
return tiles
|
||||
|
||||
def get_sides(tiles):
|
||||
sides = {}
|
||||
for tid, tile in tiles.items():
|
||||
for bits in map(lambda x: toBits(x), allSides(tile)):
|
||||
if bits not in sides: sides[bits] = []
|
||||
sides[bits].append(tid)
|
||||
return sides
|
||||
|
||||
def get_corners(tiles, sides):
|
||||
singles = {}
|
||||
for bits, xs in sides.items():
|
||||
if len(xs) == 1: singles[xs[0]] = []
|
||||
for sid in singles.keys():
|
||||
matches = [x for side in allSides(tiles[sid]) for x in sides[toBits(side)]]
|
||||
singles[sid] = list(dict.fromkeys(matches))
|
||||
corners = []
|
||||
for sid, single in singles.items():
|
||||
if len(single) < 4: corners.append(sid)
|
||||
return corners
|
||||
|
||||
def build_picture(tiles, sides, start):
|
||||
picture = [[None for x in range(12)] for x in range(12)]
|
||||
matches = [x for side in allSides(tiles[corner]) for x in sides[toBits(side)]]
|
||||
matches = list(dict.fromkeys(matches))
|
||||
matches.remove(corner)
|
||||
for t in comb(tiles[corner]):
|
||||
x, y = map(lambda v: tiles[v], matches)
|
||||
if matchRight(t,x) is not None and matchBot(t,y) is not None: break
|
||||
if matchRight(t,y) is not None and matchBot(t,x) is not None: break
|
||||
else: tiles[corner] = t
|
||||
picture[0][0] = corner
|
||||
|
||||
for i, p in enumerate(picture[0]):
|
||||
s = sides[getRight(tiles[p])]
|
||||
s.remove(p)
|
||||
if len(s) > 0:
|
||||
tiles[s[0]] = matchRight(tiles[p], tiles[s[0]])
|
||||
picture[0][i+1] = s[0]
|
||||
for j in range(1, len(picture)):
|
||||
z = sides[getBot(tiles[p])]
|
||||
z.remove(p)
|
||||
if len(z) > 0:
|
||||
tiles[z[0]] = matchBot(tiles[p], tiles[z[0]])
|
||||
picture[j][i] = z[0]
|
||||
p = z[0]
|
||||
|
||||
return picture
|
||||
|
||||
def countSM(pic, sm):
|
||||
count = 0
|
||||
y, x = pic.shape
|
||||
ys, xs = sm.shape
|
||||
for i in range(0, y-ys):
|
||||
for j in range(0, x-xs):
|
||||
if np.all(pic[i:i+ys,j:j+xs] | sm):
|
||||
count += 1
|
||||
return count
|
||||
|
||||
if __name__ == '__main__':
|
||||
tiles = parse_data(open(sys.argv[1]).read().split('\n\n'))
|
||||
sides = get_sides(tiles)
|
||||
|
||||
corner = get_corners(tiles, sides)[0]
|
||||
p = build_picture(tiles, sides, corner)
|
||||
print(p[0][0] * p[0][-1] * p[-1][0] * p[-1][-1])
|
||||
|
||||
pic = np.concatenate(tuple(np.concatenate(tuple(tiles[x][1:-1,1:-1] for x in r), axis=1) for r in p), axis=0)
|
||||
grayscale = np.vectorize(lambda x: np.int8(x == "#"))(pic)
|
||||
print(grayscale)
|
||||
|
||||
snake = \
|
||||
[ " # "
|
||||
, "# ## ## ###"
|
||||
, " # # # # # # "
|
||||
]
|
||||
|
||||
sneasnake = np.array([[c for c in line] for line in snake])
|
||||
sneasnake = np.vectorize(lambda x: np.int8(x != "#"))(sneasnake)
|
||||
|
||||
for p in comb(grayscale):
|
||||
print(countSM(p, sneasnake))
|
||||
print(np.count_nonzero(grayscale) - 26 * 15)
|
||||
|
||||
# plt.show()
|
||||
# plt.imshow(grayscale)
|
||||
# plt.savefig("test.png")
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
|
||||
def parse(line):
|
||||
line = line.split('(')
|
||||
line[0] = line[0].split(' ')[:-1]
|
||||
line[1] = line[1][9:-2]
|
||||
line[1] = line[1].split(', ')
|
||||
return line
|
||||
|
||||
if __name__ == '__main__':
|
||||
ingr = open(sys.argv[1]).readlines()
|
||||
ingredients = [parse(i) for i in ingr]
|
||||
allergenes = []
|
||||
for i in ingredients:
|
||||
for a in i[1]:
|
||||
allergenes.append(a)
|
||||
allergenes = set(allergenes)
|
||||
dicta = {}
|
||||
for i in ingredients:
|
||||
for a in i[1]:
|
||||
if a not in dicta:
|
||||
dicta[a] = [x for x in i[0]]
|
||||
else:
|
||||
copy = [x for x in dicta[a]]
|
||||
for w in copy:
|
||||
if w not in i[0]:
|
||||
dicta[a].remove(w)
|
||||
|
||||
count = 0
|
||||
for i in ingredients:
|
||||
for n in i[0]:
|
||||
b = True
|
||||
for v in dicta.values():
|
||||
if n in v:
|
||||
b = False
|
||||
if b:
|
||||
count += 1
|
||||
print(count)
|
||||
|
||||
dicta = {k:v for k,v in sorted(dicta.items(),key = lambda i: i[0])}
|
||||
for w in range(len(dicta)):
|
||||
for a, i in dicta.items():
|
||||
if len(i) == 1:
|
||||
for b, j in dicta.items():
|
||||
if b != a and i[0] in j:
|
||||
j.remove(i[0])
|
||||
for k, v in dicta.items():
|
||||
dicta[k] = v[0]
|
||||
print(','.join(dicta.values()))
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
|
||||
def step(deck1, deck2):
|
||||
new1, new2 = [x for x in deck1[1:]], [y for y in deck2[1:]]
|
||||
if deck1[0] > deck2[0]:
|
||||
new1.append(deck1[0])
|
||||
new1.append(deck2[0])
|
||||
else:
|
||||
new2.append(deck2[0])
|
||||
new2.append(deck1[0])
|
||||
return new1, new2
|
||||
|
||||
def game(deck1, deck2):
|
||||
while len(deck1) > 0 and len(deck2) > 0:
|
||||
deck1, deck2 = step(deck1, deck2)
|
||||
if len(deck1) > 0: return "1", deck1
|
||||
else: return "2", deck2
|
||||
|
||||
def recursive_game(deck1, deck2):
|
||||
comb = []
|
||||
while True:
|
||||
if len(deck1) == 0: return 'player2', deck2
|
||||
if len(deck2) == 0: return 'player1', deck1
|
||||
|
||||
new1, new2 = [x for x in deck1[1:]], [y for y in deck2[1:]]
|
||||
if (deck1, deck2) in comb: return 'player1', deck1
|
||||
comb.append((deck1, deck2))
|
||||
|
||||
if len(new1) >= deck1[0] and len(new2) >= deck2[0]:
|
||||
if recursive_game(deck1[1:(deck1[0]+1)], deck2[1:(deck2[0]+1)])[0] == 'player1':
|
||||
new1.append(deck1[0])
|
||||
new1.append(deck2[0])
|
||||
else:
|
||||
new2.append(deck2[0])
|
||||
new2.append(deck1[0])
|
||||
deck1, deck2 = [x for x in new1], [y for y in new2]
|
||||
else: deck1, deck2 = step(deck1, deck2)
|
||||
|
||||
def score(deck):
|
||||
count = 0
|
||||
for i, n in enumerate(deck):
|
||||
count += ((len(deck)-i) * n)
|
||||
return count
|
||||
|
||||
if __name__ == '__main__':
|
||||
decks = open(sys.argv[1]).read()
|
||||
deck1, deck2 = decks.split('\n\n')
|
||||
deck1, deck2 = deck1.split('\n')[1:], deck2.split('\n')[1:-1]
|
||||
deck1, deck2 = [int(i) for i in deck1], [int(j) for j in deck2]
|
||||
rdeck1, rdeck2 = [x for x in deck1], [y for y in deck2]
|
||||
|
||||
winner, windeck = game(deck1, deck2)
|
||||
print(winner, score(windeck))
|
||||
|
||||
winner, wdeck = recursive_game(rdeck1, rdeck2)
|
||||
print(winner, score(wdeck))
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from blist import blist
|
||||
|
||||
def destination(c, out):
|
||||
while True:
|
||||
if c-1>0 and c-1 not in out:
|
||||
return c-1, order.index(c-1)
|
||||
else:
|
||||
if c>1:
|
||||
c = c-1
|
||||
else:
|
||||
c = highest+1
|
||||
|
||||
|
||||
def move(order):
|
||||
rem = order
|
||||
a = rem.pop(1)
|
||||
b = rem.pop(1)
|
||||
c = rem.pop(1)
|
||||
|
||||
_, dest = destination(order[0], [a,b,c])
|
||||
|
||||
rem.insert(dest+1, a)
|
||||
rem.insert(dest+2, b)
|
||||
rem.insert(dest+3, c)
|
||||
|
||||
if __name__ == "__main__":
|
||||
#test_order = [3,8,9,1,2,5,4,6,7]
|
||||
order = blist([1,9,8,7,5,3,4,6,2])
|
||||
for x in range(10,1000001):
|
||||
order.append(x)
|
||||
current_index = 0
|
||||
lowest = min(order)
|
||||
highest = 1000000
|
||||
#highest = max(order)
|
||||
for i in range(10000000):
|
||||
print(i)
|
||||
move(order)
|
||||
current_index += 1
|
||||
last = order.pop(0)
|
||||
order.append(last)
|
||||
|
||||
order = order[order.index(1):] + order[:order.index(1)]
|
||||
print(order)
|
||||
print(order[1]*order[2])
|
||||
Executable
+49
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
|
||||
def destination(v, l): return (v - 2) % l + 1
|
||||
def move(cycle, current):
|
||||
a = cycle[current]
|
||||
b = cycle[a]
|
||||
c = cycle[b]
|
||||
dest = destination(current, len(cycle))
|
||||
if dest in [a,b,c]: dest = destination(dest, len(cycle))
|
||||
if dest in [a,b,c]: dest = destination(dest, len(cycle))
|
||||
if dest in [a,b,c]: dest = destination(dest, len(cycle))
|
||||
|
||||
cycle[current] = cycle[c]
|
||||
cycle[c] = cycle[dest]
|
||||
cycle[dest] = a
|
||||
|
||||
def score(cycle):
|
||||
cups = []
|
||||
current = 1
|
||||
for _ in cycle:
|
||||
current = cycle[current]
|
||||
cups.append(current)
|
||||
return "".join(str(cup) for cup in cups[:-1])
|
||||
|
||||
def solve(cups, num_moves):
|
||||
# Current Cup is first cup in list
|
||||
current = cups[0]
|
||||
# Cycle[cup_value] = next_cup_value in clockwise order
|
||||
cycle = {}
|
||||
for i, cup in enumerate(cups):
|
||||
cycle[int(cup)] = cups[(i + 1) % len(cups)]
|
||||
for _ in range(num_moves):
|
||||
move(cycle, current)
|
||||
current = cycle[current]
|
||||
return cycle
|
||||
|
||||
if __name__ == '__main__':
|
||||
cups = [int(i) for i in list(sys.argv[1])]
|
||||
print(score(solve(cups, 100)))
|
||||
|
||||
|
||||
million = 1000000
|
||||
new_cups = cups + [x for x in range(10, million+1)]
|
||||
cycle = solve(new_cups, 10*million)
|
||||
a = cycle[1]
|
||||
b = cycle[a]
|
||||
print(a*b)
|
||||
Executable
+87
@@ -0,0 +1,87 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
|
||||
def neighbors(x,y,z):
|
||||
r = []
|
||||
try: r.append(floor[x+1,y-1,z])
|
||||
except KeyError: pass
|
||||
try: r.append(floor[x-1,y+1,z])
|
||||
except KeyError: pass
|
||||
try: r.append(floor[x+1,y,z-1])
|
||||
except KeyError: pass
|
||||
try: r.append(floor[x-1,y,z+1])
|
||||
except KeyError: pass
|
||||
try: r.append(floor[x,y-1,z+1])
|
||||
except KeyError: pass
|
||||
try: r.append(floor[x,y+1,z-1])
|
||||
except KeyError: pass
|
||||
return r
|
||||
|
||||
def day(floor):
|
||||
copy = {}
|
||||
for (x,y,z) in floor:
|
||||
copy[(x,y,z)] = floor[(x,y,z)]
|
||||
c = sum([i%2 for i in neighbors(x,y,z)])
|
||||
if floor[(x,y,z)] % 2 == 1 and (c == 0 or c > 2):
|
||||
copy[(x,y,z)] += 1
|
||||
if floor[(x,y,z)] % 2 == 0 and c == 2:
|
||||
copy[(x,y,z)] += 1
|
||||
return copy
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
lines = open(sys.argv[1]).readlines()
|
||||
for i, line in enumerate(lines):
|
||||
lines[i] = list(line[:-1])
|
||||
|
||||
for line in lines:
|
||||
for j, b in enumerate(line):
|
||||
if b == 'n' or b == 's':
|
||||
line[j] = line[j] + line.pop(j+1)
|
||||
|
||||
floor = {}
|
||||
for x in range(-120, 121):
|
||||
for y in range(-120,121):
|
||||
z = -(x+y)
|
||||
floor[(x,y,z)] = 0
|
||||
for line in lines:
|
||||
x, y, z = 0, 0, 0
|
||||
for d in line:
|
||||
if d == 'e':
|
||||
x += 1
|
||||
y -= 1
|
||||
if d == 'w':
|
||||
x -= 1
|
||||
y += 1
|
||||
if d == 'ne':
|
||||
x += 1
|
||||
z -= 1
|
||||
if d == 'nw':
|
||||
y += 1
|
||||
z -= 1
|
||||
if d == 'se':
|
||||
y -= 1
|
||||
z += 1
|
||||
if d == 'sw':
|
||||
x -= 1
|
||||
z += 1
|
||||
if (x,y,z) in floor:
|
||||
floor[(x,y,z)] += 1
|
||||
else:
|
||||
floor[(x,y,z)] = 1
|
||||
count = 0
|
||||
for a in floor.values():
|
||||
if a%2 == 1:
|
||||
count += 1
|
||||
|
||||
print(count)
|
||||
|
||||
for _ in range(100):
|
||||
floor = day(floor)
|
||||
|
||||
count = 0
|
||||
for a in floor.values():
|
||||
if a%2 == 1:
|
||||
count += 1
|
||||
print(count)
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
|
||||
if __name__ == '__main__':
|
||||
lines = open(sys.argv[1]).readlines()
|
||||
for i, line in enumerate(lines):
|
||||
lines[i] = list(line[:-1])
|
||||
|
||||
for line in lines:
|
||||
for j, b in enumerate(line):
|
||||
if b == 'n' or b == 's':
|
||||
line[j] = line[j] + line.pop(j+1)
|
||||
|
||||
for a, line in enumerate(lines):
|
||||
for i in range(len(line)):
|
||||
for j in range(i+1, len(line)):
|
||||
x, y = line[i], line[j]
|
||||
if (x == 'e' and y == 'w') or (x == 'w' and y == 'e') or (x == 'se' and y == 'sw') or (x == 'sw' and y == 'se') or (x == 'ne' and y == 'nw') or (x == 'nw' and y == 'ne'):
|
||||
line[j] = ''
|
||||
line[i] = ''
|
||||
line.sort()
|
||||
lines[a] = ''.join(line)
|
||||
|
||||
dict = {}
|
||||
for di in lines:
|
||||
if di in dict:
|
||||
dict[di] += 1
|
||||
else:
|
||||
dict[di] = 1
|
||||
|
||||
count = 0
|
||||
for a in dict.values():
|
||||
if a % 2 == 1:
|
||||
count += 1
|
||||
print(count)
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
|
||||
if __name__ == '__main__':
|
||||
key1, key2 = open(sys.argv[1]).readlines()
|
||||
print(key1, key2)
|
||||
key1, key2 = int(key1), int(key2)
|
||||
|
||||
v = 1
|
||||
ls1 = 0
|
||||
while v != key1:
|
||||
v = (v*7) % 20201227
|
||||
ls1 += 1
|
||||
print(ls1)
|
||||
|
||||
v = 1
|
||||
ls2 = 0
|
||||
while v != key2:
|
||||
v = (v*7) % 20201227
|
||||
ls2 += 1
|
||||
print(ls2)
|
||||
|
||||
ek2 = 1
|
||||
for _ in range(ls1):
|
||||
ek2 = (ek2*key2) % 20201227
|
||||
|
||||
ek1 = 1
|
||||
for _ in range(ls2):
|
||||
ek1 = (ek1*key1) % 20201227
|
||||
|
||||
print(ek1, ek2)
|
||||
@@ -0,0 +1,45 @@
|
||||
#!/bin/env python3
|
||||
|
||||
from copy import deepcopy
|
||||
import sys
|
||||
|
||||
|
||||
def show(space):
|
||||
for row in space: print("".join(row))
|
||||
print()
|
||||
|
||||
|
||||
def neighbors(space, y, x):
|
||||
dirs = [(y, x) for x in [0, 1, -1] for y in [0, 1, -1]][1:]
|
||||
neighbors = []
|
||||
for a, b in dirs:
|
||||
try:
|
||||
neighbors.append(space[y + a][x + b])
|
||||
except IndexError:
|
||||
pass
|
||||
return neighbors
|
||||
|
||||
|
||||
def next(space):
|
||||
new = deepcopy(space)
|
||||
for y in range(len(space)):
|
||||
for x in range(len(space[y])):
|
||||
occ = neighbors(space, y, x).count("#")
|
||||
if space[y][x] == "L":
|
||||
if occ == 0: new[y][x] = "#"
|
||||
if space[y][x] == "#":
|
||||
if occ >= 4: new[y][x] = "L"
|
||||
return new
|
||||
|
||||
|
||||
def count(space):
|
||||
return sum(row.count('#') for row in space)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
space = [list(line) for line in open(r"C:\Users\Maya\Desktop\Uni\WS_2021\AoC\input11")]
|
||||
while space != next(next(space)):
|
||||
space = next(space)
|
||||
print(count(space))
|
||||
print(count(next(space)))
|
||||
print(count(next(next(space))))
|
||||
Reference in new issue
Block a user