summaryrefslogtreecommitdiff
path: root/2024/aoc2024-d05.py
blob: 2f8490a823e4f93bc53b9d789a14842cf64f155c (plain)
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
#advent of code 2024
#day 05
#cool, but seemed harder on first glance
#part1: keep looking up the rules for each page in an update
#if any of the pages in rules are present before the current page
#then the update is incorrect, else add the middle page to part1 score
#part2: keep correcting the order until each rule is satisfied
#popping the incorrectly placed page, then inserting it at the index
#of the page violating the rule
#edit: apparently there's a cycle in the rules which may lead to inifite 
#corrections, but in my solution, or at least for my input, that isnt the case

f = open("05.in","r");
r, u = f.read().split("\n\n"); #rules and updates
f.close();
rules, updates = {}, [];
part1 = 0;
part2 = 0;

for l in r.split("\n"):
	v1, v2 = [int(x) for x in l.split("|")];
	if not v1 in rules: rules[v1] = [];
	rules[v1].append(v2);

for l in u.split("\n")[:-1]: #skipping last line because its reading an empty line
	updates.append([int(x) for x in l.split(",")]);

def Verify(update):
	ok = True;
	for x, page in enumerate(update):
		if page in rules:
			for rule in rules[page]:
				if rule in update[0:x]: ok = False;
	return ok*update[len(update)//2];

def correction(update):
	NewUpdate = update.copy();
	ok = False; 
	while not ok: 
		ok = True;
		for x, page in enumerate(NewUpdate):
			if page in rules:
				for y in range(x,-1,-1):
					if NewUpdate[y] in rules[page]:
						ok = False;
						NewUpdate.pop(x);
						NewUpdate.insert(y, page);
						break; 
	return NewUpdate[len(NewUpdate)//2];

for update in updates:
	score = Verify(update);
	part1 += score;
	if score == 0: part2 += correction(update);
	
print("part 1 =", part1);
print("part 2 =", part2);