Skip to content

Commit 02e8941

Browse files
committed
DynamicSolver appears to be working, but slow
1 parent b491c1b commit 02e8941

File tree

4 files changed

+56
-23
lines changed

4 files changed

+56
-23
lines changed

python/graphs.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,32 @@ def __init__(self):
1313
self.edge_labels = None
1414

1515
def generate(self, n_verts):
16+
iteration = 0
17+
while iteration < 100:
18+
iteration += 1
19+
self._try_generate(n_verts)
20+
largest_component = extract_largest_component(self.graph, prune=True, directed=False)
21+
print(f"N verts = {largest_component.num_vertices()}, N edges = {largest_component.num_edges()}")
22+
if largest_component.num_vertices() == n_verts:
23+
return
24+
print("Could not generate a connected graph")
25+
26+
def _try_generate(self, n_verts):
1627
self.graph = Graph(directed = True)
1728
self.labels = self.graph.new_vp("int")
1829
self.gates = defaultdict(dict)
1930
self.edge_labels = self.graph.new_ep("int")
2031

2132
self.verts = []
33+
labels = []
2234
for i in range(n_verts):
2335
v = self.graph.add_vertex()
2436
label = random.randint(0, 3)
37+
labels.append(label)
2538
self.labels[v] = label
2639
#self.graph.vertex_index[v] = i
2740
self.verts.append(v)
41+
print(f"Labels: {labels}")
2842

2943
for v1_idx, v1 in enumerate(self.verts):
3044
for src_gate_idx in range(6):
@@ -45,6 +59,7 @@ def generate(self, n_verts):
4559
self.gates[v1_idx][src_gate_idx] = edge
4660
self.gates[v2_idx][dst_gate_idx] = edge
4761
self.edge_labels[edge] = src_gate_idx
62+
print(f"connect [{v1_idx}].{src_gate_idx} to [{v2_idx}].{dst_gate_idx}")
4863
#print(f"...selected: [{v2_idx}].{dst_gate_idx}")
4964
break
5065

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ object ProblemDefinition {
1616
case "quintus" => 30
1717
case _ => throw new Exception(s"Unknown problem name: $name."),
1818
name match
19-
case "probatio" => 54
19+
case "probatio" => 12
2020
case "primus" => 108
2121
case "secundus" => 216
2222
case "tertius" => 324

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

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ case class StepApplied(graph : MyGraph, nextDoor : DoorVertex) extends SolverSte
1111
}
1212
case class TargetDoorsExhausted() extends SolverStepResult derives ReadWriter
1313
case class TargetRoomsExhausted() extends SolverStepResult derives ReadWriter
14-
case class Contradiction() extends SolverStepResult derives ReadWriter
15-
case class TryOtherDoor() extends SolverStepResult derives ReadWriter
14+
case class Contradiction(roomLabel : Int) extends SolverStepResult derives ReadWriter
15+
case class TryOtherDoor(roomLabel : Option[Int]) extends SolverStepResult derives ReadWriter
1616
case class Rollback() extends SolverStepResult derives ReadWriter
1717
case class Impossible() extends SolverStepResult derives ReadWriter
1818

@@ -23,8 +23,9 @@ case class Offsets(roomOffset : Int, doorOffset : Int) derives ReadWriter
2323

