Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7efddfd

Browse files
committed
Clean up 2024 day 24 part 2
1 parent 659e71a commit 7efddfd

File tree

2 files changed

+28
-38
lines changed

2 files changed

+28
-38
lines changed

‎src/main/scala/eu/sim642/adventofcode2024/Day24.scala

Lines changed: 27 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package eu.sim642.adventofcode2024
22

3-
import scala.annotation.tailrec
43
import scala.collection.mutable
54

5+
import eu.sim642.adventofcodelib.IteratorImplicits._
6+
67
object Day24 {
78

89
enum Op {
@@ -16,15 +17,19 @@ object Day24 {
1617
case Gate(lhs: String, op: Op, rhs: String)
1718
}
1819

19-
class CyclicCircuit extends RuntimeException
20+
/**
21+
* Exception to indicate cyclic circuit evaluation.
22+
* When trying for swaps in part 2, cycles may be introduced, which otherwise (slowly) lead to StackOverflowError.
23+
*/
24+
class CircuitCycleException extends RuntimeException
2025

2126
case class Circuit(wireMap: Map[String, Wire]) {
2227
def zValue: Long = {
2328
val memo = mutable.Map.empty[String, Boolean]
2429

2530
def evalName(name: String, called: Set[String]): Boolean =
2631
if (called.contains(name))
27-
throw new CyclicCircuit
32+
throw new CircuitCycleException
2833
else
2934
memo.getOrElseUpdate(name, evalWire(wireMap(name), called + name))
3035

@@ -54,7 +59,7 @@ object Day24 {
5459

5560
def evalName(name: String, called: Set[String]): Set[String] =
5661
if (called.contains(name))
57-
throw new CyclicCircuit
62+
throw new CircuitCycleException
5863
else
5964
memo.getOrElseUpdate(name, evalWire(wireMap(name), called + name) + name)
6065

@@ -91,62 +96,57 @@ object Day24 {
9196
withXValue(xValue).withYValue(yValue).zValue
9297
}
9398

94-
def findWrongBits(circuit: Circuit): Seq[(String, String)] = {
95-
99+
def findWireSwaps(circuit: Circuit): Seq[(String, String)] = {
96100
def isCorrect(circuit: Circuit, i: Int): Boolean = {
97101
(for {
102+
// must also check previous bit to account for incoming carry
98103
xBit <- 0 to 3
99104
yBit <- 0 to 3
100105
xValue = xBit.toLong << i >> 1
101106
yValue = yBit.toLong << i >> 1
102-
//if (try {circuit.dependencies("z45"); true} catch {case e: CyclicCircuit => false})
103-
} yield try {circuit.add(xValue, yValue) == xValue + yValue} catch {case e: CyclicCircuit => false}).forall(identity)
107+
} yield {
108+
try circuit.add(xValue, yValue) == xValue + yValue
109+
catch case _: CircuitCycleException => false
110+
}).forall(identity)
104111
}
105112

106-
def helper(circuit: Circuit, i: Int, acc: Seq[(String, String)]): Seq[Seq[(String, String)]] = {
113+
def helper(circuit: Circuit, i: Int, acc: List[(String, String)]): Iterator[List[(String, String)]] = {
107114
if (acc.sizeIs > 4)
108-
Seq.empty
115+
Iterator.empty
109116
else if (i > 44)
110-
Seq(acc)
117+
Iterator.single(acc)
111118
else if (isCorrect(circuit, i))
112119
helper(circuit, i + 1, acc)
113120
else {
114-
println(i)
115121
val depsPrev = circuit.dependencies(s"z${i - 1}")
116122
val deps = circuit.dependencies(s"z$i")
117123
val depsNext = circuit.dependencies(s"z${i + 1}")
118124
val depsNext2 = circuit.dependencies(s"z${i + 2}")
119125
val wrong1 = ((deps -- depsPrev) ++ (depsNext -- deps)).filterNot(_.startsWith("x")).filterNot(_.startsWith("y"))
120126
val wrong2 = (depsNext2 -- depsPrev).filterNot(_.startsWith("x")).filterNot(_.startsWith("y"))
121-
println(wrong1)
122-
println(wrong2)
123127
val swaps =
124128
for {
125129
name1 <- wrong1
126130
name2 <- wrong2
131+
// order names in swap to avoid duplicate checking
127132
minName = if (name1 < name2) name1 else name2
128133
maxName = if (name1 < name2) name2 else name1
129134
} yield (minName, maxName)
130135
for {
131-
(name1, name2) <- swaps.toSeq
132-
//name2 <- wrong2
136+
swap@(name1, name2) <- swaps.iterator
133137
newCircuit = circuit.swapped(name1, name2)
134-
//() = println((name1, name2))
135-
if isCorrect(newCircuit, i - 1)
136138
if isCorrect(newCircuit, i)
137-
swap = (name1, name2)
138-
rest <- helper(newCircuit, i + 1, acc :+ swap)
139-
} yield rest
139+
newAcc <- helper(newCircuit, i + 1, swap :: acc)
140+
} yield newAcc
140141
}
141142
}
142143

143-
val all = helper(circuit, 0, Seq.empty)
144-
all.foreach(println)
145-
all.head
144+
val swapss = helper(circuit, 0, Nil)
145+
swapss.head
146146
}
147147

148-
def findWrongBitsString(circuit: Circuit): String =
149-
findWrongBits(circuit).flatMap({ case (a, b) => Seq(a, b)}).sorted.mkString(",")
148+
def findWireSwapsString(circuit: Circuit): String =
149+
findWireSwaps(circuit).flatMap({ case (name1, name2) => Seq(name1, name2) }).sorted.mkString(",")
150150

151151
def parseInput(s: String): (String, Wire.Input) = s match {
152152
case s"$name: 0" => name -> Wire.Input(false)
@@ -186,16 +186,6 @@ object Day24 {
186186
def main(args: Array[String]): Unit = {
187187
val circuit = parseCircuit(input)
188188
println(circuit.zValue)
189-
findWrongBits(circuit)
190-
val circuit2 = circuit.swapped("z21", "nhn").swapped("tvb", "khg").swapped("z33", "gst").swapped("z12", "vdc")
191-
//printCircuitDot(circuit2)
192-
//println(circuit2.zValue)
193-
//println("51401618891888")
194-
195-
val circuit3 = circuit2.withXValue(0)
196-
//println(circuit3.zValue)
197-
198-
//println(Seq("z21", "nhn", "tvb", "khg", "z33", "gst", "z12", "vdc").sorted.mkString(","))
199-
// part 2: gst,khg,nhn,tvb,vdc,z12,z21,z33 - correct
189+
println(findWireSwapsString(circuit))
200190
}
201191
}

‎src/test/scala/eu/sim642/adventofcode2024/Day24Test.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,6 @@ class Day24Test extends AnyFunSuite {
7676
}
7777

7878
test("Part 2 input answer") {
79-
assert(findWrongBitsString(parseCircuit(input)) == "gst,khg,nhn,tvb,vdc,z12,z21,z33")
79+
assert(findWireSwapsString(parseCircuit(input)) == "gst,khg,nhn,tvb,vdc,z12,z21,z33")
8080
}
8181
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /