Skip to content

Commit 951d238

Browse files
committed
Run the existing algo
1 parent af4e878 commit 951d238

File tree

1 file changed

+108
-103
lines changed

1 file changed

+108
-103
lines changed

20.rev.swift

Lines changed: 108 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -70,108 +70,113 @@ func readInput() -> Modules {
7070
return result
7171
}
7272

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+
}
173178

174179
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

Comments
 (0)