AoC 2025 Advent of Code (Python)
By telleropnul, November 28, 2025
Advent of Code (AoC) is an Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like. Go check it out: Advent of Code
Input files: adventofcode2025inputs.zip
2025 Day 12 Part 02
2025 Day 12 Part 01
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| groups = [group.split("\n") for group in open("input").read().split("\n\n")]
gift_sizes = {}
for g in groups[:-1]:
id = int(g[0][:-1])
size = sum([r.count("#") for r in g])
gift_sizes[id] = size
p1 = 0
for r in groups[-1]:
width, length = r.split(":")[0].split("x")
space = int(width) * int(length)
required = r.split(" ")[1:]
space_req = 0
for i, v in enumerate(required):
space_req += int(v) * gift_sizes[i]
p1 += space >= space_req
print(p1) |
groups = [group.split("\n") for group in open("input").read().split("\n\n")]
gift_sizes = {}
for g in groups[:-1]:
id = int(g[0][:-1])
size = sum([r.count("#") for r in g])
gift_sizes[id] = size
p1 = 0
for r in groups[-1]:
width, length = r.split(":")[0].split("x")
space = int(width) * int(length)
required = r.split(" ")[1:]
space_req = 0
for i, v in enumerate(required):
space_req += int(v) * gift_sizes[i]
p1 += space >= space_req
print(p1)
2025 Day 11 Part 01 + 02
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| from collections import defaultdict
lines = open("input").read().splitlines()
outputs = defaultdict(list)
for line in lines:
a, b = line.split(": ")
outputs[a] = b.split(" ")
visited = {}
def dfs(current, target):
key = (current, target)
if key in visited:
return visited[key]
if current == target:
return 1
out = 0
for n in outputs[current]:
out += dfs(n, target)
visited[key] = out
return out
p1 = dfs("you", "out")
print(p1)
if dfs("dac", "out") > 0:
p2 = dfs("svr", "fft") * dfs("fft", "dac") * dfs("dac", "out")
else:
p2 = dfs("svr", "dac") * dfs("dac", "fft") * dfs("fft", "out")
print(p2) |
from collections import defaultdict
lines = open("input").read().splitlines()
outputs = defaultdict(list)
for line in lines:
a, b = line.split(": ")
outputs[a] = b.split(" ")
visited = {}
def dfs(current, target):
key = (current, target)
if key in visited:
return visited[key]
if current == target:
return 1
out = 0
for n in outputs[current]:
out += dfs(n, target)
visited[key] = out
return out
p1 = dfs("you", "out")
print(p1)
if dfs("dac", "out") > 0:
p2 = dfs("svr", "fft") * dfs("fft", "dac") * dfs("dac", "out")
else:
p2 = dfs("svr", "dac") * dfs("dac", "fft") * dfs("fft", "out")
print(p2)
2025 Day 11 Part 01
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| from collections import defaultdict
lines = open("input").read().splitlines()
outputs = defaultdict(list)
for line in lines:
a, b = line.split(":")
outputs[a].append(b.split(" "))
def dfs(node):
count = 0
for b in outputs[node]:
for a in b:
count += dfs(a)
print(a)
if a == "out":
return 1
return count
print(dfs("you")) |
from collections import defaultdict
lines = open("input").read().splitlines()
outputs = defaultdict(list)
for line in lines:
a, b = line.split(":")
outputs[a].append(b.split(" "))
def dfs(node):
count = 0
for b in outputs[node]:
for a in b:
count += dfs(a)
print(a)
if a == "out":
return 1
return count
print(dfs("you"))
2025 Day 10 Part 01 + 02
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
| # python -m pip install z3-solver
from z3 import *
lines = open("input").read().splitlines()
def f(target, buttons):
open = {frozenset()}
completed = set()
clicks = 0
while True:
next_open = set()
completed |= open
for current in open:
if current == target:
return clicks
for b in buttons:
next = set(current)
for i in b:
if i in next:
next.remove(i)
else:
next.add(i)
if next not in completed:
next_open.add(frozenset(next))
open = next_open
clicks += 1
def solve(target, buttons):
my_optimizer = z3.Optimize()
clicks = [Int(i) for i in range(len(buttons))]
for i, target_i in enumerate(target):
count = 0
for j, b in enumerate(buttons):
if i in b:
count += clicks[j]
my_optimizer.add(count == target_i)
my_optimizer.add(And([c >= 0 for c in clicks]))
my_optimizer.minimize(sum(clicks))
my_optimizer.check()
model = my_optimizer.model()
return sum([model.eval(c).as_long() for c in clicks])
p1 = 0
p2 = 0
for line in lines:
target_raw = line.split(" ")[0][1:-1]
target = set()
for i, v in enumerate(target_raw):
if v == "#":
target.add(i)
buttons = []
for buttons_raw in line.split(" ")[1:-1]:
buttons.append([int(b) for b in buttons_raw[1:-1].split(",")])
joltage = [int(j) for j in line.split("{")[1][:-1].split(",")]
p1 += f(target, buttons)
p2 += solve(joltage, buttons)
print("Part 1: " + str(p1))
print("Part 2: " + str(p2)) |
# python -m pip install z3-solver
from z3 import *
lines = open("input").read().splitlines()
def f(target, buttons):
open = {frozenset()}
completed = set()
clicks = 0
while True:
next_open = set()
completed |= open
for current in open:
if current == target:
return clicks
for b in buttons:
next = set(current)
for i in b:
if i in next:
next.remove(i)
else:
next.add(i)
if next not in completed:
next_open.add(frozenset(next))
open = next_open
clicks += 1
def solve(target, buttons):
my_optimizer = z3.Optimize()
clicks = [Int(i) for i in range(len(buttons))]
for i, target_i in enumerate(target):
count = 0
for j, b in enumerate(buttons):
if i in b:
count += clicks[j]
my_optimizer.add(count == target_i)
my_optimizer.add(And([c >= 0 for c in clicks]))
my_optimizer.minimize(sum(clicks))
my_optimizer.check()
model = my_optimizer.model()
return sum([model.eval(c).as_long() for c in clicks])
p1 = 0
p2 = 0
for line in lines:
target_raw = line.split(" ")[0][1:-1]
target = set()
for i, v in enumerate(target_raw):
if v == "#":
target.add(i)
buttons = []
for buttons_raw in line.split(" ")[1:-1]:
buttons.append([int(b) for b in buttons_raw[1:-1].split(",")])
joltage = [int(j) for j in line.split("{")[1][:-1].split(",")]
p1 += f(target, buttons)
p2 += solve(joltage, buttons)
print("Part 1: " + str(p1))
print("Part 2: " + str(p2))
2025 Day 09 Part 01 + 02
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
| lines = open("input").read().splitlines()
def is_valid(p1, p2):
x1, y1 = p1
x2, y2 = p2
top = min(y1, y2)
right = max(x1, x2)
lower = max(y1, y2)
left = min(x1, x2)
for w in walls:
c1, c2 = w
wall_top = min(c1[1], c2[1])
wall_lower = max(c1[1], c2[1])
wall_left = min(c1[0], c2[0])
wall_right = max(c1[0], c2[0])
if left < wall_right and \
wall_left < right and \
top < wall_lower and \
wall_top < lower:
return False
return True
corners = []
for l in lines:
a, b = l.split(",")
a = int(a)
b = int(b)
corners.append((a, b))
walls = list(zip(corners, corners[1:]))
walls.append((corners[-1], corners[0]))
p1 = 0
p2 = 0
for c1 in corners:
for c2 in corners:
if c1 > c2:
x1, y1 = c1
x2, y2 = c2
size = (abs(x1 - x2) + 1) * (abs(y1 - y2) + 1)
p1 = max(size, p1)
if size > p2:
if is_valid(c1, c2):
p2 = size
print(p1)
print(p2) |
lines = open("input").read().splitlines()
def is_valid(p1, p2):
x1, y1 = p1
x2, y2 = p2
top = min(y1, y2)
right = max(x1, x2)
lower = max(y1, y2)
left = min(x1, x2)
for w in walls:
c1, c2 = w
wall_top = min(c1[1], c2[1])
wall_lower = max(c1[1], c2[1])
wall_left = min(c1[0], c2[0])
wall_right = max(c1[0], c2[0])
if left < wall_right and \
wall_left < right and \
top < wall_lower and \
wall_top < lower:
return False
return True
corners = []
for l in lines:
a, b = l.split(",")
a = int(a)
b = int(b)
corners.append((a, b))
walls = list(zip(corners, corners[1:]))
walls.append((corners[-1], corners[0]))
p1 = 0
p2 = 0
for c1 in corners:
for c2 in corners:
if c1 > c2:
x1, y1 = c1
x2, y2 = c2
size = (abs(x1 - x2) + 1) * (abs(y1 - y2) + 1)
p1 = max(size, p1)
if size > p2:
if is_valid(c1, c2):
p2 = size
print(p1)
print(p2)
2025 Day 08 Part 02
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
| lines = open("input").read().splitlines()
boxes = [list(map(int, line.split(","))) for line in lines]
pairs = {}
for i, box1 in enumerate(boxes):
for j, box2 in enumerate(boxes[i + 1 :], i + 1):
pairs[(i, j)] = sum((a - b) ** 2 for a, b in zip(box1, box2))
pairs = sorted(pairs.items(), key=lambda x: x[1])
connected_sets: list[set] = []
connected = set()
for (i, j), d in pairs:
connected.add(i)
connected.add(j)
_id_i = -1
_id_j = -1
for idx, s in enumerate(connected_sets):
if i in s:
_id_i = idx
if j in s:
_id_j = idx
match (_id_i > -1, _id_j > -1):
case (False, False):
connected_sets.append(set([i, j]))
case (True, False):
connected_sets[_id_i].add(j)
case (False, True):
connected_sets[_id_j].add(i)
case (True, True) if _id_i != _id_j:
connected_sets[_id_i] |= connected_sets[_id_j]
del connected_sets[_id_j]
if len(connected) == len(boxes) and len(connected_sets) == 1:
print (boxes[i][0] * boxes[j][0])
exit() |
lines = open("input").read().splitlines()
boxes = [list(map(int, line.split(","))) for line in lines]
pairs = {}
for i, box1 in enumerate(boxes):
for j, box2 in enumerate(boxes[i + 1 :], i + 1):
pairs[(i, j)] = sum((a - b) ** 2 for a, b in zip(box1, box2))
pairs = sorted(pairs.items(), key=lambda x: x[1])
connected_sets: list[set] = []
connected = set()
for (i, j), d in pairs:
connected.add(i)
connected.add(j)
_id_i = -1
_id_j = -1
for idx, s in enumerate(connected_sets):
if i in s:
_id_i = idx
if j in s:
_id_j = idx
match (_id_i > -1, _id_j > -1):
case (False, False):
connected_sets.append(set([i, j]))
case (True, False):
connected_sets[_id_i].add(j)
case (False, True):
connected_sets[_id_j].add(i)
case (True, True) if _id_i != _id_j:
connected_sets[_id_i] |= connected_sets[_id_j]
del connected_sets[_id_j]
if len(connected) == len(boxes) and len(connected_sets) == 1:
print (boxes[i][0] * boxes[j][0])
exit()
2025 Day 08 Part 01
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| lines = open("input").read().splitlines()
boxes = [list(map(int, line.split(","))) for line in lines]
pairs = {}
for i, box1 in enumerate(boxes):
for j, box2 in enumerate(boxes[i + 1 :], i + 1):
pairs[(i, j)] = sum((a - b) ** 2 for a, b in zip(box1, box2))
pairs = sorted(pairs.items(), key=lambda x: x[1])
# nums = 10 if it's test data
nums = 10 if len(boxes) == 20 else 1000
pairs = pairs[:nums]
connected_sets: list[set] = []
for (i, j), d in pairs:
_id_i = -1
_id_j = -1
for idx, s in enumerate(connected_sets):
if i in s:
_id_i = idx
if j in s:
_id_j = idx
match (_id_i > -1, _id_j > -1):
case (False, False):
connected_sets.append(set([i, j]))
case (True, False):
connected_sets[_id_i].add(j)
case (False, True):
connected_sets[_id_j].add(i)
case (True, True) if _id_i != _id_j:
connected_sets[_id_i] |= connected_sets[_id_j]
del connected_sets[_id_j]
_lens = sorted([len(s) for s in connected_sets], reverse=True)
print (_lens[0] * _lens[1] * _lens[2]) |
lines = open("input").read().splitlines()
boxes = [list(map(int, line.split(","))) for line in lines]
pairs = {}
for i, box1 in enumerate(boxes):
for j, box2 in enumerate(boxes[i + 1 :], i + 1):
pairs[(i, j)] = sum((a - b) ** 2 for a, b in zip(box1, box2))
pairs = sorted(pairs.items(), key=lambda x: x[1])
# nums = 10 if it's test data
nums = 10 if len(boxes) == 20 else 1000
pairs = pairs[:nums]
connected_sets: list[set] = []
for (i, j), d in pairs:
_id_i = -1
_id_j = -1
for idx, s in enumerate(connected_sets):
if i in s:
_id_i = idx
if j in s:
_id_j = idx
match (_id_i > -1, _id_j > -1):
case (False, False):
connected_sets.append(set([i, j]))
case (True, False):
connected_sets[_id_i].add(j)
case (False, True):
connected_sets[_id_j].add(i)
case (True, True) if _id_i != _id_j:
connected_sets[_id_i] |= connected_sets[_id_j]
del connected_sets[_id_j]
_lens = sorted([len(s) for s in connected_sets], reverse=True)
print (_lens[0] * _lens[1] * _lens[2])
2025 Day 07 Part 02
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| grid = open("input").read().splitlines()
h, w = len(grid), len(grid[0])
timelines = {}
def f(p):
if p in timelines:
return timelines[p]
# We have not been here before.
x, y = p
if y >= h:
return 1 # We have reached the end of 1 timeline.
if p in splitters:
timelines[p] = f((x - 1, y + 1)) + f((x + 1, y + 1))
else:
timelines[p] = f((x, y + 1))
return timelines[p]
start = None
splitters = set()
for y in range(0, h):
for x in range(0, w):
p = (x , y)
c = grid[y][x]
if c == 'S':
start = p
elif c == '^':
splitters.add(p)
print (f(start)) |
grid = open("input").read().splitlines()
h, w = len(grid), len(grid[0])
timelines = {}
def f(p):
if p in timelines:
return timelines[p]
# We have not been here before.
x, y = p
if y >= h:
return 1 # We have reached the end of 1 timeline.
if p in splitters:
timelines[p] = f((x - 1, y + 1)) + f((x + 1, y + 1))
else:
timelines[p] = f((x, y + 1))
return timelines[p]
start = None
splitters = set()
for y in range(0, h):
for x in range(0, w):
p = (x , y)
c = grid[y][x]
if c == 'S':
start = p
elif c == '^':
splitters.add(p)
print (f(start))
2025 Day 07 Part 01
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| grid = open("input").read().splitlines()
h, w = len(grid), len(grid[0])
start = None
splitters = set()
for y in range(0, h):
for x in range(0, w):
p = (x , y)
c = grid[y][x]
if c == 'S':
start = p
elif c == '^':
splitters.add(p)
open = {start}
splitted = set()
while open:
p = open.pop()
x, y = p
if y < h:
if p in splitters:
splitted.add(p)
open.add((x + 1, y + 1))
open.add((x - 1, y + 1))
else:
open.add((x, y + 1))
print(len(splitted)) |
grid = open("input").read().splitlines()
h, w = len(grid), len(grid[0])
start = None
splitters = set()
for y in range(0, h):
for x in range(0, w):
p = (x , y)
c = grid[y][x]
if c == 'S':
start = p
elif c == '^':
splitters.add(p)
open = {start}
splitted = set()
while open:
p = open.pop()
x, y = p
if y < h:
if p in splitters:
splitted.add(p)
open.add((x + 1, y + 1))
open.add((x - 1, y + 1))
else:
open.add((x, y + 1))
print(len(splitted))
2025 Day 06 Part 02
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| from math import prod
data = open("input").read().splitlines()
operands = data[-1].split()
tot = 0
op = 0
nums = []
for j in range(0, len(data[0])):
pos_num = ""
# Get the column number.
for i in range(0, len(data)-1):
if data[i][j] != " ":
pos_num += data[i][j]
# If the column number is all whitespace,
# then the numbers end, and you operate them.
# Same if it is the last column.
if pos_num == "" or j == len(data[0])-1:
if j == len(data[0])-1:
nums.append(int(pos_num))
operand = operands[op]
if operand == '*':
tot += prod(nums)
else:
tot += sum(nums)
nums = []
op += 1
# If the column contains some number,
# delete the whitespace and add the number.
else:
nums.append(int(pos_num))
print(tot) |
from math import prod
data = open("input").read().splitlines()
operands = data[-1].split()
tot = 0
op = 0
nums = []
for j in range(0, len(data[0])):
pos_num = ""
# Get the column number.
for i in range(0, len(data)-1):
if data[i][j] != " ":
pos_num += data[i][j]
# If the column number is all whitespace,
# then the numbers end, and you operate them.
# Same if it is the last column.
if pos_num == "" or j == len(data[0])-1:
if j == len(data[0])-1:
nums.append(int(pos_num))
operand = operands[op]
if operand == '*':
tot += prod(nums)
else:
tot += sum(nums)
nums = []
op += 1
# If the column contains some number,
# delete the whitespace and add the number.
else:
nums.append(int(pos_num))
print(tot)
2025 Day 06 Part 01
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| from math import prod
lines = open("input").read().splitlines()
lines = [(line.split(" ")) for line in lines]
tot = 0
for x in range (0, len(lines[0])):
args = []
for y in range (0, len(lines)-1):
args.append(int(lines[y][x]))
if lines[len(lines)-1][x] == '*':
tot += prod(args)
else:
tot += sum(args)
print(tot) |
from math import prod
lines = open("input").read().splitlines()
lines = [(line.split(" ")) for line in lines]
tot = 0
for x in range (0, len(lines[0])):
args = []
for y in range (0, len(lines)-1):
args.append(int(lines[y][x]))
if lines[len(lines)-1][x] == '*':
tot += prod(args)
else:
tot += sum(args)
print(tot)
2025 Day 05 Part 02
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| lines, _ = open("input").read().split("\n\n")
ranges = []
for line in lines.splitlines():
start, end = map(int, line.split('-'))
ranges.append((start, end))
# Sort ranges by start value
ranges.sort()
# Merge overlapping ranges
merged = []
for start, end in ranges:
if not merged:
merged.append((start, end))
else:
last_start, last_end = merged[-1]
# If current range overlaps or is adjacent to the last merged range
if start <= last_end + 1:
# Merge: extend the last range if needed
merged[-1] = (last_start, max(last_end, end))
else:
# No overlap: add as new range
merged.append((start, end))
# Calculate total number of IDs in all merged ranges
total = 0
for start, end in merged:
total += (end - start + 1)
print (total) |
lines, _ = open("input").read().split("\n\n")
ranges = []
for line in lines.splitlines():
start, end = map(int, line.split('-'))
ranges.append((start, end))
# Sort ranges by start value
ranges.sort()
# Merge overlapping ranges
merged = []
for start, end in ranges:
if not merged:
merged.append((start, end))
else:
last_start, last_end = merged[-1]
# If current range overlaps or is adjacent to the last merged range
if start <= last_end + 1:
# Merge: extend the last range if needed
merged[-1] = (last_start, max(last_end, end))
else:
# No overlap: add as new range
merged.append((start, end))
# Calculate total number of IDs in all merged ranges
total = 0
for start, end in merged:
total += (end - start + 1)
print (total)
2025 Day 05 Part 01
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| IDranges, IDs = open("input").read().split("\n\n")
IDranges = IDranges.splitlines()
IDs = IDs.splitlines()
fresh = 0
for ID in IDs:
for IDrange in IDranges:
start,end = IDrange.split("-")
if int(start) <= int(ID) <= int(end):
#print(ID)
fresh += 1
break
print (fresh) |
IDranges, IDs = open("input").read().split("\n\n")
IDranges = IDranges.splitlines()
IDs = IDs.splitlines()
fresh = 0
for ID in IDs:
for IDrange in IDranges:
start,end = IDrange.split("-")
if int(start) <= int(ID) <= int(end):
#print(ID)
fresh += 1
break
print (fresh)
2025 Day 04 Part 02
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
| grid = open("input").read().splitlines()
grid1 = grid.copy()
h, w = len(grid), len(grid[0])
moves = [(-1,-1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)]
def change_letter(string, letter, index): # string is bad variable name.
return string[:index] + letter + string[index+1:]
def loc(y, x):
if y < 0 or x < 0:
return None
try:
return grid[y][x]
except Exception:
return None
def bfs(start):
cur = set([start])
rolls = 0
for y, x in list(cur):
if loc(y, x) == '@':
for ny, nx in list((y+dy, x+dx) for dy, dx in moves):
if loc(ny, nx) == '@':
rolls +=1
if rolls < 4:
# grid1[y][x] = '.' No can't do.
line = change_letter(grid1[y], '.', x)
grid1[y] = line
return 1
else:
return 0
else:
return 0
def run_grid():
tot = 0
for y in range(h):
for x in range(w):
tot += bfs((y, x))
return (tot)
tots = 0
tots_previous = -1
while True:
tots += run_grid()
if tots == tots_previous:
break
grid = grid1.copy()
tots_previous = tots
print(tots) |
grid = open("input").read().splitlines()
grid1 = grid.copy()
h, w = len(grid), len(grid[0])
moves = [(-1,-1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)]
def change_letter(string, letter, index): # string is bad variable name.
return string[:index] + letter + string[index+1:]
def loc(y, x):
if y < 0 or x < 0:
return None
try:
return grid[y][x]
except Exception:
return None
def bfs(start):
cur = set([start])
rolls = 0
for y, x in list(cur):
if loc(y, x) == '@':
for ny, nx in list((y+dy, x+dx) for dy, dx in moves):
if loc(ny, nx) == '@':
rolls +=1
if rolls < 4:
# grid1[y][x] = '.' No can't do.
line = change_letter(grid1[y], '.', x)
grid1[y] = line
return 1
else:
return 0
else:
return 0
def run_grid():
tot = 0
for y in range(h):
for x in range(w):
tot += bfs((y, x))
return (tot)
tots = 0
tots_previous = -1
while True:
tots += run_grid()
if tots == tots_previous:
break
grid = grid1.copy()
tots_previous = tots
print(tots)
2025 Day 04 Part 01
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| grid = open("input").read().splitlines()
h, w = len(grid), len(grid[0])
moves = [(-1,-1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)]
def loc(y, x):
if y < 0 or x < 0:
return None
try:
return grid[y][x]
except Exception:
return None
def bfs(start):
cur = set([start])
rolls = 0
for y, x in list(cur):
if loc(y, x) == '@':
for ny, nx in list((y+dy, x+dx) for dy, dx in moves):
if loc(ny, nx) == '@':
rolls +=1
if rolls < 4:
return 1
else:
return 0
else:
return 0
tot = 0
for y in range(h):
for x in range(w):
tot += bfs((y, x))
print(tot) |
grid = open("input").read().splitlines()
h, w = len(grid), len(grid[0])
moves = [(-1,-1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)]
def loc(y, x):
if y < 0 or x < 0:
return None
try:
return grid[y][x]
except Exception:
return None
def bfs(start):
cur = set([start])
rolls = 0
for y, x in list(cur):
if loc(y, x) == '@':
for ny, nx in list((y+dy, x+dx) for dy, dx in moves):
if loc(ny, nx) == '@':
rolls +=1
if rolls < 4:
return 1
else:
return 0
else:
return 0
tot = 0
for y in range(h):
for x in range(w):
tot += bfs((y, x))
print(tot)
2025 Day 03 Part 02
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| def find_max_joltage(n: int) -> int:
res = 0
digits = [int(char) for char in str(n)]
left = 0
right = len(digits) - 12
while right < len(digits):
max_tuple = left, digits[left]
for i in range(left + 1, right + 1):
if digits[i] > digits[max_tuple[0]]:
max_tuple = i, digits[i]
res = res * 10 + max_tuple[1]
right += 1
left = max_tuple[0] + 1
return res
lines = open("input").read().splitlines()
sumjolts = 0
for line in lines:
maxjolt = find_max_joltage(line)
print(maxjolt)
sumjolts += maxjolt
print (sumjolts) |
def find_max_joltage(n: int) -> int:
res = 0
digits = [int(char) for char in str(n)]
left = 0
right = len(digits) - 12
while right < len(digits):
max_tuple = left, digits[left]
for i in range(left + 1, right + 1):
if digits[i] > digits[max_tuple[0]]:
max_tuple = i, digits[i]
res = res * 10 + max_tuple[1]
right += 1
left = max_tuple[0] + 1
return res
lines = open("input").read().splitlines()
sumjolts = 0
for line in lines:
maxjolt = find_max_joltage(line)
print(maxjolt)
sumjolts += maxjolt
print (sumjolts)
2025 Day 03 Part 01
1
2
3
4
5
6
7
8
9
10
11
12
13
| lines = open("input").read().splitlines()
maxjolt = 0
sumjolts = 0
for line in lines:
for i, x in enumerate(line):
for y in range (i+1, len(line)):
jolt = int(x+line[y])
#jolt = int(''.join([x,line[y]]))
if jolt > maxjolt:
maxjolt = jolt
sumjolts += maxjolt
maxjolt = 0
print (sumjolts) |
lines = open("input").read().splitlines()
maxjolt = 0
sumjolts = 0
for line in lines:
for i, x in enumerate(line):
for y in range (i+1, len(line)):
jolt = int(x+line[y])
#jolt = int(''.join([x,line[y]]))
if jolt > maxjolt:
maxjolt = jolt
sumjolts += maxjolt
maxjolt = 0
print (sumjolts)
2025 Day 02 Part 02
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| def check_string_repeats(s: str) -> bool:
"""
Purpose:
Checks if the string consists of multiple repeats.
Arguments:
s: The input string.
Returns:
True if the string is a repeated sequence, False otherwise.
"""
# Initialize result as False
res = False
# Iterate through possible lengths of substrings
for i in range(1, len(s) // 2 + 1):
# Check if current length divides the string evenly
if len(s) % i == 0:
# Check if the substring repeats to form the string
if s[:i] * (len(s) // i) == s:
res = True
break
return(res)
suminvalids = 0
lines = open("input").read().split(",")
for line in lines:
firstID, lastID = line.split("-")
for s in range (int(firstID), int(lastID)+1):
if check_string_repeats(str(s)):
suminvalids += int(s)
print(suminvalids) |
def check_string_repeats(s: str) -> bool:
"""
Purpose:
Checks if the string consists of multiple repeats.
Arguments:
s: The input string.
Returns:
True if the string is a repeated sequence, False otherwise.
"""
# Initialize result as False
res = False
# Iterate through possible lengths of substrings
for i in range(1, len(s) // 2 + 1):
# Check if current length divides the string evenly
if len(s) % i == 0:
# Check if the substring repeats to form the string
if s[:i] * (len(s) // i) == s:
res = True
break
return(res)
suminvalids = 0
lines = open("input").read().split(",")
for line in lines:
firstID, lastID = line.split("-")
for s in range (int(firstID), int(lastID)+1):
if check_string_repeats(str(s)):
suminvalids += int(s)
print(suminvalids)
2025 Day 02 Part 01
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| def check_string_halves_equality(s: str) -> bool:
"""
Purpose:
Checks if the first half of a string is equal to its second half.
Arguments:
s: The input string.
Returns:
True if the first half is equal to the second half, False otherwise.
Returns False if the string has an odd length.
"""
n = len(s)
# If string length is odd,
# it cannot be perfectly divided into two equal halves.
if n % 2 != 0:
return False
midpoint = n // 2
first_half = s[:midpoint]
second_half = s[midpoint:]
return first_half == second_half
suminvalids = 0
lines = open("input").read().split(",")
for line in lines:
firstID, lastID = line.split("-")
for s in range(int(firstID), int(lastID)+1):
if check_string_halves_equality(str(s)):
suminvalids += int(s)
print(suminvalids) |
def check_string_halves_equality(s: str) -> bool:
"""
Purpose:
Checks if the first half of a string is equal to its second half.
Arguments:
s: The input string.
Returns:
True if the first half is equal to the second half, False otherwise.
Returns False if the string has an odd length.
"""
n = len(s)
# If string length is odd,
# it cannot be perfectly divided into two equal halves.
if n % 2 != 0:
return False
midpoint = n // 2
first_half = s[:midpoint]
second_half = s[midpoint:]
return first_half == second_half
suminvalids = 0
lines = open("input").read().split(",")
for line in lines:
firstID, lastID = line.split("-")
for s in range(int(firstID), int(lastID)+1):
if check_string_halves_equality(str(s)):
suminvalids += int(s)
print(suminvalids)
2025 Day 01 Part 02
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| lines = open("input").read().splitlines()
dial = 50
lastdial = 50
countzero = 0
for line in lines:
countzero += int(line[1:]) // 100
if line[0] == "L":
dial -= int(line[1:]) % 100
elif line[0] == "R":
dial += int(line[1:]) % 100
if dial < 0:
dial += 100
if lastdial != 0:
countzero += 1
if dial > 99:
dial -= 100
if dial != 0:
countzero += 1
if dial == 0:
countzero += 1
print (dial, countzero)
lastdial = dial
print (countzero) |
lines = open("input").read().splitlines()
dial = 50
lastdial = 50
countzero = 0
for line in lines:
countzero += int(line[1:]) // 100
if line[0] == "L":
dial -= int(line[1:]) % 100
elif line[0] == "R":
dial += int(line[1:]) % 100
if dial < 0:
dial += 100
if lastdial != 0:
countzero += 1
if dial > 99:
dial -= 100
if dial != 0:
countzero += 1
if dial == 0:
countzero += 1
print (dial, countzero)
lastdial = dial
print (countzero)
2025 Day 01 Part 01
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| lines = open("input").read().splitlines()
dial = 50
countzero = 0
for line in lines:
if line[0] == "L":
dial -= int(line[1:]) % 100
elif line[0] == "R":
dial += int(line[1:]) % 100
if dial < 0:
dial += 100
if dial > 99:
dial -= 100
if dial == 0:
countzero += 1
print (countzero) |
lines = open("input").read().splitlines()
dial = 50
countzero = 0
for line in lines:
if line[0] == "L":
dial -= int(line[1:]) % 100
elif line[0] == "R":
dial += int(line[1:]) % 100
if dial < 0:
dial += 100
if dial > 99:
dial -= 100
if dial == 0:
countzero += 1
print (countzero)