Advertisement
musifter

AoC 2023 day 20, part 1 (Smalltalk)

Dec 20th, 2023 (edited)
1,760
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Smalltalk 2.88 KB | Source Code | 0 0
  1. #!/usr/local/bin/gst -q
  2.  
  3. Symbol extend [ value: arg [^arg perform: self] ]
  4.  
  5. "
  6. |  Classes for circuit components
  7. "
  8. Object subclass: Gate [  " Virtual parent class "
  9.     | out |
  10.     Gate class >> new  [ ^super new init   ]
  11.     init               [ out := OrderedCollection new. ^self ]
  12.  
  13.     addOuts: array     [ ^out := array ]
  14.     getOuts            [ ^out          ]
  15.     addIn:   name      [ ^nil ]
  16.  
  17.     pulse: level from: src  [ ^self NotImplemented ]
  18. ]
  19.  
  20. Gate subclass: FlipFlop  [
  21.     | state |
  22.     FlipFlop class >> new  [ ^(super new) init      ]
  23.     init                   [ state := false. ^self  ]
  24.  
  25.     setState: level [ ^state := level ]
  26.     printOn: stream [ stream nextPutAll: ('FlipFlop (%1)' % {state}) ]
  27.  
  28.     pulse: level from: src [
  29.         level ifFalse: [ ^state := state not ].
  30.         ^nil
  31.     ]
  32. ]
  33.  
  34. Gate subclass: NANDGate [
  35.     | in |
  36.     NANDGate class >> new  [ ^(super new) init           ]
  37.     init                   [ in := Dictionary new. ^self ]
  38.  
  39.     addIn: name     [ in at: name put: false ]
  40.     printOn: stream [ stream nextPutAll: ('NANDGate (%1)' % {in}) ]
  41.  
  42.     pulse: level from: src [
  43.         in at: src put: level.
  44.         ^(in values inject: true into: [:a :b | a & b]) not
  45.     ]
  46. ]
  47.  
  48.  
  49. "
  50. | Mainline
  51. "
  52. input := stdin contents lines collect: [:line | line subStrings: '-> ,' ].
  53.  
  54. " Read in circuit making forward links: "
  55. circuit := Dictionary new.
  56. input do: [ :line |
  57.    | gate name |
  58.     (line first = 'broadcaster') ifTrue: [
  59.         gate := circuit at: #broadcaster put: FlipFlop new.
  60.  
  61.     ] ifFalse: [
  62.         name := line first allButFirst asSymbol.
  63.         (line first first = $%) ifTrue: [
  64.             gate := circuit at: name put: FlipFlop new.
  65.         ] ifFalse: [
  66.             gate := circuit at: name put: NANDGate new.
  67.         ]
  68.     ].
  69.  
  70.     gate addOuts: (line allButFirst collect: #asSymbol).
  71. ].
  72.  
  73. " Add back links: "
  74. circuit keys do: [ :src |
  75.     (circuit at: src) getOuts do: [ :dest |
  76.        | gate |
  77.         gate := circuit at: dest ifAbsent: [circuit at: dest put: FlipFlop new].
  78.         gate ifNotNil: [ gate addIn: src ]
  79.     ]
  80. ].
  81.  
  82. " Run machine: "
  83. pulses := Bag new.
  84. 1000 timesRepeat: [
  85.     (circuit at: #broadcaster) setState: true.
  86.     queue := OrderedCollection with: {false. #button. #broadcaster}.
  87.  
  88.     [queue isEmpty] whileFalse: [
  89.         signal := queue removeFirst.
  90.         level := signal first.
  91.         src   := signal second.
  92.         curr  := signal third.
  93.  
  94.         "('%1 -%<high|low>2-> %3' % {src. level. curr}) displayNl."
  95.  
  96.         pulses add: level.
  97.         send := (circuit at: curr) pulse: level from: src.
  98.  
  99.         send ifNotNil: [
  100.             outs := (circuit at: curr) getOuts.
  101.             queue addAll: (outs collect: [:next | {send. curr. next}])
  102.         ]
  103.     ]
  104. ].
  105.  
  106. part1 := (pulses occurrencesOf: false) * (pulses occurrencesOf: true).
  107. ('Part 1: %1' % {part1}) displayNl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement