Skip to content

Instantly share code, notes, and snippets.

@fidergo-stephane-gourichon
Last active December 19, 2020 20:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fidergo-stephane-gourichon/5f39f2f00830d4923533f72d6201cf7d to your computer and use it in GitHub Desktop.
Save fidergo-stephane-gourichon/5f39f2f00830d4923533f72d6201cf7d to your computer and use it in GitHub Desktop.
Advent of code, step 1: an unusual math context where operators have no priority!
#!/usr/bin/env python3
import itertools
from enum import Enum, auto
import re
import logging
import sys
import numbers
logging.basicConfig(level=logging.INFO, stream=sys.stderr)
logger = logging.getLogger('dec16')
logger.info("Log started")
def logexpr(*somestring, l=logging.DEBUG):
if isinstance(l, str):
l = getattr(logging, l)
for arg in somestring:
logger.log(l, f"{arg}\t=\t{repr(eval(arg))}")
def logexpr_info(somestring):
logexpr(somestring, l=logging.INFO)
#logexpr=(lambda *w: [logger.debug("{}\t=\t{}".format(x,repr(eval(x)))) for x in w ])
fileName = 'input'
if (len(sys.argv) > 1):
fileName = sys.argv[1]
logger.debug("Reading from file {fileName!r}")
def collect(stack):
if len(stack) < 3:
return
if not callable(stack[-2]):
return
if not isinstance(stack[-1], numbers.Number):
return
if not isinstance(stack[-3], numbers.Number):
return
v2 = stack.pop()
op = stack.pop()
v1 = stack.pop()
nv = op(v1, v2)
stack.append(nv)
def rempar(stack):
if len(stack) < 2:
return
if stack[-2] != '(':
logger.error(f"Cannot close paren: {stack=}")
raise Exception("Cannot close paren.")
del stack[-2]
def parse(l):
logger.debug(f'Parsing {l=}')
stack = []
while len(l) > 0:
logger.debug(f'{stack=} {l=}')
c = l[0]
if c == ' ':
pass
elif c >= '0' and c <= '9':
v = int(c)
stack.append(v)
elif c == '+':
collect(stack)
stack.append(lambda x, y: x + y)
elif c == '-':
collect(stack)
stack.append(lambda x, y: x - y)
elif c == '*':
collect(stack)
stack.append(lambda x, y: x * y)
elif c == '(':
stack.append(c)
elif c == ')':
collect(stack)
rempar(stack)
l = l[1:]
collect(stack)
if len(stack) != 1:
logger.error(f"Stack not of size 1: {stack=}")
raise Exception("Not a valid expression.")
return stack.pop()
value = 0
with open(fileName) as f:
for l in f:
l = l.rstrip()
number = parse(l)
logger.debug(f'{l=} {number=}')
value += number
print(f"{value=}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment