summaryrefslogtreecommitdiff
path: root/2024/aoc2024-d14.py
blob: c824d96b247a6341684bab7e4dfd26ce1019049a (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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#advent of code 2024
#day 14
#correctly assumed that the picture will show up 
#if the robots don't overlap
#doing previous years with online help paid off
#NOTE: I learned that it's not recommended to
#take modulo of a negative value
#however there was no problem with that in python 

import re

class robot:
	def __init__(self,rx,ry,rvx,rvy):
		self.posx = rx;
		self.posy = ry;
		self.startx = rx; #useless, no need to reset
		self.starty = ry; #useless, no need to reset
		self.velx = rvx;
		self.vely = rvy;
	def move(self,steps):
		self.posx = (self.posx + steps*self.velx)%xMax;
		self.posy = (self.posy + steps*self.vely)%yMax;
	def currentpos(self):
		return (self.posx,self.posy);
	def resetpos(self): #useless, no need to reset
		self.posx = self.startx;
		self.posy = self.starty;

robots = [];
xMin = 0;	#from part 1 description, grid range
yMin = 0;	#from part 1 description, grid range
xMax = 101; #from part 1 description, grid range
yMax = 103; #from part 1 description, grid range

f = open("14.in","r");
for l in f:
	nums = re.findall(r'-?\d+',l)
	robots.append(robot(*[int(n) for n in nums]));
f.close();

RobotPositions = {};
TimeElapsed = 100; #from part 1 description, time of simulation

for r in robots:
	r.move(TimeElapsed);
	robx,roby = r.currentpos();
	if RobotPositions.get((robx,roby),None) == None:
		RobotPositions[(robx,roby)] = 0;
	RobotPositions[(robx,roby)] += 1;

part1 = 1; #Safety Factor to multiply
qlim = [(0,xMax//2,0,yMax//2),(1+xMax//2,xMax+1,0,yMax//2),(0,xMax//2,1+yMax//2,yMax+1),(1+xMax//2,xMax+1,1+yMax//2,yMax+1)];
#qlim = ranges of each quadrant in format: x_min,x_max,y_min,y_max
#not to be confused with xMin,xMax,yMin,yMax of the total grid
#could probably change it a bit and check which quadrant given robot 
#belongs to after calculating its position at TimeElapsed
#and count them during "r in robots" for loop
for qx1,qx2,qy1,qy2 in qlim:
	robotcountq = 0; #number of robots for each quadrant
	for y in range(qy1,qy2):
		for x in range(qx1,qx2):
			robotcountq += RobotPositions.get((x,y),0);
	part1 *= robotcountq;

print("part 1 = ", part1);
TotalRobots = len(robots);
#I assume (in hindsight: correctly) that the picture doesn't show up before the 100s mark from part 1
#in general robots' positions should be reset and then start the timer from t = 0
while True:
	TimeElapsed += 1;
	RobotSpots = set();
	for r in robots:
		r.move(1);
		robx,roby = r.currentpos();
		RobotSpots.add((robx,roby));
	if len(RobotSpots)==TotalRobots: break;
part2 = TimeElapsed;
print("part 2 = ", part2);
#commented out the print of the tree itself
#for y in range(yMax):
#	for x in range(xMax):
#		c = ".";
#		if (x,y) in RobotSpots: c = "#";
#		#c = RobotPositions.get((x,y),".");
#		print(c,end="");
#	print();