beat speed, down to 14 seconds now (see crosssolveriteratorupgraded
This commit is contained in:
parent
f7a2e30832
commit
200fd4e85f
@ -32,6 +32,7 @@ open abstract class CrossSolver {
|
||||
*
|
||||
* - no changes: base times: 72s, 29s, 61s
|
||||
* - changed list<int> in edgemodel to intarray: 51s, 21s, 35s
|
||||
* - new version, optimised now avoid recalc: 47s, 21s, 34s, 14s, (401592291, 147023415, 67382002, 67381995)
|
||||
*/
|
||||
fun main(args: Array<String>) {
|
||||
|
||||
@ -82,20 +83,24 @@ fun main(args: Array<String>) {
|
||||
val usedModel = EdgeModel.withMoves(moves)
|
||||
println(usedModel)
|
||||
|
||||
// val baseSolve = CrossSolverBase().solveCrossesTimed(usedModel)
|
||||
// CrossSolver.printResults(baseSolve)
|
||||
|
||||
val upgradedSolve = CrossSolverUpgraded().solveCrossesTimed(usedModel)
|
||||
CrossSolver.printResults(upgradedSolve)
|
||||
//
|
||||
|
||||
val upgradedSolveSkip = CrossSolverUpgradedSkip().solveCrossesTimed(usedModel)
|
||||
CrossSolver.printResults(upgradedSolveSkip)
|
||||
|
||||
val solveCrossesTimed = CrossSolverIterator().solveCrossesTimed(usedModel)
|
||||
CrossSolver.printResults(solveCrossesTimed)
|
||||
|
||||
val s3 = CrossSolverIteratorUpgraded().solveCrossesTimed(usedModel)
|
||||
CrossSolver.printResults(s3)
|
||||
|
||||
// val allCrossMoveCountUpgradedSkip = allCrossMoveCountUpgradedSkip(scrambledModel)
|
||||
// allCrossMoveCountUpgradedSkip.forEach { color, moves ->
|
||||
// println("skip upgrade cross for color: ${color} in ${moves.size}: ${moves.joinToString(" ")}")
|
||||
// }
|
||||
// val baseSolve = CrossSolverBase().solveCrossesTimed(usedModel)
|
||||
// CrossSolver.printResults(baseSolve)
|
||||
}
|
||||
|
||||
|
||||
44
src/main/kotlin/be/nielandt/CrossSolverIteratorUpgraded.kt
Normal file
44
src/main/kotlin/be/nielandt/CrossSolverIteratorUpgraded.kt
Normal file
@ -0,0 +1,44 @@
|
||||
package be.nielandt
|
||||
|
||||
import be.nielandt.iterator.ValidClassMoveIterator
|
||||
|
||||
/**
|
||||
* This solver avoids redoing edgemodel manipulations. Should be equivalent to X nested for loops.
|
||||
*/
|
||||
class CrossSolverIteratorUpgraded : CrossSolver() {
|
||||
|
||||
override fun solveCrosses(edgeModel: EdgeModel): Map<Int, IntArray> {
|
||||
val moveCounts = mutableMapOf<Int, IntArray>()
|
||||
var iteratorCount = 0
|
||||
for (moveCount in 1..8) {
|
||||
println("all cross move count upgrade doing $moveCount")
|
||||
// build a counter of moveCount big
|
||||
val counter = ValidClassMoveIterator(moveCount)
|
||||
val edgeModelFactory = EdgeModelFactoryIterator(edgeModel, counter)
|
||||
|
||||
while (edgeModelFactory.hasNext()) {
|
||||
// get the next model, using the internal counter which simply iterates over possible combinations of moves
|
||||
val next = edgeModelFactory.getNext()
|
||||
iteratorCount++
|
||||
|
||||
// check crosses that have not been found yet
|
||||
(0..5).forEach { color ->
|
||||
if (!moveCounts.containsKey(color)) {
|
||||
val crossSolved = next.crossSolved(color)
|
||||
if (crossSolved) {
|
||||
// what is the move combination we're looking at?
|
||||
moveCounts[color] = edgeModelFactory.movesOfCurrent().copyOf()
|
||||
}
|
||||
}
|
||||
}
|
||||
// break if we have found hem all
|
||||
if (moveCounts.keys.size == 6) {
|
||||
println("iteratorCount = $iteratorCount")
|
||||
return moveCounts
|
||||
}
|
||||
}
|
||||
}
|
||||
println("had to do it all... iteratorCount = $iteratorCount")
|
||||
return moveCounts
|
||||
}
|
||||
}
|
||||
66
src/main/kotlin/be/nielandt/EdgeModelFactoryIterator.kt
Normal file
66
src/main/kotlin/be/nielandt/EdgeModelFactoryIterator.kt
Normal file
@ -0,0 +1,66 @@
|
||||
package be.nielandt
|
||||
|
||||
/**
|
||||
* This thing helps us to create edgemodels using a counter. The advantage is that the edgemodel doesn't need to be calculated
|
||||
* completely from scratch: previous states are kept, so if, e.g., the third digit changes in the counter (of length 5),
|
||||
* the previous state that was calculated using the first two states is used to perform move 3,4,5 on.
|
||||
*
|
||||
* This is probably equivalent to 8 nested for loops, you'd be able to keep track of temporary solutions there too....
|
||||
*/
|
||||
class EdgeModelFactoryIterator(val original: EdgeModel, val counter: Iterator<IntArray>) {
|
||||
// keep a modified version of the edgemodel for each digit in the counter, from left to right
|
||||
private val history: MutableList<EdgeModel> = mutableListOf()
|
||||
private var previous:IntArray
|
||||
private var lastMoves: IntArray
|
||||
|
||||
init {
|
||||
// init the history
|
||||
val firstOne = counter.next()
|
||||
lastMoves = firstOne
|
||||
this.history.add(original.doMove(firstOne[0]))
|
||||
for (i in 1 until firstOne.size) {
|
||||
this.history.add(this.history.last().doMove(firstOne[i]))
|
||||
}
|
||||
// keep track of the 'previous move that was performed'
|
||||
previous = firstOne
|
||||
}
|
||||
|
||||
fun hasNext(): Boolean {
|
||||
return counter.hasNext()
|
||||
}
|
||||
|
||||
fun movesOfCurrent() : IntArray {
|
||||
return previous
|
||||
}
|
||||
|
||||
fun getNext(): EdgeModel {
|
||||
// the next set of moves
|
||||
val moves = counter.next()
|
||||
this.lastMoves = moves
|
||||
// figure out the first index that differs
|
||||
val lastModifiedIndex = firstDifferingIndex(previous, moves)
|
||||
// we only need to redo everything starting from the lastoverflowindex
|
||||
// these are our moves, but we can salvage everything up to lastoverflowindex
|
||||
// we have a history to work with... only redo what's necessary
|
||||
for (i in lastModifiedIndex until moves.size) {
|
||||
var start: EdgeModel = if (i == 0)
|
||||
original
|
||||
else
|
||||
history[i - 1]
|
||||
history[i] = start.doMove(moves[i])
|
||||
}
|
||||
// bump the previous value
|
||||
previous = moves
|
||||
// the last item in the history is now the edgemodel we need to test...
|
||||
return history.last()
|
||||
}
|
||||
|
||||
private fun firstDifferingIndex(previous: IntArray, moves: IntArray): Int {
|
||||
previous.forEachIndexed { index, i ->
|
||||
if(previous[index] != moves[index])
|
||||
return index
|
||||
}
|
||||
// nothing changed.. that's probably impossible
|
||||
throw IllegalStateException()
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,5 @@
|
||||
package be.nielandt.iterator
|
||||
|
||||
import be.nielandt.decodeMove
|
||||
|
||||
class ValidClassMoveIterator(val size: Int) : Iterator<IntArray> {
|
||||
|
||||
// current level of the iterator
|
||||
|
||||
Loading…
Reference in New Issue
Block a user