Paul Woitaschek
12/20/2023, 7:58 AMPaul Woitaschek
12/20/2023, 7:58 AMRiccardo Lippolis
12/20/2023, 8:16 AMSet
of resulting pulses while processing the input pulses, but as it turned out it needed to be a List
Riccardo Lippolis
12/20/2023, 8:17 AMJonathan Kolberg
12/20/2023, 8:20 AMPulses are always processed in the order they are sent. So, if a pulse is sent to modules a, b, and c, and then module a processes its pulse and sends more pulses, the pulses sent to modules b and c would have to be handled first.
Was what got m in my first try, worked on examples, but I had processed all resulting pulses from a down until nothing happened anymorePaul Woitaschek
12/20/2023, 8:37 AMRiccardo Lippolis
12/20/2023, 8:45 AMRiccardo Lippolis
12/20/2023, 8:45 AMVitaly Legchilkin
12/20/2023, 9:00 AMis Module.Conjunction -> {
module.memory[instruction.from] = instruction.low
val hasOnlyHighPulses = module.memory.all { it.value }
@Paul Woitaschek didn't you mix 'low' and 'it.value' here? looks like it means an opposite thingsVitaly Legchilkin
12/20/2023, 9:00 AMPaul Woitaschek
12/20/2023, 9:03 AMVitaly Legchilkin
12/20/2023, 9:04 AMmodule.on = !module.on
module.destinations.mapTo(queue) { destination ->
Instruction(low = module.on, to = destination, from = module.name)
}
also here. If it is 'on' then we should send a high impulseVitaly Legchilkin
12/20/2023, 9:04 AMVitaly Legchilkin
12/20/2023, 9:04 AMmodule.destinations.mapTo(queue) { destination ->
Instruction(low = !module.on, to = destination, from = module.name)
}
Paul Woitaschek
12/20/2023, 9:06 AMPaul Woitaschek
12/20/2023, 9:06 AMCharles Flynn
12/20/2023, 3:49 PMHowever, before b can turn off, the pulse sent to con is handled first, so it briefly remembers all high pulses for its inputs and sends a low pulse to output. After that, flip-flop b turns off, which causes con to update its state and send a high pulse to output.
but I'm not sure I really understand what its saying here. It says above pulses are processed in order and I don't see anything about them waiting for future inputs.
https://github.com/CfGit12/aoc-2023/blob/main/src/main/kotlin/20.ktManuel Casariego
12/20/2023, 4:07 PMCharles Flynn
12/20/2023, 4:09 PM//val memory = destinations.associateBy({ it }, { Pulse.LOW }).toMutableMap()
val memory = mutableMapOf<String, Pulse>()
Charles Flynn
12/20/2023, 4:10 PMevgenim
12/20/2023, 4:10 PMCharles Flynn
12/20/2023, 4:10 PMoutput
Jonathan Kolberg
12/20/2023, 4:10 PMCharles Flynn
12/20/2023, 4:12 PMJonathan Kolberg
12/20/2023, 4:12 PMCharles Flynn
12/20/2023, 4:12 PMCharles Flynn
12/20/2023, 4:19 PMRiccardo Lippolis
12/20/2023, 4:19 PMJonathan Kolberg
12/20/2023, 4:20 PMCharles Flynn
12/20/2023, 4:20 PMevgenim
12/20/2023, 4:40 PMandriyo
12/24/2023, 10:19 AMandriyo
12/24/2023, 10:21 AMandriyo
12/24/2023, 10:29 AMJonathan Kolberg
12/24/2023, 7:20 PMandriyo
12/24/2023, 7:52 PMOzioma Ogbe
12/25/2023, 5:16 AMimport java.util.LinkedList
fun main() {
val lines = input.split("\n")
val modules = lines.map {
val name = it.split(" -> ")[0]
when {
name == "broadcaster" -> Module.BroadcasterModule(name)
name.startsWith("%") -> Module.FlipFlopModule(name.drop(1))
name.startsWith("&") -> Module.ConjunctionModule(name.drop(1))
else -> error("Unknown module")
}
}.associateBy { it.name }
lines.forEach {
val (parent, children) = it.split(" -> ")
val parentModule = modules[parent.removePrefix("%").removePrefix("&")]!!
children.split(", ").forEach {
if (modules[it] is Module.ConjunctionModule) {
(modules[it] as Module.ConjunctionModule).addSourceModule(parentModule.name)
}
modules[it]?.let { it1 -> parentModule.children.add(it1) }
}
}
data class QueueEntry(val sourceModule: String, val isHighPulse: Boolean, val destinationModule: Module)
val queue = LinkedList<QueueEntry>()
var lowPulseCount = 0L
var highPulseCount = 0L
(1..1000).forEach {
queue.offer(QueueEntry("button", false, modules["broadcaster"]!!))
lowPulseCount++
while (queue.isNotEmpty()) {
val (sourceModule, isHighPulse, destinationModule) = queue.poll()
val nextPulseSignals = destinationModule.processPulse(sourceModule, isHighPulse)
nextPulseSignals.second.forEach {
if (nextPulseSignals.first) {
highPulseCount++
} else {
lowPulseCount++
}
queue.offer(QueueEntry(destinationModule.name, nextPulseSignals.first, it))
}
}
}
println("Pulse count: ${(lowPulseCount) * highPulseCount}")
}
sealed interface Module {
val name: String
val children: MutableSet<Module>
fun processPulse(sourceModule: String, isHighPulse: Boolean): Pair<Boolean, Set<Module>>
data class BroadcasterModule(
override val name: String,
) : Module {
override val children: MutableSet<Module> = mutableSetOf()
override fun processPulse(sourceModule: String, isHighPulse: Boolean): Pair<Boolean, Set<Module>> {
return isHighPulse to children
}
}
data class FlipFlopModule(
override val name: String
) : Module {
private var isOn: Boolean = false
override val children: MutableSet<Module> = mutableSetOf()
override fun processPulse(sourceModule: String, isHighPulse: Boolean): Pair<Boolean, Set<Module>> {
if (!isHighPulse) {
isOn = !isOn
return isOn to children
}
return isOn to emptySet()
}
}
data class ConjunctionModule(
override val name: String
) : Module {
override val children: MutableSet<Module> = mutableSetOf()
private val sourceModules = mutableMapOf<String, Boolean>()
fun addSourceModule(sourceModule: String) {
sourceModules[sourceModule] = false
}
override fun processPulse(sourceModule: String, isHighPulse: Boolean): Pair<Boolean, Set<Module>> {
sourceModules[sourceModule] = isHighPulse
return if (sourceModules.values.all { it }) {
false to children
} else {
true to children
}
}
}
}
Riccardo Lippolis
12/25/2023, 7:55 AMprocessPulse
function of the FlipFlopModule
I see it returns isOn to emptySet()
, shouldn't that be isOn to children
instead? Of that's the case, I'm surprised this would have worked for the example though ๐
Ozioma Ogbe
12/25/2023, 8:42 AMRiccardo Lippolis
12/25/2023, 8:46 AMOzioma Ogbe
12/25/2023, 10:50 AM