add 2024/day1-day5 python
This commit is contained in:
parent
6c64d1b62e
commit
7c4e98ebcf
5 changed files with 360 additions and 0 deletions
51
2024/01/main.py
Executable file
51
2024/01/main.py
Executable file
|
@ -0,0 +1,51 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||||
|
||||
# Author: Sebastian Mark
|
||||
# CC-BY-SA (https://creativecommons.org/licenses/by-sa/4.0/deed.de)
|
||||
|
||||
# pylint: disable=missing-module-docstring,missing-function-docstring,consider-using-f-string
|
||||
|
||||
|
||||
def readinput() -> (list[int], list[int]):
|
||||
a = []
|
||||
b = []
|
||||
with open("input", "r", encoding="utf-8") as file:
|
||||
for line in file:
|
||||
num1, num2 = map(int, line.split())
|
||||
a.append(num1)
|
||||
b.append(num2)
|
||||
return a, b
|
||||
|
||||
|
||||
def distance(list_a: list[int], list_b: list[int]) -> int:
|
||||
list_a.sort()
|
||||
list_b.sort()
|
||||
|
||||
dist = 0
|
||||
for a_val, b_val in zip(list_a, list_b):
|
||||
dist += abs(a_val - b_val)
|
||||
|
||||
return dist
|
||||
|
||||
|
||||
def similarity(list_a: list[int], list_b: list[int]) -> int:
|
||||
sim = 0
|
||||
for a_val in list_a:
|
||||
sim += a_val * list_b.count(a_val)
|
||||
|
||||
return sim
|
||||
|
||||
|
||||
def main():
|
||||
list_a, list_b = readinput()
|
||||
|
||||
# part1
|
||||
print("Distance: %d" % distance(list_a, list_b))
|
||||
|
||||
# part 2
|
||||
print("Similarity: %d" % similarity(list_a, list_b))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
76
2024/02/main.py
Executable file
76
2024/02/main.py
Executable file
|
@ -0,0 +1,76 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||||
|
||||
# Author: Sebastian Mark
|
||||
# CC-BY-SA (https://creativecommons.org/licenses/by-sa/4.0/deed.de)
|
||||
|
||||
# pylint: disable=missing-module-docstring,missing-function-docstring,consider-using-f-string
|
||||
|
||||
|
||||
def readinput() -> list[int]:
|
||||
reports = []
|
||||
with open("input", "r", encoding="utf-8") as file:
|
||||
for line in file:
|
||||
levels = list(map(int, line.split(" ")))
|
||||
reports.append(levels)
|
||||
return reports
|
||||
|
||||
|
||||
def is_valid_level_difference(i: int, j: int) -> bool:
|
||||
if i == j:
|
||||
return False
|
||||
|
||||
if abs(i - j) > 3:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def is_sorted(levels: list) -> bool:
|
||||
asc_sorted = levels == sorted(levels)
|
||||
desc_sorted = levels == sorted(levels, reverse=True)
|
||||
return asc_sorted or desc_sorted
|
||||
|
||||
|
||||
def is_save(levels: list) -> bool:
|
||||
if not is_sorted(levels):
|
||||
return False
|
||||
|
||||
for i in range(len(levels) - 1):
|
||||
if not is_valid_level_difference(levels[i], levels[i + 1]):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def remove_level_by_index(levels: list, index: int) -> list:
|
||||
copy = levels.copy()
|
||||
copy.pop(index)
|
||||
return copy
|
||||
|
||||
|
||||
def is_save_with_damper(levels: list) -> bool:
|
||||
if is_save(levels):
|
||||
return True
|
||||
|
||||
for i in range(len(levels)):
|
||||
if is_save(remove_level_by_index(levels, i)):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
reports = readinput()
|
||||
|
||||
# part 1
|
||||
save_count = sum(is_save(report) for report in reports)
|
||||
print("Save reports: %d" % save_count)
|
||||
|
||||
# part 2
|
||||
save_count = sum(is_save_with_damper(report) for report in reports)
|
||||
print("Save reports (with damper): %d" % save_count)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
52
2024/03/main.py
Normal file
52
2024/03/main.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||||
|
||||
# Author: Sebastian Mark
|
||||
# CC-BY-SA (https://creativecommons.org/licenses/by-sa/4.0/deed.de)
|
||||
|
||||
# pylint: disable=missing-module-docstring,missing-function-docstring,consider-using-f-string
|
||||
|
||||
import re
|
||||
|
||||
|
||||
def readinput() -> str:
|
||||
with open("input", "r", encoding="utf-8") as file:
|
||||
lines = file.read()
|
||||
return lines
|
||||
|
||||
|
||||
def find_and_execute_instructions(m: str) -> int:
|
||||
regex = r"mul\((\d{1,3}),(\d{1,3})\)"
|
||||
res = sum(int(inst[0]) * int(inst[1]) for inst in re.findall(regex, m))
|
||||
return res
|
||||
|
||||
|
||||
def find_and_execute_enabled_instructions(m: str) -> int:
|
||||
regex = r"mul\(\d{1,3},\d{1,3}\)|do\(\)|don't\(\)"
|
||||
|
||||
res = 0
|
||||
allowed = True
|
||||
for inst in re.findall(regex, m):
|
||||
if inst.startswith("mul"):
|
||||
if allowed:
|
||||
res += find_and_execute_instructions(inst)
|
||||
else:
|
||||
allowed = inst.startswith("do()")
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def main():
|
||||
currupted_memory = readinput()
|
||||
|
||||
# part 1
|
||||
instructions_result = find_and_execute_instructions(currupted_memory)
|
||||
print("Result: %d" % instructions_result)
|
||||
|
||||
# part 2
|
||||
instructions_result = find_and_execute_enabled_instructions(currupted_memory)
|
||||
print("Result (only enabled): %d" % instructions_result)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
89
2024/04/main.py
Normal file
89
2024/04/main.py
Normal file
|
@ -0,0 +1,89 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||||
|
||||
# Author: Sebastian Mark
|
||||
# CC-BY-SA (https://creativecommons.org/licenses/by-sa/4.0/deed.de)
|
||||
|
||||
# pylint: disable=missing-module-docstring,missing-function-docstring,consider-using-f-string
|
||||
|
||||
|
||||
def readinput() -> list:
|
||||
with open("input", "r", encoding="utf-8") as file:
|
||||
lines = file.readlines()
|
||||
return lines
|
||||
|
||||
|
||||
def find_xmas(grid: list[list], x: int, y: int) -> int:
|
||||
height = len(grid) - 1
|
||||
width = len(grid[0]) - 1
|
||||
|
||||
count = 0
|
||||
for searchstring in ["XMAS", "SAMX"]:
|
||||
# horizontal right
|
||||
if x + 3 <= width:
|
||||
found = sum(grid[y][x + i] == searchstring[i] for i in range(4))
|
||||
if found == 4:
|
||||
count += 1
|
||||
|
||||
# vertical down
|
||||
if y + 3 <= height:
|
||||
found = sum(grid[y + i][x] == searchstring[i] for i in range(4))
|
||||
if found == 4:
|
||||
count += 1
|
||||
|
||||
# diagonal down right
|
||||
if y + 3 <= height and x + 3 <= width:
|
||||
found = sum(grid[y + i][x + i] == searchstring[i] for i in range(4))
|
||||
if found == 4:
|
||||
count += 1
|
||||
|
||||
# diagonal down left
|
||||
if y + 3 <= height and x - 3 >= 0:
|
||||
found = sum(grid[y + i][x - i] == searchstring[i] for i in range(4))
|
||||
if found == 4:
|
||||
count += 1
|
||||
|
||||
return count
|
||||
|
||||
|
||||
def find_cross_mass(grid: list[list], x: int, y: int) -> int:
|
||||
# check clockwise for
|
||||
# M.M
|
||||
# .A.
|
||||
# S.S
|
||||
# then rotate the outer ring clockwise and check again
|
||||
for searchstring in ["MMSS", "SMMS", "SSMM", "MSSM"]:
|
||||
found = (
|
||||
grid[y - 1][x - 1] == searchstring[0]
|
||||
and grid[y - 1][x + 1] == searchstring[1]
|
||||
and grid[y + 1][x + 1] == searchstring[2]
|
||||
and grid[y + 1][x - 1] == searchstring[3]
|
||||
)
|
||||
if found:
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def main():
|
||||
grid = readinput()
|
||||
|
||||
count = 0
|
||||
for y, _ in enumerate(grid):
|
||||
for x, _ in enumerate(grid[0]):
|
||||
pos = grid[y][x]
|
||||
if pos in ["X", "S"]:
|
||||
count += find_xmas(grid, x, y)
|
||||
print("XMAS count: %d" % count)
|
||||
|
||||
count = 0
|
||||
for y in range(1, len(grid) - 1):
|
||||
for x in range(1, len(grid[0]) - 1):
|
||||
pos = grid[y][x]
|
||||
if pos == "A":
|
||||
count += find_cross_mass(grid, x, y)
|
||||
print("X-MAS count: %d" % count)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
92
2024/05/main.py
Normal file
92
2024/05/main.py
Normal file
|
@ -0,0 +1,92 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||||
|
||||
# Author: Sebastian Mark
|
||||
# CC-BY-SA (https://creativecommons.org/licenses/by-sa/4.0/deed.de)
|
||||
|
||||
# pylint: disable=missing-module-docstring,missing-function-docstring,consider-using-f-string
|
||||
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
def readinput() -> list:
|
||||
with open("input", "r", encoding="utf-8") as file:
|
||||
lines = file.readlines()
|
||||
return lines
|
||||
|
||||
|
||||
def get_orders_and_updates() -> tuple[list, list]:
|
||||
lines = readinput()
|
||||
|
||||
sep = lines.index("\n") # newline in input
|
||||
|
||||
rules = defaultdict(set)
|
||||
for line in lines[:sep]:
|
||||
a, b = map(int, line.split("|"))
|
||||
rules[a].add(b)
|
||||
|
||||
updates = []
|
||||
for line in lines[sep + 1 :]:
|
||||
updates.append(list(map(int, line.split(","))))
|
||||
|
||||
return (rules, updates)
|
||||
|
||||
|
||||
def validate_rules(update: list, rules: list) -> bool:
|
||||
for i in range(len(update) - 1):
|
||||
next_page = update[i + 1]
|
||||
page = update[i]
|
||||
if next_page not in rules[page]:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def get_middle_number(update: list) -> int:
|
||||
return update[int(len(update) / 2)]
|
||||
|
||||
|
||||
def fix_with_rules(update: list, rules: list) -> list:
|
||||
# this block is inspired by:
|
||||
# https://github.com/nitekat1124/advent-of-code-2024/blob/main/solutions/day05.py
|
||||
|
||||
# filter only the rules for the pages in the current update
|
||||
filtered_rules = defaultdict(set)
|
||||
for i in update:
|
||||
new_rules = []
|
||||
for x in rules[i]:
|
||||
if x in update:
|
||||
new_rules.append(x)
|
||||
filtered_rules[i] = new_rules
|
||||
|
||||
# the more filtered rules for the value exist,
|
||||
# the further to the end is has to be placed,
|
||||
# then reverse this
|
||||
ordered_keys = sorted(
|
||||
filtered_rules, key=lambda val: len(filtered_rules[val]), reverse=True
|
||||
)
|
||||
|
||||
return ordered_keys
|
||||
|
||||
|
||||
def main():
|
||||
rules, updates = get_orders_and_updates()
|
||||
|
||||
# part 1
|
||||
count = 0
|
||||
for update in updates:
|
||||
if validate_rules(update, rules):
|
||||
count += get_middle_number(update)
|
||||
print("Summed updates: %d" % count)
|
||||
|
||||
# part 2
|
||||
count = 0
|
||||
for update in updates:
|
||||
if not validate_rules(update, rules):
|
||||
new_update = fix_with_rules(update, rules)
|
||||
count += get_middle_number(new_update)
|
||||
print("Summ fixed updates: %d" % count)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in a new issue