2424
object DynamicSolver {
2525
def processStep(g : MyGraph, input : StepInput, offset : Offsets) : SolverStepResult =
26-
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+
//println(s"Try: from room #${input.roomFromUid}, via door #${input.doorIdx}, to room labeled ${input.roomToLabel}, room offset = ${offset.roomOffset}, door offset = ${offset.doorOffset}")
2727
if (offset.roomOffset > g.rooms.length - 1) {
28+
//println("Room offset is too big")
2829
TargetRoomsExhausted()
2930
} else if (offset.doorOffset > 5) {
3031
TargetDoorsExhausted()
@@ -34,12 +35,12 @@ object DynamicSolver {
3435
case None => {
3536
val existingCandidateRoomsWithDoors = g.findRoomsByLabelWithFreeDoors(input.roomToLabel)
3637
val existingCandidateRooms = existingCandidateRoomsWithDoors.keys.toSeq.sortBy(_.uid)
37-
println(s"Rooms already labeled ${input.roomToLabel}: $existingCandidateRooms")
38+
//println(s"Rooms already labeled ${input.roomToLabel}: $existingCandidateRooms")
3839
if (existingCandidateRooms.length > offset.roomOffset) {
3940
val existingCandidateDoors = existingCandidateRoomsWithDoors(existingCandidateRooms(offset.roomOffset))
4041
if (existingCandidateDoors.length > offset.doorOffset) {
4142
val nextDoor = existingCandidateDoors(offset.doorOffset)
42-
println(s"Connect room #${input.roomFromUid} door ${input.doorIdx} to room ${nextDoor.roomUid}, door ${nextDoor.idx}")
43+
//println(s"Connect room #${input.roomFromUid} door ${input.doorIdx} to room ${nextDoor.roomUid}, door ${nextDoor.idx}")
4344
StepApplied(
4445
g.connectRooms(input.roomFromUid, input.doorIdx, nextDoor.roomUid, nextDoor.idx),
4546
nextDoor
@@ -53,24 +54,25 @@ object DynamicSolver {
5354
if (freeRooms.length > freeRoomOffset) {
5455
val freeRoom = freeRooms(freeRoomOffset)
5556
val labeledGraph = g.setRoomLabel(freeRoom.uid, Some(input.roomToLabel))
56-
println(s"Connect room #${input.roomFromUid} door ${input.doorIdx} to room ${freeRoom.uid}, door ${0}")
57+
//println(s"Connect room #${input.roomFromUid} door ${input.doorIdx} to room ${freeRoom.uid}, door ${0}")
5758
StepApplied(
5859
labeledGraph.connectRooms(input.roomFromUid, input.doorIdx, freeRoom.uid, 0),
5960
DoorVertex(freeRoom.uid, 0)
6061
)
6162
} else {
63+
//println(s"There are no free rooms to be labeled ${input.roomToLabel} left")
6264
TargetRoomsExhausted()
6365
}
6466
}
6567
}
6668
case Some(linkedRoom) => {
6769
if (linkedRoom.label == Some(input.roomToLabel)) {
68-
println(s"Room #${input.roomFromUid} door ${input.doorIdx} was already connected to room #${linkedRoom.uid} (label ${linkedRoom.label}) => good")
70+
//println(s"Room #${input.roomFromUid} door ${input.doorIdx} was already connected to room #${linkedRoom.uid} (label ${linkedRoom.label}) => good")
6971
val nextDoor = g.adjacentDoor(g.doors(input.roomFromUid)(input.doorIdx)).get
7072
StepApplied(g, nextDoor)
7173
} else {
72-
println(s"Room #${input.roomFromUid} door ${input.doorIdx} was already connected to room #${linkedRoom.uid} (label ${linkedRoom.label}) => contradiction")
73-
Contradiction()
74+
//println(s"Room #${input.roomFromUid} door ${input.doorIdx} was already connected to room #${linkedRoom.uid} (label ${linkedRoom.label}) => contradiction")
75+
Contradiction(input.roomToLabel)
7476
}
7577
}
7678
}
@@ -82,35 +84,50 @@ object DynamicSolver {
8284
var subDoorOffset = 0
8385
while (iteration < 100)
8486
val subOffsets = Offsets(subRoomOffset, subDoorOffset) +: offsets
85-
println(f"Step into, iteration $iteration; remaining length is ${inputs.length}; offsets: $subOffsets")
87+
//println(f"Step into, iteration $iteration; remaining length is ${inputs.length}; offsets: $subOffsets")
8688
val subResult = processStepRecursive(graph, inputs, currentRoomUid = currentRoomUid, offsets = subOffsets)
87-
println(s"Returning from recursive call: $subResult")
89+
//println(s"Returning from recursive call: $subResult, current target label is #${inputs.head.roomToLabel}")
8890
subResult match {
8991
case StepApplied(_,_) => return subResult
90-
case TargetRoomsExhausted() => return TryOtherDoor()
92+
case TargetRoomsExhausted() => return TryOtherDoor(None)
9193
case TargetDoorsExhausted() =>
9294
subRoomOffset += 1
9395
subDoorOffset = 0
94-
case TryOtherDoor() =>
95-
subDoorOffset += 1
96-
case Contradiction() => return TryOtherDoor()
96+
case TryOtherDoor(r) =>
97+
val roomMatched = r match {
98+
case Some(label) => label == inputs.head.roomToLabel
99+
case None => true
100+
}
101+
if (roomMatched)
102+
subDoorOffset += 1
103+
else
104+
TryOtherDoor(r)
105+
case Contradiction(roomLabel) =>
106+
val roomMatched = roomLabel == inputs.head.roomToLabel
107+
if (roomMatched)
108+
subDoorOffset += 1
109+
else
110+
return TryOtherDoor(Some(roomLabel))
97111
}
98112
iteration += 1
99113
Impossible()
100114

101115
def processStepRecursive(graph : MyGraph, inputs : Seq[LabelInput], currentRoomUid : Int = 0, offsets : Seq[Offsets] = Seq(Offsets(0,0))) : SolverStepResult =
102116
if (inputs.length == 0) {
103-
println("no inputs left")
117+
//println("no inputs left")
104118
StepApplied(graph, DoorVertex(currentRoomUid, 0))
105119
} else {
106120
val stepInput = StepInput(currentRoomUid, inputs.head.doorIdx, inputs.head.roomToLabel)
107121
val stepResult = processStep(graph, stepInput, offsets.head)
108-
println(s"Returning from single step call: $stepResult")
109-
stepResult match {
110-
case StepApplied(newGraph, door) =>
111-
processStepRecursiveEnumerate(newGraph, door.roomUid, inputs = inputs.tail, offsets=offsets)
112-
case _ => stepResult
113-
}
122+
//println(s"Returning from single step call: $stepResult")
123+
if (inputs.tail.isEmpty)
124+
stepResult
125+
else
126+
stepResult match {
127+
case StepApplied(newGraph, door) =>
128+
processStepRecursiveEnumerate(newGraph, door.roomUid, inputs = inputs.tail, offsets=offsets)
129+
case _ => stepResult
130+
}
114131
}
115132

116133
def makeInput(plan : Seq[Int], roomLabels : Seq[Int]) : Seq[LabelInput] =

src/main/scala/ru/org/codingteam/icfpc_2025/Æedificium.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ object Ædificium:
6060
}
6161
)
6262
)
63+
println(asJson(request))
6364
val response = basicRequest
6465
.post(uri"$baseUrl/guess")
6566
.body(asJson(request))

0 commit comments

Comments
 (0)