#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();