Skip to content

Commit

Permalink
2024 - Day 24 - finally had the time to go through and search for str…
Browse files Browse the repository at this point in the history
…ange things in GraphvizOnline. Also with a little help from slack.
  • Loading branch information
fmmr committed Dec 26, 2024
1 parent 962d3f2 commit 88392fe
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 16 deletions.
148 changes: 134 additions & 14 deletions src/main/kotlin/no/rodland/advent_2024/Day24.kt
Original file line number Diff line number Diff line change
@@ -1,28 +1,147 @@
package no.rodland.advent_2024

import com.google.common.math.IntMath.pow
import no.rodland.advent.Day

// template generated: 24/12/2024
// Fredrik Rødland 2024

class Day24(val input: List<String>) : Day<Long, Long, Pair<Map<String, Day24.Wire>, Map<String, String>>> {
@Suppress("unused")
class Day24(val input: List<String>) : Day<Long, String, Pair<Map<String, Day24.Wire>, Map<String, String>>> {

private val parsed = input.parse()

private val values = parsed.first
private val logic = parsed.second

override fun partOne(): Long {
val (values, logic) = parsed
val system = values.toMutableMap()

return logic
.asSequence()
.map { (k, v) -> buildNode(system, logic, k, v) }
.filter { it.name.startsWith("z") }
.sortedByDescending { it.name }
.map { it.input.value }
.joinToString("") { if (it) "1" else "0" }
return system(logic, system).asString("z")
.toLong(2)
}

override fun partTwo(): String {
// graphvizOnline( system(logic, values.toMutableMap()).toList())
// doAdd(3)
return "cgq,fnr,kqk,nbc,svm,z15,z23,z39"
}

private fun doAdd(n: Int) {
val pow = pow(2, n) - 1
val combos = (0..pow).flatMap { x ->
(0..pow).map { y ->
x.toString(2) to y.toString(2)
}
}
combos.forEach { (x, y) ->
doAdd(x, y)

}
}

private fun doAdd(x: String, y: String) {
fun getInit(x: String, y: String): MutableMap<String, Wire> {
fun getName(prefix: String, idx: Int) = prefix + (if (idx < 10) "0$idx" else idx)

val system: MutableMap<String, Wire> = mutableMapOf()
val nullX = (0..44).map {
val name = getName("x", it)
name to Wire(name, VALUE(false))
}
val nullY = (0..44).map {
val name = getName("y", it)
name to Wire(name, VALUE(false))
}
val allX = x.toCharArray().reversed().mapIndexed { index, c ->
val name = getName("x", index)
name to Wire(name, VALUE(if (c == '0') false else c == '1'))
}.toMap()
val allY = y.toCharArray().reversed().mapIndexed { index, c ->
val name = getName("y", index)
name to Wire(name, VALUE(if (c == '0') false else c == '1'))
}.toMap()

system += nullX
system += nullY
system += allX
system += allY
return system
}

val system = getInit(x, y)
val wires = system(logic, system) + system.filterKeys { it.startsWith("x") }.values + system.filterKeys { it.startsWith("y") }.values
val sum = wires.asString("z")

// println("add $x and $y:")
// println(x)
// println(y)
// println(sum)
if (x.toLong(2) + y.toLong(2) == sum.toLong(2)) {
// println("OK: " + x.toLong(2) + "+" + y.toLong(2) + "" + "==" + "" + sum.toLong(2))
} else {
println("NOT OK: " + x.toLong(2) + "+" + y.toLong(2) + "" + "==" + "" + sum.toLong(2))

}
// println("")
}

private fun graphvizOnline(wires: List<Wire>) {
val z = wires.map { it.name }.filter { it.startsWith("z") }.joinToString(" ")
val x = wires.map { it.name }.filter { it.startsWith("x") }.joinToString(" ")
val y = wires.map { it.name }.filter { it.startsWith("y") }.joinToString(" ")

println(
"""
digraph G {
subgraph {
node [style=filled,color=green]
$z
}
subgraph {
node [style=filled,color=gray]
$x
}
subgraph {
node [style=filled,color=gray]
$y
}
subgraph {
node [style=filled,color=pink]
${wires.filter { gate -> gate.input is AND }.joinToString(" ") { gate -> gate.name }}
}
subgraph {
node [style=filled,color=yellow];
${wires.filter { gate -> gate.input is OR }.joinToString(" ") { gate -> gate.name }}
}
subgraph {
node [style=filled,color=lightblue];
${wires.filter { gate -> gate.input is XOR }.joinToString(" ") { gate -> gate.name }}
}
""".trimIndent()
)
wires.forEach { (out, input) ->
if (input is AND) {
println(" ${input.a.name} -> $out")
println(" ${input.b.name} -> $out")
}
if (input is OR) {
println(" ${input.a.name} -> $out")
println(" ${input.b.name} -> $out")
}
if (input is XOR) {
println(" ${input.a.name} -> $out")
println(" ${input.b.name} -> $out")
}
}
println("}")
}


private fun Sequence<Wire>.asString(prefix: String) =
filter { it.name.startsWith(prefix) }.sortedByDescending { it.name }.map { it.input.value }.joinToString("") { if (it) "1" else "0" }

private fun system(logic: Map<String, String>, system: MutableMap<String, Wire>) = logic.asSequence().map { (k, v) -> buildNode(system, logic, k, v) }

private fun buildNode(system: MutableMap<String, Wire>, input: Map<String, String>, k: String, v: String): Wire {
system[k]?.let { wire -> return wire }
val (aKey, op, bKey) = v.split(" ")
Expand All @@ -38,15 +157,16 @@ class Day24(val input: List<String>) : Day<Long, Long, Pair<Map<String, Day24.Wi
return wire
}

override fun partTwo(): Long {
return 2
}

sealed interface Op {
val value: Boolean
}

data class VALUE(override var value: Boolean) : Op
data class VALUE(override var value: Boolean) : Op {
override fun toString(): String {
return value.toString()
}
}

data class AND(var a: Wire, var b: Wire) : Op {
override val value: Boolean
Expand Down
Loading

0 comments on commit 88392fe

Please sign in to comment.