Skip to content

Commit 1c8210a

Browse files
authored
Merge pull request #99 from MaritimeOptima/day1819/preng
Day 18 and 19 solutions in python by preng. Very low-level code, avoiding higher level python temptations as a re-learning excercise
2 parents 68c335e + 9fe32de commit 1c8210a

File tree

8 files changed

+1184
-8
lines changed

8 files changed

+1184
-8
lines changed

days/day-18/io/preng.input

Lines changed: 373 additions & 0 deletions
Large diffs are not rendered by default.

days/day-18/io/preng.output

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
6640667297513
2+
451589894841552
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
from functools import reduce
2+
from sys import stdin
3+
import math
4+
import re
5+
6+
# Long winded code that does not use high-level system libraries
7+
8+
def get_stdin():
9+
return [line.rstrip() for line in stdin]
10+
11+
def parentokens(tokens):
12+
closecnt = 0
13+
for i in range(len(tokens)):
14+
t = tokens[i]
15+
if t == "(":
16+
closecnt -= 1
17+
elif t == ")":
18+
closecnt += 1
19+
if closecnt == 1:
20+
return tokens[0:i], tokens[i+1:]
21+
print("unbalanced", tokens)
22+
23+
def tokenize(expr):
24+
tokens = []
25+
pos = 0
26+
while pos < len(expr):
27+
c = expr[pos]
28+
if c == " ":
29+
pos += 1
30+
elif c == "(":
31+
tokens.append(c)
32+
pos += 1
33+
elif c == ")":
34+
tokens.append(c)
35+
pos += 1
36+
elif c == "+":
37+
tokens.append(sum)
38+
pos += 1
39+
elif c == "*":
40+
tokens.append(math.prod)
41+
pos += 1
42+
else:
43+
token = re.findall(r'-{0,1}\d+', expr[pos:])[0]
44+
tokens.append(int(token))
45+
pos += len(token)
46+
return tokens
47+
48+
def presedence(a, b):
49+
return a == sum and b == math.prod
50+
51+
def parsenext(tokens, builder):
52+
if len(tokens) == 1:
53+
return tokens[0], []
54+
t = tokens.pop(0)
55+
if t == "(":
56+
inside, tail = parentokens(tokens)
57+
return parsetree(inside, builder), tail
58+
else:
59+
return parsetree([t], builder), tokens
60+
61+
def parsetree(tokens, builder, left = None):
62+
op = None
63+
right = None
64+
if len(tokens) == 1:
65+
return Expr(None, tokens[0], None)
66+
if left is None:
67+
left, tokens = parsenext(tokens, builder)
68+
if len(tokens) == 0:
69+
return Expr(None, left, None)
70+
op = tokens.pop(0)
71+
right, tokens = parsenext(tokens, builder)
72+
if len(tokens) == 0:
73+
return Expr(op, left, right)
74+
return builder(op, left, right, tokens)
75+
76+
def part1builder(op, left, right, tail):
77+
return parsetree(tail, part1builder, Expr(op, Expr(None,left,None), Expr(None,right,None)))
78+
79+
def part2builder(op, left, right, tail):
80+
if presedence(tail[0], op):
81+
op2 = tail[0]
82+
nexttoken, tail = parsenext(tail[1:], part2builder)
83+
return Expr(op, left, parsetree(tail, part2builder, Expr(op2, right, nexttoken)))
84+
else:
85+
return parsetree(tail, part2builder, Expr(op, Expr(None,left,None), Expr(None,right,None)))
86+
87+
class Expr:
88+
def __init__(self, op, left, right):
89+
self.op = op
90+
self.left = left
91+
self.right = right
92+
93+
def isplus(self):
94+
return self.op is not None and self.op == sum
95+
96+
def ismult(self):
97+
return self.op is not None and self.op == math.prod
98+
99+
def calc(self):
100+
if self.isplus():
101+
return self.value(self.left) + self.value(self.right)
102+
elif self.ismult():
103+
return self.value(self.left) * self.value(self.right)
104+
else:
105+
return self.value(self.left)
106+
107+
def value(self, node):
108+
if isinstance(node, Expr):
109+
return node.calc()
110+
else:
111+
return node
112+
113+
def __str__(self):
114+
if self.op is None:
115+
return "%s" % (self.left)
116+
if self.isplus():
117+
return "(%s + %s) " % (self.left, self.right)
118+
else:
119+
return "(%s * %s) " % (self.left, self.right)
120+
121+
def __repr__(self):
122+
return self.__str__()
123+
124+
125+
# PART 1
126+
lines = get_stdin()
127+
print(sum([parsetree(tokenize(l), part1builder).calc() for l in lines]))
128+
129+
# PART 2
130+
print(sum([parsetree(tokenize(l), part2builder).calc() for l in lines]))

days/day-18/test.sh

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@ set -euo pipefail
33

44
D=$(dirname $(realpath $0))
55

6-
echo "--- Day 18: --- ????? ---"
6+
echo "--- Day 18: --- Operation Order ---"
77
#$D/../../lang/go.sh "$D/solutions/*.go" "$D/io/*"
88
#$D/../../lang/sml.sh "$D/solutions/*.sml" "$D/io/*"
9-
#$D/../../lang/python.sh "$D/solutions/*.py" "$D/io/*"
9+
$D/../../lang/python.sh "$D/solutions/*.py" "$D/io/*"
1010
#$D/../../lang/deno.sh "$D/solutions/*.ts" "$D/io/*"
11-
12-
exit 1337;

0 commit comments

Comments
 (0)