Skip to content

Commit 16113f2

Browse files
committed
DynamicSolver: it tries to work, but does not :/
1 parent 23adff4 commit 16113f2

File tree

3 files changed

+52
-38
lines changed

3 files changed

+52
-38
lines changed

src/main/scala/ru/org/codingteam/icfpc_2025/DynamicSolver.scala

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,26 @@ case class Impossible() extends SolverStepResult derives ReadWriter
1818
case class LabelInput(roomFromLabel : Int, doorIdx : Int, roomToLabel : Int) derives ReadWriter
1919
case class StepInput(roomFromUid : Int, doorIdx : Int, roomToLabel : Int) derives ReadWriter
2020

21+
case class Offsets(roomOffset : Int, doorOffset : Int) derives ReadWriter
22+
2123
object DynamicSolver {
22-
def processStep(g : MyGraph, input : StepInput, targetRoomOffset : Int = 0, targetDoorOffset : Int = 0) : SolverStepResult =
23-
println(s"Try: from room #${input.roomFromUid}, via door #${input.doorIdx}, to room labeled ${input.roomToLabel}, room offset = $targetRoomOffset, door offset = $targetDoorOffset")
24-
if (targetRoomOffset > g.rooms.length - 1) {
24+
def processStep(g : MyGraph, input : StepInput, offset : Offsets) : SolverStepResult =
25+
println(s"Try: from room #${input.roomFromUid}, via door #${input.doorIdx}, to room labeled ${input.roomToLabel}, room offset = ${offset.roomOffset}, door offset = ${offset.doorOffset}")
26+
if (offset.roomOffset > g.rooms.length - 1) {
2527
TargetRoomsExhausted()
26-
} else if (targetDoorOffset > 5) {
28+
} else if (offset.doorOffset > 5) {
2729
TargetDoorsExhausted()
2830
} else {
2931
val existingLinkedRoom = g.adjacentRoom(g.doors(input.roomFromUid)(input.doorIdx))
3032
existingLinkedRoom match {
3133
case None => {
32-
val existingCandidateRooms = g.findRoomsByLabel(input.roomToLabel)
34+
val existingCandidateRoomsWithDoors = g.findRoomsByLabelWithFreeDoors(input.roomToLabel)
35+
val existingCandidateRooms = existingCandidateRoomsWithDoors.keys.toSeq.sortBy(_.uid)
3336
println(s"Rooms already labeled ${input.roomToLabel}: $existingCandidateRooms")
34-
if (existingCandidateRooms.length > targetRoomOffset) {
35-
val existingCandidateDoors = g.findFreeDoors(existingCandidateRooms(targetRoomOffset).uid)
36-
if (existingCandidateDoors.length > targetDoorOffset) {
37-
val nextDoor = existingCandidateDoors(targetDoorOffset)
37+
if (existingCandidateRooms.length > offset.roomOffset) {
38+
val existingCandidateDoors = existingCandidateRoomsWithDoors(existingCandidateRooms(offset.roomOffset))
39+
if (existingCandidateDoors.length > offset.doorOffset) {
40+
val nextDoor = existingCandidateDoors(offset.doorOffset)
3841
println(s"Connect room #${input.roomFromUid} door ${input.doorIdx} to room ${nextDoor.roomUid}, door ${nextDoor.idx}")
3942
StepApplied(
4043
g.connectRooms(input.roomFromUid, input.doorIdx, nextDoor.roomUid, nextDoor.idx),
@@ -45,7 +48,7 @@ object DynamicSolver {
4548
}
4649
} else {
4750
val freeRooms = g.findUnlabeledRooms
48-
val freeRoomOffset = targetRoomOffset - existingCandidateRooms.length
51+
val freeRoomOffset = offset.roomOffset - existingCandidateRooms.length
4952
if (freeRooms.length > freeRoomOffset) {
5053
val freeRoom = freeRooms(freeRoomOffset)
5154
val labeledGraph = g.setRoomLabel(freeRoom.uid, Some(input.roomToLabel))
@@ -71,39 +74,40 @@ object DynamicSolver {
7174
}
7275
}
7376

74-
def processStepEnumerating(graph : MyGraph, inputs : Seq[LabelInput], currentRoomUid : Int = 0, roomOffset : Int = 0, doorOffset : Int = 0) : SolverStepResult =
77+
def processStepRecursiveEnumerate(graph : MyGraph, currentRoomUid : Int, inputs : Seq[LabelInput], offsets : Seq[Offsets] = Seq()) : SolverStepResult =
78+
var iteration = 0
79+
var subRoomOffset = 0
80+
var subDoorOffset = 0
81+
while (iteration < 100)
82+
val subOffsets = Offsets(subRoomOffset, subDoorOffset) +: offsets
83+
println(f"Step into, iteration $iteration; remaining length is ${inputs.tail.length}; offsets: $subOffsets")
84+
val subResult = processStepRecursive(graph, inputs, currentRoomUid = currentRoomUid, offsets = subOffsets)
85+
println(s"Returning from recursive call: $subResult")
86+
subResult match {
87+
case StepApplied(_,_) => return subResult
88+
case TargetRoomsExhausted() => return Contradiction()
89+
case TargetDoorsExhausted() =>
90+
subRoomOffset += 1
91+
subDoorOffset = 0
92+
case Contradiction() =>
93+
subDoorOffset += 1
94+
}
95+
iteration += 1
96+
Impossible()
97+
98+
def processStepRecursive(graph : MyGraph, inputs : Seq[LabelInput], currentRoomUid : Int = 0, offsets : Seq[Offsets] = Seq(Offsets(0,0))) : SolverStepResult =
7599
if (inputs.length == 0) {
76100
println("no inputs left")
77101
StepApplied(graph, DoorVertex(currentRoomUid, 0))
78102
} else {
79103
val stepInput = StepInput(currentRoomUid, inputs.head.doorIdx, inputs.head.roomToLabel)
80-
val stepResult = processStep(graph, stepInput, roomOffset, doorOffset)
104+
val stepResult = processStep(graph, stepInput, offsets.head)
105+
println(s"Returning from single step call: $stepResult")
81106
stepResult match {
82107
case StepApplied(newGraph, door) =>
83-
println(f"Step into; remaining length is ${inputs.tail.length}")
84-
val subResult = processStepEnumerating(newGraph, inputs.tail, currentRoomUid = door.roomUid)
85-
println(s"Returning from recursive call: $subResult")
86-
subResult match {
87-
case StepApplied(_,_) => return subResult
88-
case _ =>
89-
println(s"Do rollback; remaining length is ${inputs.length}")
90-
return processStepEnumerating(graph, inputs, currentRoomUid, roomOffset = roomOffset, doorOffset = doorOffset+1)
91-
}
92-
case TargetDoorsExhausted() =>
93-
println("Doors exhausted")
94-
return processStepEnumerating(graph, inputs, 0, roomOffset+1, 0)
95-
case TargetRoomsExhausted() =>
96-
println("Rooms exhausted")
97-
return TargetRoomsExhausted()
98-
case Contradiction() =>
99-
println("Contradiction")
100-
//return processStepEnumerating(graph, inputs, currentRoomUid, roomOffset = roomOffset, doorOffset = doorOffset+1)
101-
return Rollback()
102-
case Rollback() =>
103-
println("Rollback")
104-
return processStepEnumerating(graph, inputs, currentRoomUid, roomOffset = roomOffset, doorOffset = doorOffset+1)
108+
processStepRecursiveEnumerate(newGraph, door.roomUid, inputs = inputs.tail, offsets=offsets)
109+
case _ => stepResult
105110
}
106-
Impossible()
107111
}
108112

109113
def makeInput(plan : Seq[Int], roomLabels : Seq[Int]) : Seq[LabelInput] =
@@ -119,6 +123,6 @@ object DynamicSolver {
119123

120124
def processPlanAndRooms(graph : MyGraph, srcRoomUid : Int, plan : Seq[Int], roomLabels : Seq[Int]) : SolverStepResult =
121125
val inputs = makeInput(plan, roomLabels)
122-
processStepEnumerating(graph, inputs, currentRoomUid = srcRoomUid)
126+
processStepRecursiveEnumerate(graph, currentRoomUid = srcRoomUid, inputs)
123127

124128
}

src/main/scala/ru/org/codingteam/icfpc_2025/Graph.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,16 @@ class MyGraph private (val graph : Graph[MyVertex, UnDiEdge[MyVertex]],
5959
def findRoomsByLabel(label : Int) =
6060
rooms.filter(r => r.label == Some(label))
6161

62+
def findRoomsByLabelWithFreeDoors(label : Int) : Map[RoomVertex, Seq[DoorVertex]] =
63+
val pairs = rooms.filter(r => r.label == Some(label)).flatMap(room =>
64+
val freeDoors = doors(room.uid).filter(d => graph.get(d).degree == 1)
65+
if (freeDoors.isEmpty)
66+
None
67+
else
68+
Some(room -> freeDoors)
69+
)
70+
Map(pairs*)
71+
6272
def findFreeDoors(roomUid : Int) =
6373
doors(roomUid).filter(d => graph.get(d).degree == 1)
6474

src/main/scala/ru/org/codingteam/icfpc_2025/SatSolver.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ object SatSolver:
2727
return
2828
else
2929
println(s"The solution for problem ${problem.name} is not correct!")
30-
throw new Exception("Incorrect solution! Analyze results in \"path\".")
30+
throw new Exception("Incorrect solution! Analyze results in \"path\".")
3131
case Step.StopGuessing() =>
3232
println("Don't wanna play anymore.")
3333
return
@@ -50,7 +50,7 @@ object SatSolver:
5050

5151
val folder = Files.createTempDirectory(s"icfpc.sat.${problem.name}")
5252
println(s"Temp directory: ${folder}")
53-
53+
5454
val sb = new StringBuilder()
5555
val roomLabelVariablesCount = problem.size*4
5656
val roomLabelClausesCount = problem.size

0 commit comments

Comments
 (0)