Advertisement
musifter

AoC day 8, Smalltalk

Dec 8th, 2020
2,057
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/local/bin/gst -q
  2.  
  3. Array extend [
  4.     atInc: idx [
  5.         ^self at: idx put: ((self at: idx) + 1)
  6.     ]
  7. ]
  8.  
  9. Object subclass: VirtualMachine [
  10.     | acc ip opcodes code toggle |
  11.  
  12.     VirtualMachine class >> new [
  13.         ^(super new) init
  14.     ]
  15.  
  16.     init [
  17.         opcodes := Dictionary new.
  18.         opcodes at: #acc put: [ :a | acc := acc + a. ip := ip + 1 ];
  19.                 at: #jmp put: [ :a | ip := ip + a ];
  20.                 at: #nop put: [ :a | ip := ip + 1 ].
  21.  
  22.         toggle := Dictionary new.
  23.         toggle at: #nop put: #jmp;
  24.                at: #jmp put: #nop;
  25.                at: #acc put: #acc.
  26.  
  27.         code := OrderedCollection new.
  28.         ^self
  29.     ]
  30.  
  31.     load: op arg: arg [
  32.         code addLast: (op -> arg)
  33.     ]
  34.  
  35.     halted [
  36.         ^(ip = (code size + 1))
  37.     ]
  38.  
  39.     run [
  40.         | inst ran |
  41.  
  42.         acc := 0.
  43.         ip  := 1.
  44.         ran := Array new: (code size + 1) withAll: 0.
  45.  
  46.         [ self halted ] whileFalse: [
  47.             ((ran atInc: ip) = 2) ifTrue: [     " looped "
  48.                 ^acc
  49.             ].
  50.  
  51.             inst := code at: ip.
  52.             (opcodes at: inst key) value: inst value.
  53.         ].
  54.  
  55.         ^acc
  56.     ]
  57.  
  58.     try: inst [
  59.         (code at: inst) key: (toggle at: (code at: inst) key).
  60.         self run.
  61.         (code at: inst) key: (toggle at: (code at: inst) key).
  62.  
  63.         ^self halted.
  64.     ]
  65.  
  66.     getAcc      [ ^acc ]
  67.     codeSize    [ ^code size ]
  68. ]
  69.  
  70. "
  71. |  Mainline
  72. "
  73. vm := VirtualMachine new.
  74.  
  75. stdin linesDo: [ :line |
  76.     split := line subStrings: ' +'.
  77.     vm load: (split first asSymbol) arg: (split second asNumber).
  78. ].
  79.  
  80. stdout nextPutAll: ('Part 1: ', vm run asString); nl.
  81.  
  82. " XXX: Check and don't bother with trying to toggle #acc "
  83. (1 to: (vm codeSize)) detect: [ :inst | vm try: inst ].
  84. stdout nextPutAll: ('Part 2: ', vm getAcc asString); nl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement