ok, let's try and improve the skip solution
This commit is contained in:
parent
af89c48970
commit
60b2b3bb1a
@ -5,29 +5,25 @@ import kotlin.math.min
|
|||||||
/**
|
/**
|
||||||
* Counter for X digits of a given base.
|
* Counter for X digits of a given base.
|
||||||
*/
|
*/
|
||||||
class Counter(size: Int, val base: Int = 10) {
|
open class Counter(size: Int, val base: Int = 10) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Empty counter, all 0 values for each digit.
|
* Empty counter, all 0 values for each digit.
|
||||||
*/
|
*/
|
||||||
private var counter: Array<Int> = Array(size) { 0 }
|
protected var counter: Array<Int> = Array(size) { 0 }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The last (highest significance) index that overflowed and has been changed in the counter. Could be null, if it never overflowed.
|
* The last (highest significance) index that overflowed and has been changed in the counter. Could be null, if it never overflowed.
|
||||||
* Start with saying that everything changed.
|
* Start with saying that everything changed.
|
||||||
*/
|
*/
|
||||||
private var lastModifiedIndex: Int = 0
|
var lastModifiedIndex: Int = 0
|
||||||
|
|
||||||
fun getLastModifiedIndex(): Int {
|
|
||||||
return this.lastModifiedIndex
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increase the counter.
|
* Increase the counter.
|
||||||
*
|
*
|
||||||
* @return true if the increase happened, false if we hit the ceiling.
|
* @return true if the increase happened, false if we hit the ceiling.
|
||||||
*/
|
*/
|
||||||
fun increase(): Boolean {
|
open fun increase(): Boolean {
|
||||||
if (atMax()) {
|
if (atMax()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
41
src/main/kotlin/be/nielandt/CounterSkipSameFaces.kt
Normal file
41
src/main/kotlin/be/nielandt/CounterSkipSameFaces.kt
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package be.nielandt
|
||||||
|
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counter for X digits of a given base. Skips situations where faces are the same.
|
||||||
|
*/
|
||||||
|
class CounterSkipSameFaces(size: Int, base: Int = 10): Counter(size, base) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increase the counter.
|
||||||
|
*
|
||||||
|
* @return true if the increase happened, false if we hit the ceiling.
|
||||||
|
*/
|
||||||
|
override fun increase(): Boolean {
|
||||||
|
var lmi = lastModifiedIndex
|
||||||
|
var last = super.increase()
|
||||||
|
lmi = min(lastModifiedIndex, lmi)
|
||||||
|
// are we having an invalid situation? this would be two consecutive moves on the same face
|
||||||
|
while (containsConsecutiveSameFaceMoves() && !atMax()) {
|
||||||
|
last = super.increase()
|
||||||
|
lmi = min(lastModifiedIndex, lmi)
|
||||||
|
}
|
||||||
|
// we have to set the lastmodified index to the lowest point that it got to... otherwise we might be skipping some cases
|
||||||
|
this.lastModifiedIndex = lmi
|
||||||
|
return last
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Are there two moves in the current counter / chain that act on the same face? This would be F+F2 for example.
|
||||||
|
*/
|
||||||
|
private fun containsConsecutiveSameFaceMoves(): Boolean {
|
||||||
|
for (i in 1 until this.counter.size) {
|
||||||
|
val current = Move.values()[this.counter[i]]
|
||||||
|
val previous = Move.values()[this.counter[i - 1]]
|
||||||
|
if (current sameFace previous)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -67,17 +67,20 @@ fun main(args: Array<String>) {
|
|||||||
|
|
||||||
|
|
||||||
// scramble random
|
// scramble random
|
||||||
val moves = Move.random(20)
|
val moves = Move.random(10)
|
||||||
println("Scramble: $moves")
|
println("Scramble: $moves")
|
||||||
val scrambledModel = EdgeModel(moves)
|
val scrambledModel = EdgeModel(moves)
|
||||||
println(scrambledModel)
|
println(scrambledModel)
|
||||||
|
|
||||||
val baseSolve = CrossSolverBase().solveCrossesTimed(scrambledModel)
|
// val baseSolve = CrossSolverBase().solveCrossesTimed(scrambledModel)
|
||||||
CrossSolver.printResults(baseSolve)
|
// CrossSolver.printResults(baseSolve)
|
||||||
|
|
||||||
val upgradedSolve = CrossSolverUpgraded().solveCrossesTimed(scrambledModel)
|
val upgradedSolve = CrossSolverUpgraded().solveCrossesTimed(scrambledModel)
|
||||||
CrossSolver.printResults(upgradedSolve)
|
CrossSolver.printResults(upgradedSolve)
|
||||||
|
|
||||||
|
val upgradedSolveSkip = CrossSolverUpgradedSkip().solveCrossesTimed(scrambledModel)
|
||||||
|
CrossSolver.printResults(upgradedSolveSkip)
|
||||||
|
|
||||||
// val allCrossMoveCountUpgradedSkip = allCrossMoveCountUpgradedSkip(scrambledModel)
|
// val allCrossMoveCountUpgradedSkip = allCrossMoveCountUpgradedSkip(scrambledModel)
|
||||||
// allCrossMoveCountUpgradedSkip.forEach { color, moves ->
|
// allCrossMoveCountUpgradedSkip.forEach { color, moves ->
|
||||||
// println("skip upgrade cross for color: ${color} in ${moves.size}: ${moves.joinToString(" ")}")
|
// println("skip upgrade cross for color: ${color} in ${moves.size}: ${moves.joinToString(" ")}")
|
||||||
|
|||||||
@ -1,16 +1,12 @@
|
|||||||
package be.nielandt
|
package be.nielandt
|
||||||
|
|
||||||
import java.time.Instant
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This solver avoids redoing edgemodel manipulations. Should be equivalent to X nested for loops.
|
* This solver avoids redoing edgemodel manipulations. Should be equivalent to X nested for loops.
|
||||||
*/
|
*/
|
||||||
class CrossSolverUpgraded : CrossSolver() {
|
class CrossSolverUpgraded : CrossSolver() {
|
||||||
|
|
||||||
override fun solveCrosses(edgeModel: EdgeModel): Map<Int, List<Move>> {
|
override fun solveCrosses(edgeModel: EdgeModel): Map<Int, List<Move>> {
|
||||||
val start = Instant.now()
|
|
||||||
val moveCounts = mutableMapOf<Int, List<Move>>()
|
val moveCounts = mutableMapOf<Int, List<Move>>()
|
||||||
|
|
||||||
for (moveCount in 1..8) {
|
for (moveCount in 1..8) {
|
||||||
println("all cross move count upgrade doing $moveCount")
|
println("all cross move count upgrade doing $moveCount")
|
||||||
// build a counter of moveCount big
|
// build a counter of moveCount big
|
||||||
|
|||||||
@ -7,16 +7,12 @@ class CrossSolverUpgradedSkip : CrossSolver() {
|
|||||||
|
|
||||||
override fun solveCrosses(edgeModel: EdgeModel): Map<Int, List<Move>> {
|
override fun solveCrosses(edgeModel: EdgeModel): Map<Int, List<Move>> {
|
||||||
val moveCounts = mutableMapOf<Int, List<Move>>()
|
val moveCounts = mutableMapOf<Int, List<Move>>()
|
||||||
|
|
||||||
for (moveCount in 1..8) {
|
for (moveCount in 1..8) {
|
||||||
println("all cross move count upgrade doing $moveCount")
|
println("all cross move count upgrade doing $moveCount")
|
||||||
// build a counter of moveCount big
|
// build a counter of moveCount big
|
||||||
val counter = Counter(moveCount, Move.values().size)
|
val counter = CounterSkipSameFaces(moveCount, Move.values().size)
|
||||||
// TODO skip the counter
|
|
||||||
val edgeModelFactory = EdgeModelFactory(edgeModel, counter)
|
val edgeModelFactory = EdgeModelFactory(edgeModel, counter)
|
||||||
|
|
||||||
println("moveCounts = ${moveCounts}")
|
|
||||||
|
|
||||||
while (edgeModelFactory.hasNext()) {
|
while (edgeModelFactory.hasNext()) {
|
||||||
// get the next model, using the internal counter which simply iterates over possible combinations of moves
|
// get the next model, using the internal counter which simply iterates over possible combinations of moves
|
||||||
val next = edgeModelFactory.getNext()
|
val next = edgeModelFactory.getNext()
|
||||||
@ -34,7 +30,6 @@ class CrossSolverUpgradedSkip : CrossSolver() {
|
|||||||
}
|
}
|
||||||
// break if we have found hem all
|
// break if we have found hem all
|
||||||
if (moveCounts.keys.size == 6) {
|
if (moveCounts.keys.size == 6) {
|
||||||
// println("counter.skipInvalidCount = ${counter.skipInvalidCount}")
|
|
||||||
return moveCounts
|
return moveCounts
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,12 +28,12 @@ class EdgeModelFactory(val original: EdgeModel, val counter: Counter) {
|
|||||||
|
|
||||||
fun getNext(): EdgeModel {
|
fun getNext(): EdgeModel {
|
||||||
// the counter was increased, hooray
|
// the counter was increased, hooray
|
||||||
val lastOverflowIndex = counter.getLastModifiedIndex()
|
val lastOverflowIndex = counter.lastModifiedIndex
|
||||||
// we only need to redo everything starting from the lastoverflowindex
|
// we only need to redo everything starting from the lastoverflowindex
|
||||||
// these are our moves, but we can salvage everything up to lastoverflowindex
|
// these are our moves, but we can salvage everything up to lastoverflowindex
|
||||||
val moves = Move.combo(counter)
|
val moves = Move.combo(counter)
|
||||||
// we have a history to work with... only redo what's necessary
|
// we have a history to work with... only redo what's necessary
|
||||||
for (i in counter.getLastModifiedIndex() until counter.size()) {
|
for (i in counter.lastModifiedIndex until counter.size()) {
|
||||||
var start: EdgeModel = if (i == 0)
|
var start: EdgeModel = if (i == 0)
|
||||||
original
|
original
|
||||||
else
|
else
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user