Part 1:
with open('input') as data:
lines = [l.strip() for l in data.readlines()]
# Remove empty line
class Result():
def __init__(self):
self.count = 0
def analyze_lines(lines: list[str]):
ans.count += get_rights(lines)
ans.count += get_ups(lines)
ans.count += get_downs(lines)
ans.count += get_down_rights(lines)
ans.count += get_down_lefts(lines)
ans.count += get_up_lefts(lines)
ans.count += get_up_rights(lines)
for line in lines:
ans.count += get_lefts(line)
def get_ups(lines: list[str]) -> int:
up_count = 0
for i_l, line in enumerate(lines):
result = ""
if i_l < 3:
continue
for i_c, char in enumerate(line):
if char == "X":
result = char
result += "".join([lines[i_l - n][i_c] for n in range(1, 4)])
if result == "XMAS":
up_count += 1
else:
result = ""
return up_count
def get_downs(lines: list[str]) -> int:
down_count = 0
for i_l, l in enumerate(lines):
result = ""
for i_c, c in enumerate(l):
if c == "X":
result += c
try:
result += "".join([lines[i_l + n][i_c] for n in range(1, 4)])
except IndexError:
result = ""
continue
finally:
if result == "XMAS":
down_count += 1
result = ""
return down_count
def get_lefts(line: str) -> int:
left_count = 0
for i, char in enumerate(line):
if i < 3:
continue
elif char == "X" and line[i-1] == "M" and line[i-2] == "A" and line[i-3] == "S":
left_count += 1
return left_count
def get_rights(lines: list[str]) -> int:
right_counts = 0
for l in lines:
right_counts += l.count("XMAS")
return right_counts
def get_down_rights(lines: list[str]) -> int:
down_right_count = 0
for i_l, l in enumerate(lines):
result = ""
for i_c, c in enumerate(l):
if c == "X":
result += c
try:
result += "".join(
[lines[i_l + n][i_c + n] for n in range(1,4)]
)
except IndexError:
result = ""
continue
finally:
if result == "XMAS":
down_right_count += 1
result = ""
return down_right_count
def get_down_lefts(lines: list[str]) -> int:
down_left_count = 0
for i_l, l in enumerate(lines):
result = ""
for i_c, c in enumerate(l):
if i_c < 3:
continue
if c == "X":
result += c
try:
result += "".join(
[lines[i_l + n][i_c - n] for n in range(1,4)]
)
except IndexError:
result = ""
continue
finally:
if result == "XMAS":
down_left_count += 1
result = ""
return down_left_count
def get_up_rights(lines: list[str]) -> int:
up_right_count = 0
for i_l, l in enumerate(lines):
result = ""
if i_l < 3:
continue
for i_c, c in enumerate(l):
if c == "X":
result += c
try:
result += "".join(
[lines[i_l - n][i_c + n] for n in range(1,4)]
)
except IndexError:
result = ""
continue
finally:
if result == "XMAS":
up_right_count += 1
result = ""
return up_right_count
def get_up_lefts(lines: list[str]) -> int:
up_left_count = 0
for i_l, l in enumerate(lines):
result = ""
if i_l < 3:
continue
for i_c, c in enumerate(l):
if i_c < 3:
continue
if c == "X":
result = c
try:
result += "".join(
[lines[i_l - n][i_c - n] for n in range(1,4)]
)
except IndexError as e:
result = ""
continue
finally:
if result == "XMAS":
up_left_count += 1
result = ""
return up_left_count
ans = Result()
analyze_lines(lines)
print(ans.count)
Part 2:
with open('input') as data:
lines = list(filter(lambda x: x != '', [l.strip() for l in data.readlines()]))
xmases = 0
for i in range(1, len(lines)):
for j in range(1, len(lines[i])):
if lines[i][j] == "A":
try:
up_back = lines[i-1][j-1]
down_over = lines[i+1][j+1]
up_over = lines[i-1][j+1]
down_back = lines[i+1][j-1]
except IndexError:
continue
else:
if {up_back, down_over} == set("MS") and {up_over, down_back} == set("MS"):
xmases += 1
print(xmases)
I actually found part two A LOT easier than part 1.
Python
(Part 1) omg I can’t believe this actually worked first try!
with open('input') as data: parts = data.read().rstrip().split("\n\n") ordering_rules = parts[0].split("\n") updates = parts[1].split("\n") correct_updates = [] middle_updates = [] def find_relevant_rules(pg_num: str, rules: list[str]) -> list[str] | None: for rule in rules: return list(filter(lambda x: x.split("|")[0] == pg_num, rules)) def interpret_rule(rule: str) -> list[str]: return rule.split("|") def interpret_update(update: str) -> list[str]: return update.split(",") def find_middle_update_index(update: list[str]) -> int: num_of_elements = len(update) return num_of_elements // 2 for update in updates: is_correct = True for i, page in enumerate(interpret_update(update)): rules_to_check = find_relevant_rules(page, ordering_rules) for rule in rules_to_check: if rule.split("|")[1] in interpret_update(update)[:i]: is_correct = False if is_correct: correct_updates.append(update) for update in correct_updates: split_update = update.split(",") middle_updates.append(int(split_update[find_middle_update_index(split_update)])) print(sum(middle_updates))