Advertisement
musifter

AoC 2024 day 17 (smalltalk)

Dec 17th, 2024
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Smalltalk 2.58 KB | Source Code | 0 0
  1. #!/usr/local/bin/gst -q
  2.  
  3. Symbol extend       [ value: arg [^arg perform: self] ]
  4.  
  5. Collection extend   [ min   [^self fold: [:a :b | a min: b]] ]
  6. Character extend    [ + num [^self value + num] ]
  7.  
  8. Integer extend [
  9.     >> shift  [^self bitShift: shift negated]
  10.     << shift  [^self bitShift: shift]
  11. ]
  12.  
  13. Object subclass: VirtualMachine [
  14.     | ip reg code buff |
  15.     opcodes := Dictionary from: { 0 -> #adv:.  1 -> #bxl:.  2 -> #bst:.  3 -> #jnz:.
  16.                                   4 -> #bxc:.  5 -> #out:.  6 -> #bdv:.  7 -> #cdv: }.
  17.  
  18.     VirtualMachine class >> new: codeArray [^super new init: codeArray]
  19.     init: codeArray  [code := codeArray.  ^self]
  20.  
  21.     " Code to run machine, with regA set, halting when haltOp is reached "
  22.     run: regA halt: haltOp [
  23.         | out inst |
  24.         ip   := 1.
  25.         reg  := Dictionary from: {#A -> regA. #B -> 0. #C -> 0}.
  26.         buff := OrderedCollection new.
  27.  
  28.         [(ip < code size) and: [haltOp ~= (inst := opcodes at: (code at: ip))]] whileTrue: [
  29.             self perform: inst with: (code at: ip+1).
  30.             ip := ip + 2.
  31.         ].
  32.         ^buff
  33.     ]
  34.  
  35.     " #nop is not a machine code, so this only halts when ip >= code size "
  36.     run: regA [^self run: regA halt: #nop]
  37.  
  38.     " combo operand referencing: "
  39.     combo: op [
  40.         ^(op >= 4) ifTrue:  [reg at: ($A + (op - 4)) asCharacter asSymbol]
  41.                    ifFalse: [op]
  42.     ]
  43.  
  44.     " Op codes: "
  45.     adv: op [reg at: #A  put: ((reg at: #A) >> (self combo: op))]
  46.     bdv: op [reg at: #B  put: ((reg at: #A) >> (self combo: op))]
  47.     cdv: op [reg at: #C  put: ((reg at: #A) >> (self combo: op))]
  48.  
  49.     bxl: op [reg at: #B  put: ((reg at: #B) bitXor: op)]
  50.     bxc: op [reg at: #B  put: ((reg at: #B) bitXor: (reg at: #C))]
  51.     bst: op [reg at: #B  put: ((self combo: op) \\ 8)]
  52.  
  53.     out: op [buff add: ((self combo: op) \\ 8)]
  54.  
  55.     jnz: op [((reg at: #A) ~= 0) ifTrue: [ip := op - 1]]
  56. ]
  57.  
  58. "
  59. | Mainline
  60. "
  61. para    := stdin contents tokenize: '\n\n'.
  62. numbers := para collect: [:p | ((p tokenize: '[^0-9]') reject: #isEmpty) collect: #asNumber].
  63.  
  64. regs := numbers first.
  65. code := numbers second.
  66.  
  67. vm := VirtualMachine new: code.
  68.  
  69. " Part 1: "
  70. part1 := vm run: (regs first).
  71. ('Part 1: %1' % {(part1 collect: #asString) join: ','}) displayNl.
  72.  
  73. " Part 2: "
  74. possible := Set with: 0.
  75. (code reverse) do: [:digit |
  76.     next := Set new.
  77.     possible do: [:prev |
  78.         base := prev << 3.
  79.         next addAll: ((base to: base+7) select: [:a | (vm run: a halt: #jnz) first == digit]).
  80.     ].
  81.  
  82.     possible := next.
  83. ].
  84.  
  85. ('Part 2: %1' % {possible min}) displayNl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement