Advertisement
musifter

AoC day 18, Smalltalk

Dec 18th, 2020
2,002
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/local/bin/gst -q
  2.  
  3. Character extend [
  4.     asDigit [
  5.         ^self value - $0 value
  6.     ]
  7. ]
  8.  
  9. " Class to handle parsing for part 2 "
  10. Object subclass: Parser [
  11.     | stack ops |
  12.  
  13.     Parser class >> new [
  14.         ^(super new) init
  15.     ]
  16.  
  17.     init [
  18.         stack := OrderedCollection new.
  19.         ops   := OrderedCollection new.
  20.         ^self
  21.     ]
  22.  
  23.     doOp: op [
  24.         (op = $+) ifTrue: [
  25.             stack addLast: (stack removeLast + stack removeLast)
  26.         ] ifFalse: [
  27.             stack addLast: (stack removeLast * stack removeLast)
  28.         ]
  29.     ]
  30.  
  31.     evaluate: str [
  32.         | pop done |
  33.  
  34.         " Assuming only single digit numbers "
  35.         (str reject: [ :c | (c = Character space) ]) reverseDo: [ :chr |
  36.             (chr isDigit) ifTrue: [
  37.                 stack addLast: (chr asDigit).
  38.             ] ifFalse: [
  39.                 (chr = $() ifTrue: [
  40.                     " Process operators until matching paren "
  41.                     [ (pop := ops removeLast) ~= $) ] whileTrue: [
  42.                         self doOp: pop.
  43.                     ].
  44.                 ] ifFalse: [
  45.                     (chr = $*) ifTrue: [
  46.                         " Handle * having lower precedence than + "
  47.                         done := false.
  48.                         [ (done not) and: [ops size > 0] ] whileTrue: [
  49.                             " Process higher +s on top of stack "
  50.                             pop := ops removeLast.
  51.                             (pop = $+) ifTrue: [
  52.                                 self doOp: pop.
  53.                             ] ifFalse: [
  54.                                 ops addLast: pop.   " Restore last item on stack "
  55.                                 done := true.
  56.                             ]
  57.                         ]
  58.                     ].
  59.  
  60.                     " Add operation to the ops stack "
  61.                     ops addLast: chr.
  62.                 ]
  63.             ]
  64.         ].
  65.  
  66.         " Process remaining operations on ops stack "
  67.         [ (ops size > 0) ] whileTrue: [
  68.             self doOp: ops removeLast.
  69.         ].
  70.  
  71.         ^stack removeLast.
  72.     ]
  73. ].
  74.  
  75.  
  76. "
  77. |  Mainline
  78. "
  79. part1 := 0.
  80. part2 := 0.
  81.  
  82. stdin linesDo: [ :line |
  83.     part1 := part1 + (Behavior evaluate: line).   " Smalltalk does part 1 already! "
  84.     part2 := part2 + (Parser new evaluate: line).
  85. ].
  86.  
  87. stdout nextPutAll: ('Part 1: ', part1 asString); nl.
  88. stdout nextPutAll: ('Part 2: ', part2 asString); nl.
  89.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement