My solutions for Advent of Code.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
adventofcode/2020/18.py

298 lines
6.3 KiB

4 years ago
#!/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]
4 years ago
# def addParsToSub(line:str):
# # this function split the strings addition thing
# # no parenthesis here
4 years ago
4 years ago
# addlines = line.split("*") # each element is an addition
# #newline = "("
# newline = ""
4 years ago
4 years ago
# 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})"
4 years ago
4 years ago
# #newline += ")"
4 years ago
4 years ago
# return newline
4 years ago
4 years ago
# def getLowestPar(par:dict):
# bestdiff = None
# bestkey = None
4 years ago
4 years ago
# for key, val in par.items():
# diff = val - key
4 years ago
4 years ago
# if( bestdiff == None ):
# bestdiff = diff
# bestkey = key
# continue
4 years ago
4 years ago
# if( diff > bestdiff ):
# bestdiff = diff
# bestkey = key
# continue
4 years ago
4 years ago
# return bestkey
4 years ago
4 years ago
# def addPars(line:str, usedPar=[]):
# line = line.replace(" ", "")
# newline = line
# count = 0
4 years ago
4 years ago
# # Get pars etc
# pars = findParens(line)
# chars = strToList(line)
4 years ago
4 years ago
# print(pars)
4 years ago
4 years ago
# # Get pars with lowest depth
# start = getLowestPar(pars)
# end = pars[start]+1
4 years ago
4 years ago
# # Enclose addition in pars
# subline = lstToStr(chars[start:end])
# newsubline = addParsToSub(subline)
4 years ago
4 years ago
# 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)
4 years ago
4 years ago
# def addParsRec(line:str, i=0, it=None):
# it = it or line.count("(")
4 years ago
4 years ago
# if( i < it ):
# return addParsRec( addParsToSub(line), i+1, it )
# else:
# return line
4 years ago
4 years ago
# def addPars(chars:list):
# curDepth = 0
# addDepth = 0
4 years ago
4 years ago
# isSearching = False
# offset = 0
# for i, char in enumerate(chars):
# if( char == "(" ):
# curDepth += 1
4 years ago
# elif( char == ")" ):
4 years ago
# curDepth -= 1
4 years ago
4 years ago
# if( char == "+" ):
# before = chars[i-1+offset]
# if(before == ")" or before == "("):
# chars.insert(i+offset, 0)
# offset += 1
4 years ago
4 years ago
# curDepth2 = curDepth
# for di, char2 in enumerate(chars[i+1:]):
4 years ago
4 years ago
# if( char2 == "(" ):
# curDepth2 += 1
# elif( char2 == ")" ):
# curDepth2 -= 1
4 years ago
4 years ago
# print(f"{i=} : {di+1=} {char=} {char2=} {curDepth=}/{curDepth2=}")
4 years ago
4 years ago
# if( char2 == "*" and curDepth == curDepth2 ):
# chars.insert(i+offset+di, ")")
# offset += 1
4 years ago
4 years ago
# # if( char == "+" and not isSearching ):
# # chars.insert(i-1+offset, "(")
# # addDepth = curDepth
# # isSearching = True
# # offset += 1
4 years ago
4 years ago
# # elif( char == "*" and curDepth == addDepth ):
# # chars.insert(i+offset, ")")
4 years ago
4 years ago
# return chars
4 years ago
4 years ago
# addPars( strToList("2*3+(4*5)") )
def parseMath2(line:str):
line = line.replace(" ", "")
4 years ago
count = 0
4 years ago
# 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)
4 years ago
4 years ago
print("##########3")
# remove bad chars
chars = list( filter(lambda c: c != "", chars) )
print(chars)
# calculate the rest
count += calcMath(chars)
return count
4 years ago
4 years ago
# problem = mathproblems[0]
# res = parseMath2(problem)
# print("\n--##########################--")
# print( problem, "=", res )
4 years ago
# mathsum = 0
# for maththing in mathproblems:
# mathsum += parseMath(maththing)
# print(mathsum)