@@ -70,108 +70,113 @@ func readInput() -> Modules {
70
70
return result
71
71
}
72
72
73
- // extension Module {
74
- // typealias State = [String: Bool]
75
- // typealias Pulse = (value: Bool, from: String, to: String)
76
- // }
77
-
78
- // typealias PropogateResult = (state: Module.State, pulses: [Module.Pulse])
79
-
80
- // func propogate(
81
- // pulse: Module.Pulse, module: Module, state: Module.State
82
- // ) -> PropogateResult? {
83
- // func emit(state: Module.State, value v: Bool) -> PropogateResult {
84
- // (state: state,
85
- // pulses: module.outputs.map { (value: v, from: module.name, to: $0) })
86
- // }
87
-
88
- // switch module.type {
89
- // case .broadcast:
90
- // return emit(state: state, value: pulse.value)
91
- // case .flip:
92
- // if pulse.value {
93
- // return nil
94
- // } else {
95
- // let newValue = !state["", default: false]
96
- // let newState = state.merging(["": newValue]) { _, new in new }
97
- // return emit(state: newState, value: newValue)
98
- // }
99
- // case .conjunction:
100
- // let newState = state.merging([pulse.from: pulse.value]) { _, new in new }
101
- // let newValue = !newState.values.reduce(true) { $0 && $1 }
102
- // return emit(state: newState, value: newValue)
103
- // default:
104
- // return nil
105
- // }
106
- // }
107
-
108
- // func simulate(modules: Modules, times: Int) -> (p1: Int, p2: Int) {
109
- // let buttonPress = (value: false, from: "button", to: "broadcaster")
110
-
111
- // var counts = [true: 0, false: 0]
112
- // // Examples don't have "rx", so don't go into an infinite loop. But since
113
- // // this solution doesn't work for p2 yet, this search for rx is actually
114
- // // always disabled for now.
115
- // var rxN: Int? = haveRx(modules: modules) ? 0 : 0
116
- // var states = [String: Module.State]()
117
-
118
- // initConjunctions(modules: modules, states: &states)
119
-
120
- // var n = 0
121
- // while n < times || rxN == nil {
122
- // n += 1
123
-
124
- // var pending = [buttonPress]
125
- // var pi = 0
126
-
127
- // counts[buttonPress.value]? += 1
128
-
129
- // while pi < pending.count {
130
- // let pulse = pending[pi]
131
- // let (value, from, to) = pulse
132
- // pi += 1
133
-
134
- // if verbose > 0 {
135
- // print("button press \(n) pulse \(pi)\t\t\(from) -\(value ? "high" : "low")-> \(to)")
136
- // }
137
-
138
- // if to == "rx" {
139
- // if !value {
140
- // print("button press \(n) sending \(value) to rx")
141
- // if rxN == nil || rxN == 0 {
142
- // rxN = n
143
- // }
144
- // }
145
- // }
146
-
147
- // let module = modules[to, default: .named(to)]
148
- // let state = states[to, default: Module.State()]
149
- // if let new = propogate(pulse: pulse, module: module, state: state) {
150
- // states[to] = new.state
151
- // pending.append(contentsOf: new.pulses)
152
- // for b in new.pulses.map({ $0.value }) {
153
- // counts[b]? += 1
154
- // }
155
- // }
156
- // }
157
- // }
158
-
159
- // let p1 = counts[false]! * counts[true]!
160
- // return (p1: p1, p2: rxN!)
161
- // }
162
-
163
-
164
- // func haveRx(modules: Modules) -> Bool {
165
- // for (input, module) in modules {
166
- // if input == "rx" { return true }
167
- // for output in module.outputs {
168
- // if output == "rx" { return true }
169
- // }
170
- // }
171
- // return false
172
- // }
73
+ typealias State = [ String : Bool ]
74
+
75
+ func initStates( modules: Modules ) -> [ String : State ] {
76
+ modules. compactMapValues { module in
77
+ switch ( module. type) {
78
+ case . flip: [ " " : false ]
79
+ case . conjunction:
80
+ Dictionary ( uniqueKeysWithValues: module. inputs. map { ( $0, false ) } )
81
+ default : nil
82
+ }
83
+ }
84
+ }
85
+
86
+ struct Pulse {
87
+ let value : Bool
88
+ let from , to : String
89
+ }
90
+
91
+ extension Pulse : CustomStringConvertible {
92
+ var description : String {
93
+ return " \( from) - \( value ? " high " : " low " ) -> \( to) "
94
+ }
95
+ }
96
+
97
+ func propogate(
98
+ pulse: Pulse , module: Module , state: State ?
99
+ ) -> ( state: State ? , pulses: [ Pulse ] ) ? {
100
+ func emit( _ v: Bool ) -> [ Pulse ] {
101
+ module. outputs. map { Pulse ( value: v, from: pulse. to, to: $0) }
102
+ }
103
+
104
+ switch module. type {
105
+ case . broadcast:
106
+ return ( state, emit ( pulse. value) )
107
+ case . flip:
108
+ if pulse. value {
109
+ return nil
110
+ } else {
111
+ let newValue = !state![ " " , default: false ]
112
+ let newState = state? . merging ( [ " " : newValue] ) { _, new in new }
113
+ return ( newState, emit ( newValue) )
114
+ }
115
+ case . conjunction:
116
+ let newState = state!. merging ( [ pulse. from: pulse. value] ) { _, new in new }
117
+ let newValue = !newState. values. reduce ( true ) { $0 && $1 }
118
+ return ( newState, emit ( newValue) )
119
+ case nil :
120
+ return nil
121
+ }
122
+ }
123
+
124
+ func simulate( modules: Modules , times: Int ) -> Int {
125
+ let buttonPress = Pulse ( value: false , from: " button " , to: " broadcaster " )
126
+
127
+ var counts = [ true : 0 , false : 0 ]
128
+ func count( _ pulse: Pulse ) {
129
+ counts [ pulse. value] ? += 1
130
+ if verbose > 0 {
131
+ print ( pulse)
132
+ }
133
+ }
134
+
135
+ var states = initStates ( modules: modules)
136
+ show ( modules: modules, states: states)
137
+
138
+ var n = 0
139
+ while n < times {
140
+ n += 1
141
+
142
+ var pending = [ buttonPress]
143
+ var pi = 0
144
+
145
+ while pi < pending. count {
146
+ let pulse = pending [ pi]
147
+ let to = pulse. to
148
+ pi += 1
149
+ count ( pulse)
150
+
151
+ let module = modules [ to] !
152
+ let state = states [ to]
153
+ if let new = propogate ( pulse: pulse, module: module, state: state) {
154
+ states [ to] = new. state
155
+ pending. append ( contentsOf: new. pulses)
156
+ }
157
+ }
158
+ }
159
+
160
+ show ( modules: modules, states: states)
161
+ if verbose > 0 {
162
+ print ( counts)
163
+ }
164
+
165
+ return counts [ false ] ! * counts[ true ] !
166
+ }
167
+
168
+ func show( modules: Modules , states: [ String : State ] ) {
169
+ if verbose > 0 {
170
+ print ( modules)
171
+ print ( states)
172
+ }
173
+ }
174
+
175
+ func analyze( modules: Modules ) -> Int {
176
+ return 0
177
+ }
173
178
174
179
let modules = readInput ( )
175
- print ( modules)
176
- // let r = simulate (modules: modules, times: 1000 )
177
- // print(r )
180
+ let p1 = simulate ( modules: modules , times : 1000 )
181
+ let p2 = analyze ( modules: modules)
182
+ print ( p1 , p2 )
0 commit comments