added a slower, yet optimized version... hrummm

This commit is contained in:
Joachim 2018-08-24 23:14:07 +02:00
parent 43578d0b5b
commit 16dfcc33cd
2 changed files with 93 additions and 10 deletions

View File

@ -1,5 +1,7 @@
package be.nielandt
import kotlin.math.min
/**
* Counter for X digits of a given base.
*/
@ -42,6 +44,33 @@ class Counter(size: Int, val base: Int = 10) {
return true
}
fun increaseAndSkipInvalid(): Boolean {
var lmi = lastModifiedIndex
var last = 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 = 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
}
/**
* How many digits does this counter contain?
*/

View File

@ -44,13 +44,17 @@ fun main(args: Array<String>) {
println(scrambledModel)
// doAllCrossMoveCounts(scrambledModel)
val allCrossMoveCount = allCrossMoveCount(scrambledModel)
allCrossMoveCount.forEach { color, moves ->
println("cross for color: ${color} in ${moves.size}: ${moves.joinToString(" ")}")
}
// val allCrossMoveCount = allCrossMoveCount(scrambledModel)
// allCrossMoveCount.forEach { color, moves ->
// println("cross for color: ${color} in ${moves.size}: ${moves.joinToString(" ")}")
// }
val allCrossMoveCountUpgraded = allCrossMoveCountUpgraded(scrambledModel)
allCrossMoveCount.forEach { color, moves ->
println("cross for color: ${color} in ${moves.size}: ${moves.joinToString(" ")}")
allCrossMoveCountUpgraded.forEach { color, moves ->
println("upgrade cross for color: ${color} in ${moves.size}: ${moves.joinToString(" ")}")
}
val allCrossMoveCountUpgradedSkip = allCrossMoveCountUpgradedSkip(scrambledModel)
allCrossMoveCountUpgradedSkip.forEach { color, moves ->
println("skip upgrade cross for color: ${color} in ${moves.size}: ${moves.joinToString(" ")}")
}
}
@ -90,6 +94,47 @@ fun crossMoveCount(edgeModel: EdgeModel, color: Color): List<Move>? {
return null
}
/**
* Solve the minimal cross for all colors. Try to upgrade the method... Can we cache the 'previous results'?
*/
fun allCrossMoveCountUpgradedSkip(edgeModel: EdgeModel): Map<Color, List<Move>> {
val start = Instant.now()
val moveCounts = mutableMapOf<Color, List<Move>>()
for (moveCount in 1..8) {
println("all cross move count upgrade doing $moveCount")
// build a counter of moveCount big
val counter = Counter(moveCount, Move.values().size)
val edgeModelFactory = EdgeModelFactory(edgeModel, counter, true)
println("moveCounts = ${moveCounts}")
while (edgeModelFactory.hasNext()) {
// get the next model, using the internal counter which simply iterates over possible combinations of moves
val next = edgeModelFactory.getNext()
// check crosses that have not been found yet
Color.values().forEach { color ->
if (!moveCounts.containsKey(color)) {
val crossSolved = next.crossSolved(color)
if (crossSolved) {
// what is the move combination we're looking at?
val moves = Move.combo(counter)
moveCounts[color] = moves
}
}
}
// break if we have found hem all
if (moveCounts.keys.size == Color.values().size) {
println("Execution time: ${Duration.between(start, Instant.now()).toMillis() / 1000}s")
// println("counter.skipInvalidCount = ${counter.skipInvalidCount}")
return moveCounts
}
}
}
println("Execution time: ${Duration.between(start, Instant.now()).toMillis() / 1000}s")
return moveCounts
}
/**
* Solve the minimal cross for all colors. Try to upgrade the method... Can we cache the 'previous results'?
*/
@ -104,7 +149,9 @@ fun allCrossMoveCountUpgraded(edgeModel: EdgeModel): Map<Color, List<Move>> {
val edgeModelFactory = EdgeModelFactory(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()
// check crosses that have not been found yet
Color.values().forEach { color ->
if (!moveCounts.containsKey(color)) {
@ -134,7 +181,7 @@ fun allCrossMoveCountUpgraded(edgeModel: EdgeModel): Map<Color, List<Move>> {
*
* This is probably equivalent to 8 nested for loops, you'd be able to keep track of temporary solutions there too....
*/
class EdgeModelFactory(val original: EdgeModel, val counter: Counter) {
class EdgeModelFactory(val original: EdgeModel, val counter: Counter, val skip: Boolean = false) {
// keep a modified version of the edgemodel for each digit in the counter, from left to right
private val history: MutableList<EdgeModel> = mutableListOf()
@ -161,7 +208,7 @@ class EdgeModelFactory(val original: EdgeModel, val counter: Counter) {
val moves = Move.combo(counter)
// we have a history to work with... only redo what's necessary
for (i in counter.getLastModifiedIndex() until counter.size()) {
var start: EdgeModel? = null
var start: EdgeModel?
start = if (i == 0)
original
else
@ -169,9 +216,15 @@ class EdgeModelFactory(val original: EdgeModel, val counter: Counter) {
history[i] = start.doMove(Move.values()[counter.digit(i)])
}
// increase the counter for next time
if(!skip) {
if (!counter.increase()) {
this.hasNext = false
}
} else {
if (!counter.increaseAndSkipInvalid()) {
this.hasNext = false
}
}
// the last item in the history is now the edgemodel we need to test...
return history.last()
}
@ -186,6 +239,7 @@ fun allCrossMoveCount(edgeModel: EdgeModel): Map<Color, List<Move>> {
for (moveCount in 1..8) {
// build a counter of moveCount big
println("allCrossMoveCount basic doing $moveCount")
val counter = Counter(moveCount, Move.values().size)
// count up, each state of the counter corresponds to a combination of moves