summaryrefslogtreecommitdiff
path: root/2024/aoc2024-d06.py
blob: e5da9b450c4bfd5490cf09173d467e74763c2de1 (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
58
59
60
61
62
63
#advent of code 2024
#day 06
#cleaned up


grid = {};
xMin, yMin, xMax, yMax = 0, 0, 0, 0;
dirs = [(0,-1),(1,0),(0,1),(-1,0)];
d = 0; #starting direction of the guard

f = open("06.in","r");
for y, l in enumerate(f):
	yMax = max(yMax,y);
	for x, c in enumerate(l[:-1]):
		xMax = max(xMax,x);
		if c == "^": 
			guard1 = (x,y); #guard position
			guard2 = (x,y); #guard pos for part 2
			c = ".";
		grid[(x,y)] = c;
f.close();

visited = set();
while True:
	gx, gy = guard1; #split guard coordinates
	dx, dy = dirs[d];
	if not (xMin <= gx <= xMax)*(yMin <= gy <= yMax): break;
	if grid.get((gx+dx,gy+dy),".") == "#":
		d = (d+1)%4;
		dx, dy = dirs[d];
	visited.add(guard1);
	guard1 = (gx+dx,gy+dy);

#definition of loop: if the guard meets the same obstacle twice, then he's looping
def bruteforce(NewPos,guard): #check if inserting in NewPos position an obstacle will create a loop
	d = 0;
	obstacles = set(); 
	#register in set "obstacles" encountered obstacles in format: x,y,d, 
	#where d is the direction from which guard encountered the obstacle
	ok = True
	while True:
		gx, gy = guard;
		dx, dy = dirs[d];
		if not (xMin <= gx+dy <= xMax)*(yMin <= gy+dy <= yMax): 
			ok = False; #if the guard left the grid then the new obstacle didnt work
			break;
		if grid.get((gx+dx,gy+dy),".") == "#" or (gx+dx,gy+dy)==NewPos:
			d = (d+1)%4;
			dx, dy = dirs[d];
			if (guard,d) in obstacles: break;
			obstacles.add((guard,d));
		else:
			guard = (gx+dx,gy+dy);
	return ok; 

NewPlaces = set(); #store the correct possibilites in a set just in case to prevent duplicates
for v in visited: #simulate another guard patrol for each possible new position v
	if bruteforce(v,guard2): NewPlaces.add(v); #if he loops, +1 to score

part1 = len(visited);
part2 = len(NewPlaces);
print("part 1 =", part1);
print("part 2 =", part2);