Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/local/bin/gst -q
- Symbol extend [ value: arg [^arg perform: self] ]
- "
- | Classes for circuit components
- "
- Object subclass: Gate [ " Virtual parent class "
- | out |
- Gate class >> new [ ^super new init ]
- init [ out := OrderedCollection new. ^self ]
- addOuts: array [ ^out := array ]
- getOuts [ ^out ]
- addIn: name [ ^nil ]
- pulse: level from: src [ ^self NotImplemented ]
- ]
- Gate subclass: FlipFlop [
- | state |
- FlipFlop class >> new [ ^(super new) init ]
- init [ state := false. ^self ]
- setState: level [ ^state := level ]
- printOn: stream [ stream nextPutAll: ('FlipFlop (%1)' % {state}) ]
- pulse: level from: src [
- level ifFalse: [ ^state := state not ].
- ^nil
- ]
- ]
- Gate subclass: NANDGate [
- | in |
- NANDGate class >> new [ ^(super new) init ]
- init [ in := Dictionary new. ^self ]
- addIn: name [ in at: name put: false ]
- printOn: stream [ stream nextPutAll: ('NANDGate (%1)' % {in}) ]
- pulse: level from: src [
- in at: src put: level.
- ^(in values inject: true into: [:a :b | a & b]) not
- ]
- ]
- "
- | Mainline
- "
- input := stdin contents lines collect: [:line | line subStrings: '-> ,' ].
- " Read in circuit making forward links: "
- circuit := Dictionary new.
- input do: [ :line |
- | gate name |
- (line first = 'broadcaster') ifTrue: [
- gate := circuit at: #broadcaster put: FlipFlop new.
- ] ifFalse: [
- name := line first allButFirst asSymbol.
- (line first first = $%) ifTrue: [
- gate := circuit at: name put: FlipFlop new.
- ] ifFalse: [
- gate := circuit at: name put: NANDGate new.
- ]
- ].
- gate addOuts: (line allButFirst collect: #asSymbol).
- ].
- " Add back links: "
- circuit keys do: [ :src |
- (circuit at: src) getOuts do: [ :dest |
- | gate |
- gate := circuit at: dest ifAbsent: [circuit at: dest put: FlipFlop new].
- gate ifNotNil: [ gate addIn: src ]
- ]
- ].
- " Run machine: "
- pulses := Bag new.
- 1000 timesRepeat: [
- (circuit at: #broadcaster) setState: true.
- queue := OrderedCollection with: {false. #button. #broadcaster}.
- [queue isEmpty] whileFalse: [
- signal := queue removeFirst.
- level := signal first.
- src := signal second.
- curr := signal third.
- "('%1 -%<high|low>2-> %3' % {src. level. curr}) displayNl."
- pulses add: level.
- send := (circuit at: curr) pulse: level from: src.
- send ifNotNil: [
- outs := (circuit at: curr) getOuts.
- queue addAll: (outs collect: [:next | {send. curr. next}])
- ]
- ]
- ].
- part1 := (pulses occurrencesOf: false) * (pulses occurrencesOf: true).
- ('Part 1: %1' % {part1}) displayNl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement