From f6ff66ea2da1f30303f17a2dac341411fb325881 Mon Sep 17 00:00:00 2001 From: blenovo Date: Sat, 16 Aug 2025 00:38:26 +0200 Subject: final puzzle and little cleanup for 2018 --- 2018/aoc2018-d15-1.py | 324 -------------------------------------------------- 1 file changed, 324 deletions(-) delete mode 100644 2018/aoc2018-d15-1.py (limited to '2018/aoc2018-d15-1.py') diff --git a/2018/aoc2018-d15-1.py b/2018/aoc2018-d15-1.py deleted file mode 100644 index 6a2665d..0000000 --- a/2018/aoc2018-d15-1.py +++ /dev/null @@ -1,324 +0,0 @@ -#advent of code 2018 -#day 13 -#part 1 -import heapq - -f = open("input.txt",'r'); -Testing = False; -Testing = True; -if Testing: - f.close(); - f = open("testinput.txt",'r'); -Testing2 = False; -Testing2 = True; -if Testing2: - f.close(); - f = open("testinput2.txt",'r'); -Testing3 = False; -#Testing3 = True; -if Testing3: - f.close(); - f = open("testinput3.txt",'r'); -Testing4 = False; -#Testing4 = True; -if Testing4: - f.close(); - f = open("testinput4.txt",'r'); -Testing5 = False; -Testing5 = True; -if Testing5: - f.close(); - f = open("testinput5.txt",'r'); -Testing6 = False; -Testing6 = True; -if Testing6: - f.close(); - f = open("testinput6.txt",'r'); -Testing7 = False; -Testing7 = True; -if Testing7: - f.close(); - f = open("testinput7.txt",'r'); -NotTesting = False; -NotTesting = True; -if NotTesting: - f.close(); - f = open("input.txt",'r'); - #f = open("shit.txt",'r'); - -class thing: - def __init__(self, Pos, sign, currentID): - self.sign = sign; - self.PosX = Pos[1]; - self.PosY = Pos[0]; - self.IsAlive = False; - if (sign == "."): - self.IsPassable = True; - else: - self.IsPassable = False; - def __str__(self): - return self.sign; - - def SquaresInRange(self,bg): - squares = []; - p = (self.PosY-1,self.PosX); - if(bg[p].IsPassable): squares.append(p); - p = (self.PosY,self.PosX-1); - if(bg[p].IsPassable): squares.append(p); - p = (self.PosY,self.PosX+1); - if(bg[p].IsPassable): squares.append(p); - p = (self.PosY+1,self.PosX); - if(bg[p].IsPassable): squares.append(p); - return squares; - -class creature(thing): - def __init__(self, Pos, sign, currentID): - thing.__init__(self, Pos, sign, currentID); - self.ID = currentID; - self.health = 200; - self.damage = 3; - self.side = sign; - self.IsAlive = True; - if (self.side == "G"): - self.enemy = "E"; - if (self.side == "E"): - self.enemy = "G"; - - def death(self,bg): - self.IsPassable = True; - self.IsAlive = False; - self.health = 0; - unitcords[(self.PosY,self.PosX)] = None; - bg[(self.PosY,self.PosX)].IsPassable = True; - - - def movement(self,bg,PosNow,PosNew): - self.PosX = PosNew[1]; - self.PosY = PosNew[0]; - bg[PosNow].IsPassable = True; - bg[PosNew].IsPassable = False; - unitcords[PosNew] = self.ID; - unitcords[PosNow] = None; - - - def ScanProximity(self): - targets = []; - p = (self.PosY-1,self.PosX); - if p in unitcords and unitcords[p] in units and units[unitcords[p]].side == self.enemy and units[unitcords[p]].health >0: - targets.append(p); - p = (self.PosY,self.PosX-1); - if p in unitcords and unitcords[p] in units and units[unitcords[p]].side == self.enemy and units[unitcords[p]].health >0: - targets.append(p); - p = (self.PosY,self.PosX+1); - if p in unitcords and unitcords[p] in units and units[unitcords[p]].side == self.enemy and units[unitcords[p]].health >0: - targets.append(p); - p = (self.PosY+1,self.PosX); - if p in unitcords and unitcords[p] in units and units[unitcords[p]].side == self.enemy and units[unitcords[p]].health >0: - targets.append(p); - if targets: - targets.sort(key = lambda x: (units[unitcords[x]].health,units[unitcords[x]].PosY,units[unitcords[x]].PosX)); - return targets; - - - def IdentifyTargets_ALL(self,creaturelist,bg): - points = []; - for c in creaturelist: - if units[c].side == self.side or not units[c].IsAlive: continue; - points.extend(units[c].SquaresInRange(bg)); - return points; - - - def ShortestPaths(self, pointlist, bg): - paths = []; - pathlen = len(bg); - queue = []; - heapq.heappush(queue, (0,[(self.PosY,self.PosX)])); - visited = []; - while queue: - d, path = heapq.heappop(queue); - if d > pathlen: - return paths; - if path[-1] in pointlist: - if pathlen > len(path): - paths.append(path); - pathlen = len(path); - continue; - if path[-1] in visited: - continue; - else: - visited.append(path[-1]); - for a in bg[path[-1]].SquaresInRange(bg): - if a in visited: continue; - heapq.heappush(queue, (d+1, path + [a])); - return paths; - - def ChosenPath(self, pointlist, bg): - paths = self.ShortestPaths(pointlist, bg); - if len(paths) != 0: - pathends = min([p[-1] for p in paths]); - paths2= self.ShortestPaths([pathends], bg); - if len(paths2) != 0: - moves = []; - for p in paths: - moves.append(p[1]); - moves = sorted(moves, key = lambda m: (m[0],m[1])); - m = moves[0]; - self.movement(bg,(self.PosY,self.PosX),m); - - -def PathSearch(bg, Coordinates, Destination): - pass; - -def strike(attacker, target,bg): - target.health -= attacker.damage; - if (target.health <= 0): - target.death(bg); - -def armystrength(army): - strength = 0; - for soldier in army: - strength += units[unitcords[soldier]].health; - return strength; - -def armyscores(): - ElfScore = 0; - GobScore = 0; - for u in units: - if units[u].side == "G": GobScore += units[u].health; - if units[u].side == "E": ElfScore += units[u].health; - - return max(ElfScore,GobScore); - - - -def FindEnemies(team): - Enemies = 0; - for u in units: - if units[u].IsAlive and units[u].side != team: Enemies += 1; - - return Enemies; -############################################################################### - - -bgsizex = 0; -bgsizey = 0; -battleground = {}; -units = {}; -unitcords = {}; - -identifier = 11; - -for y, line in enumerate(f): - bgsizey += 1; - bgsizex = 0; - for x, c in enumerate(line): - bgsizex += 1; - if c == "G" or c == "E": - battleground[(y,x)] = thing((y,x),".",identifier); - units[identifier] = creature((y,x),c, identifier); - units[identifier].movement(battleground, (y,x), (y,x)); - identifier += 1; - else: - battleground[(y,x)] = thing((y,x),c,identifier); -''' -for y in range(bgsizey): - for x in range(bgsizex): - if (y,x) in unitcords: - print("X",end=""); - else: - print(battleground[(y,x)],end=""); #''' - - -unitcords = {}; -for u in units: - unitcords[(units[u].PosY,units[u].PosX)] = units[u].ID; - - -elfs = sum([1 for x in units if units[x].IsAlive and units[x].side=="E"]); -goblins = sum([1 for x in units if units[x].IsAlive and units[x].side=="G"]); - -ElapsedRounds = 0; - - -while goblins and elfs: - fighters = []; - for u in units: - if units[u].IsAlive: - fighters.append(units[u].ID); - - fighters = sorted(fighters, key = lambda u: (units[u].PosY,units[u].PosX)); - - for fighter in fighters: - if not units[fighter].IsAlive: continue; - if FindEnemies(units[fighter].side) <= 0: - print("loop broken FIGHTERS"); - break; - tars = units[fighter].ScanProximity(); - if tars: - tar = tars[0]; - strike(units[fighter],units[unitcords[tar]],battleground); - else: - CurrentPos = (units[fighter].PosY,units[fighter].PosX); - IdenTars = units[fighter].IdentifyTargets_ALL(fighters,battleground); - units[fighter].ChosenPath(IdenTars,battleground); - if CurrentPos == (units[fighter].PosY,units[fighter].PosX): - continue; - else: - tars = units[fighter].ScanProximity(); - if tars: - tar = tars[0]; - strike(units[fighter],units[unitcords[tar]],battleground); - - unitcords = {}; - for u in units: - unitcords[(units[u].PosY,units[u].PosX)] = units[u].ID; - - print("ROUND ", ElapsedRounds); - unitcords = {}; - for u in units: - unitcords[(units[u].PosY,units[u].PosX)] = units[u].ID; - - ElapsedRounds += 1; - elfs = sum([1 for x in units if units[x].IsAlive and units[x].side=="E"]); - goblins = sum([1 for x in units if units[x].IsAlive and units[x].side=="G"]); - ''' - for y in range(bgsizey): - for x in range(bgsizex): - if (y,x) in unitcords and unitcords[(y,x)] in units and units[unitcords[(y,x)]].IsAlive: - print(units[unitcords[(y,x)]].side,end=""); - else: - print(battleground[(y,x)],end=""); - print(); - ''' - - ''' - for y in range(bgsizey): - for x in range(bgsizex): - print((y,x), " - ", battleground[(y,x)].IsPassable); - print(); - print(); - ''' - - - -unitcords = {}; -for u in units: - unitcords[(units[u].PosY,units[u].PosX)] = units[u].ID; - print(u, f'({units[u].side} / ({units[u].PosY},{units[u].PosX})) ', units[u].health); - - -for y in range(bgsizey): - for x in range(bgsizex): - if (y,x) in unitcords and unitcords[(y,x)] in units and units[unitcords[(y,x)]].IsAlive: - print(units[unitcords[(y,x)]].side,end=""); - else: - print(battleground[(y,x)],end=""); -print(); - - -print("part 1 = ", ElapsedRounds, "*",armyscores(), "=",ElapsedRounds*armyscores()); -print("lil cheat = ", (ElapsedRounds-1), "*",armyscores(), "=",(ElapsedRounds-1)*armyscores()); -#I cant get the correct answer without implementing any short circuit logics -#thats why I print 2 outputs, for number of rounds and (number of rounds -1) - -#190777 p1 correct -- cgit v1.2.3