From 5b8623d06472ec9a4bcac8ea1e201b7ae528d7af Mon Sep 17 00:00:00 2001 From: b-idea Date: Sat, 7 Oct 2023 17:18:02 +0200 Subject: added day 13 solution --- 2018/aoc2018-d13.py | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 2018/aoc2018-d13.py diff --git a/2018/aoc2018-d13.py b/2018/aoc2018-d13.py new file mode 100644 index 0000000..906ffa2 --- /dev/null +++ b/2018/aoc2018-d13.py @@ -0,0 +1,195 @@ +#advent of code 2018 +#day 13 +#part 1 and part 2 + +#I got it working the first time, but I was getting a wrong answer for actual input +#turns out I made a mistake in calculations for the crossroads for turn-left and turn-right +#i hastily scrambled a set of 2 equations for X and Y coordinates +#and it costed me time wasted on debugging +#for each round I was drawing the current layout of the map with a single cart +#I noticed that at crossroads it was doing a turn-left, straight, turn-left +#(instead of right for 3rd crossroads) +#I followed my equations by *slowly* calculating them on paper +#and found out that I had wrong signs for Y coordinate +#fun puzzle nonetheless +#comment for part2 +#i had a bit of an issue with getting it working properly +#at this moment, the part2 is calculated correctly, but part1 was off +#I cleaned up the code a bit and managed to solve this, so both parts are in the same file + +f = open("input.txt",'r'); +Testing = False; +#Testing = True; +if Testing: + f.close(); + f = open("testinput.txt",'r'); + +class trackpoint: + def __init__(self, sign, x, y): + self.sign = sign; + self.positionX = x; + self.positionY = y; + def __str__(self): + return self.sign; + +class hline(trackpoint): + def __init__(self, sign, x, y): + trackpoint.__init__(self, sign, x, y); + def GiveSteps(self, cart_x, cart_y, cartid): + #left or right + x_next = self.positionX + (self.positionX - cart_x); + y_next = self.positionY + (self.positionY - cart_y); + return [x_next, y_next]; + +class vline(trackpoint): + def __init__(self, sign, x, y): + trackpoint.__init__(self, sign, x, y); + def GiveSteps(self, cart_x, cart_y, cartid): + #up or down + x_next = self.positionX + (self.positionX - cart_x); + y_next = self.positionY + (self.positionY - cart_y); + return [x_next, y_next]; + +class turnleft(trackpoint): + def __init__(self, sign, x, y): + trackpoint.__init__(self, sign, x, y); + def GiveSteps(self, cart_x, cart_y, cartid): + x_next = self.positionX - (cart_y - self.positionY); + y_next = self.positionY - (cart_x - self.positionX); + return [x_next, y_next]; + +class turnright(trackpoint): + def __init__(self, sign, x, y): + trackpoint.__init__(self, sign, x, y); + def GiveSteps(self, cart_x, cart_y, cartid): + x_next = self.positionX + (cart_y - self.positionY); + y_next = self.positionY + (cart_x - self.positionX); + return [x_next, y_next]; + +class crossroads(trackpoint): + def __init__(self, sign, x, y): + trackpoint.__init__(self, sign, x, y); + self.CartRegistry = {}; + def GiveSteps(self, cart_x, cart_y, cartid): + #number of crossroads is updated before this function is called, thats why it starts from 1 + if (cartid%3 == 1): + #turn left + x_next = self.positionX - (cart_y - self.positionY); + y_next = self.positionY + (cart_x - self.positionX); + elif (cartid%3 == 2): + #go straight + x_next = self.positionX + (self.positionX - cart_x); + y_next = self.positionY + (self.positionY - cart_y); + elif (cartid%3 == 0): + #turn right + x_next = self.positionX + (cart_y - self.positionY); + y_next = self.positionY - (cart_x - self.positionX); + return [x_next, y_next]; + +class minecart: + def __init__(self, sign, x, y, cart_id): + self.posX = x; + self.posY = y; + self.XroadsEncountered = 0; + self.nextstepX = x; + self.nextstepY = y; + self.Cart_ID = cart_id; + self.notHit = True; + if (sign == '>'): + self.prevX = x-1; + self.prevY = y; + if (sign == '<'): + self.prevX = x+1; + self.prevY = y; + if (sign == 'v'): + self.prevX = x; + self.prevY = y-1; + if (sign == '^'): + self.prevX = x; + self.prevY = y+1; + def cartmove(self, nextX, nextY): + self.nextstepX = nextX; + self.nextstepY = nextY; + self.prevX = self.posX; + self.prevY = self.posY; + self.posX = self.nextstepX; + self.posY = self.nextstepY; + def ReadCoords(self): + return [self.posX, self.posY]; + def CheckMatch(self, OtherCoords): + return (self.posX == OtherCoords[0] and self.posY == OtherCoords[1]); + def IsXroads(self, currentsign): + if (currentsign == "+"): + self.XroadsEncountered += 1; + +trackmap = []; + +for l in f: + subline = []; + l.replace("\n", ""); + for c in l: + subline.append(c); + trackmap.append(subline.copy()); + +cartlist = []; +cartid_counter = 10; + +TMSize_C = len(trackmap); +TMSize_R = len(trackmap[0]) -1; +#RETREIVING MINECARTS AND REPLACING SIGNS ON THE MAP +for c in range(TMSize_C): + for r in range(TMSize_R): + if (trackmap[c][r] == '^' or trackmap[c][r] == 'v' or trackmap[c][r] == '>' or trackmap[c][r] == '<'): + cartlist.append( minecart(trackmap[c][r], r, c, cartid_counter) ); + cartid_counter += 1; + if (trackmap[c][r] == '^' or trackmap[c][r] == 'v'): + trackmap[c][r] = '|'; + if (trackmap[c][r] == '>' or trackmap[c][r] == '<'): + trackmap[c][r] = '-'; + +cartlist = sorted(cartlist, key=lambda x: (x.posY, x.posX)); +newmap = []; + +for c in range(TMSize_C): + templine = []; + for r in range(TMSize_R): + if (trackmap[c][r] == ' '): + templine.append( trackpoint(trackmap[c][r], r, c) ); + elif (trackmap[c][r] == '-'): + templine.append( hline(trackmap[c][r], r, c) ); + elif (trackmap[c][r] == '|'): + templine.append( vline(trackmap[c][r], r, c) ); + elif (trackmap[c][r] == '/'): + templine.append( turnright(trackmap[c][r], r, c) ); + elif (trackmap[c][r] == '\\'): + templine.append( turnleft(trackmap[c][r], r, c) ); + elif (trackmap[c][r] == '+'): + templine.append( crossroads(trackmap[c][r], r, c) ); + newmap.append( templine.copy() ); + +roundcounter = 0; +part1 = None; +p1round = 0; + +while (len(cartlist) > 1): + roundcounter += 1; + cartlist = sorted(cartlist, key=lambda x: (x.posY, x.posX)); + for mc in cartlist: + NextSteps = []; + mc.IsXroads(newmap[mc.posY][mc.posX].sign); + NextSteps = newmap[mc.posY][mc.posX].GiveSteps(mc.prevX, mc.prevY, mc.XroadsEncountered); + mc.cartmove(NextSteps[0],NextSteps[1]); + MatchCounter = 0; + for mc2 in cartlist: + if mc.Cart_ID != mc2.Cart_ID: + mc.notHit = not mc.CheckMatch( mc2.ReadCoords() ); + mc2.notHit = not mc2.CheckMatch( mc.ReadCoords() ); + if part1 == None and mc.notHit == False: + part1 = mc.ReadCoords(); + p1round = int(roundcounter); + #print("part 1 = ",part1, "\t after", roundcounter, "rounds"); + cartlist = [c for c in cartlist if c.notHit]; + +part2 = cartlist[0].ReadCoords(); +print("part 1 = ",part1, "\t after", p1round, "rounds"); +print("part 2 = ",part2, "\t after", roundcounter, "rounds"); -- cgit v1.2.3