Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/local/bin/gst -q
- Character extend [
- asDigit [
- ^self value - $0 value
- ]
- ]
- " Class to handle parsing for part 2 "
- Object subclass: Parser [
- | stack ops |
- Parser class >> new [
- ^(super new) init
- ]
- init [
- stack := OrderedCollection new.
- ops := OrderedCollection new.
- ^self
- ]
- doOp: op [
- (op = $+) ifTrue: [
- stack addLast: (stack removeLast + stack removeLast)
- ] ifFalse: [
- stack addLast: (stack removeLast * stack removeLast)
- ]
- ]
- evaluate: str [
- | pop done |
- " Assuming only single digit numbers "
- (str reject: [ :c | (c = Character space) ]) reverseDo: [ :chr |
- (chr isDigit) ifTrue: [
- stack addLast: (chr asDigit).
- ] ifFalse: [
- (chr = $() ifTrue: [
- " Process operators until matching paren "
- [ (pop := ops removeLast) ~= $) ] whileTrue: [
- self doOp: pop.
- ].
- ] ifFalse: [
- (chr = $*) ifTrue: [
- " Handle * having lower precedence than + "
- done := false.
- [ (done not) and: [ops size > 0] ] whileTrue: [
- " Process higher +s on top of stack "
- pop := ops removeLast.
- (pop = $+) ifTrue: [
- self doOp: pop.
- ] ifFalse: [
- ops addLast: pop. " Restore last item on stack "
- done := true.
- ]
- ]
- ].
- " Add operation to the ops stack "
- ops addLast: chr.
- ]
- ]
- ].
- " Process remaining operations on ops stack "
- [ (ops size > 0) ] whileTrue: [
- self doOp: ops removeLast.
- ].
- ^stack removeLast.
- ]
- ].
- "
- | Mainline
- "
- part1 := 0.
- part2 := 0.
- stdin linesDo: [ :line |
- part1 := part1 + (Behavior evaluate: line). " Smalltalk does part 1 already! "
- part2 := part2 + (Parser new evaluate: line).
- ].
- stdout nextPutAll: ('Part 1: ', part1 asString); nl.
- stdout nextPutAll: ('Part 2: ', part2 asString); nl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement