#!/usr/bin/env python from aoc import get_input # AoC import re # regex mathproblems = get_input(18).splitlines() operators = ["+", "*"] def strToList(string): list1=[] list1[:0]=string return list1 def findParens(s): toret = dict() pstack = [] for i, c in enumerate(s): if( c == "(" ): pstack.append(i) elif( c == ")" ): if( len(pstack) == 0 ): raise IndexError("No matching closing parens at: " + str(i)) toret[pstack.pop()] = i if(len(pstack) > 0): raise IndexError("No matching opening parens at: " + str(pstack.pop())) return toret def getFirstNum(chars:list): first = None for i in range(len(chars)): char = chars[i] print(f"check {char=}", end=" ") if(not char in operators and char != "(" and char != ")" and char != ""): first = int(char) print("is first") break else: print("") return first def calcMath(chars:list): count = 0 first = getFirstNum(chars) count += first for i in range(len(chars)): char = chars[i] after = None if(char == "+"): after = chars[i+1] count += int(after) elif(char == "*"): after = chars[i+1] count *= int(after) print(f"{first=} {char=} {i=} {after=} {count=}") return count def parseMath(line): line = line.replace(" ", "") count = 0 # calculate all pars and replace them pars = findParens(line) chars = strToList(line) print(chars) for start, end in pars.items(): calc = calcMath(chars[start:end+1]) for j in range(start, end+1): chars[j] = "" chars[start] = str(calc) print("##########3") # remove bad chars chars = list( filter(lambda c: c != "", chars) ) print(chars) # calculate the rest count += calcMath(chars) return count def printMath(mathlist): for m in mathlist: print(m, end="") print("") def lstToStr(lst): out = "" for char in lst: out += str(char) return out def copyList(lst): return [elem for elem in lst] # def addParsToSub(line:str): # # this function split the strings addition thing # # no parenthesis here # addlines = line.split("*") # each element is an addition # #newline = "(" # newline = "" # for i in range(len(addlines)): # l = addlines[i] # if( i < 1 ): # newline += f"({l})*" # elif( i >= 1 and i < len(addlines)-1 ): # newline += f"({l})*" # elif( i == len(addlines)-1 ): # newline += f"({l})" # #newline += ")" # return newline # def getLowestPar(par:dict): # bestdiff = None # bestkey = None # for key, val in par.items(): # diff = val - key # if( bestdiff == None ): # bestdiff = diff # bestkey = key # continue # if( diff > bestdiff ): # bestdiff = diff # bestkey = key # continue # return bestkey # def addPars(line:str, usedPar=[]): # line = line.replace(" ", "") # newline = line # count = 0 # # Get pars etc # pars = findParens(line) # chars = strToList(line) # print(pars) # # Get pars with lowest depth # start = getLowestPar(pars) # end = pars[start]+1 # # Enclose addition in pars # subline = lstToStr(chars[start:end]) # newsubline = addParsToSub(subline) # newline = newline.replace(subline, newsubline) # # for start, end in pars.items(): # # if( not start in usedPar ): # # x, y = start, end+1 # # subline = lstToStr(chars[x:y]) # # newsubline = addParsToSub(subline) # # newline.replace(subline, newsubline) # # print(f"{newsubline=}") # print("FINAL", newline) # print(subline, newsubline) # print(addParsToSub(newline)) # def addParsRec(line:str, usedPar=[]): # line = line.replace(" ", "") # newline = line # pars = findParens(newline) # def addParsRec(line:str, i=0, it=None): # it = it or line.count("(") # if( i < it ): # return addParsRec( addParsToSub(line), i+1, it ) # else: # return line # def addPars(chars:list): # curDepth = 0 # addDepth = 0 # isSearching = False # offset = 0 # for i, char in enumerate(chars): # if( char == "(" ): # curDepth += 1 # elif( char == ")" ): # curDepth -= 1 # if( char == "+" ): # before = chars[i-1+offset] # if(before == ")" or before == "("): # chars.insert(i+offset, 0) # offset += 1 # curDepth2 = curDepth # for di, char2 in enumerate(chars[i+1:]): # if( char2 == "(" ): # curDepth2 += 1 # elif( char2 == ")" ): # curDepth2 -= 1 # print(f"{i=} : {di+1=} {char=} {char2=} {curDepth=}/{curDepth2=}") # if( char2 == "*" and curDepth == curDepth2 ): # chars.insert(i+offset+di, ")") # offset += 1 # # if( char == "+" and not isSearching ): # # chars.insert(i-1+offset, "(") # # addDepth = curDepth # # isSearching = True # # offset += 1 # # elif( char == "*" and curDepth == addDepth ): # # chars.insert(i+offset, ")") # return chars # addPars( strToList("2*3+(4*5)") ) def parseMath2(line:str): line = line.replace(" ", "") count = 0 # calculate all pars and replace them pars = findParens(line) chars = strToList(line) print(chars) for start, end in pars.items(): calc = calcMath(chars[start:end+1]) for j in range(start, end+1): chars[j] = "" chars[start] = str(calc) print("##########3") # remove bad chars chars = list( filter(lambda c: c != "", chars) ) print(chars) # calculate the rest count += calcMath(chars) return count # problem = mathproblems[0] # res = parseMath2(problem) # print("\n--##########################--") # print( problem, "=", res ) # mathsum = 0 # for maththing in mathproblems: # mathsum += parseMath(maththing) # print(mathsum)