added a slower, yet optimized version... hrummm
This commit is contained in:
parent
43578d0b5b
commit
16dfcc33cd
@ -1,5 +1,7 @@
|
|||||||
package be.nielandt
|
package be.nielandt
|
||||||
|
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Counter for X digits of a given base.
|
* Counter for X digits of a given base.
|
||||||
*/
|
*/
|
||||||
@ -42,6 +44,33 @@ class Counter(size: Int, val base: Int = 10) {
|
|||||||
return true
|
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?
|
* How many digits does this counter contain?
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -44,13 +44,17 @@ fun main(args: Array<String>) {
|
|||||||
println(scrambledModel)
|
println(scrambledModel)
|
||||||
|
|
||||||
// doAllCrossMoveCounts(scrambledModel)
|
// doAllCrossMoveCounts(scrambledModel)
|
||||||
val allCrossMoveCount = allCrossMoveCount(scrambledModel)
|
// val allCrossMoveCount = allCrossMoveCount(scrambledModel)
|
||||||
allCrossMoveCount.forEach { color, moves ->
|
// allCrossMoveCount.forEach { color, moves ->
|
||||||
println("cross for color: ${color} in ${moves.size}: ${moves.joinToString(" ")}")
|
// println("cross for color: ${color} in ${moves.size}: ${moves.joinToString(" ")}")
|
||||||
}
|
// }
|
||||||
val allCrossMoveCountUpgraded = allCrossMoveCountUpgraded(scrambledModel)
|
val allCrossMoveCountUpgraded = allCrossMoveCountUpgraded(scrambledModel)
|
||||||
allCrossMoveCount.forEach { color, moves ->
|
allCrossMoveCountUpgraded.forEach { color, moves ->
|
||||||
println("cross for color: ${color} in ${moves.size}: ${moves.joinToString(" ")}")
|
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
|
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'?
|
* 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)
|
val edgeModelFactory = EdgeModelFactory(edgeModel, counter)
|
||||||
|
|
||||||
while (edgeModelFactory.hasNext()) {
|
while (edgeModelFactory.hasNext()) {
|
||||||
|
// get the next model, using the internal counter which simply iterates over possible combinations of moves
|
||||||
val next = edgeModelFactory.getNext()
|
val next = edgeModelFactory.getNext()
|
||||||
|
|
||||||
// check crosses that have not been found yet
|
// check crosses that have not been found yet
|
||||||
Color.values().forEach { color ->
|
Color.values().forEach { color ->
|
||||||
if (!moveCounts.containsKey(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....
|
* 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
|
// keep a modified version of the edgemodel for each digit in the counter, from left to right
|
||||||
private val history: MutableList<EdgeModel> = mutableListOf()
|
private val history: MutableList<EdgeModel> = mutableListOf()
|
||||||
|
|
||||||
@ -161,7 +208,7 @@ class EdgeModelFactory(val original: EdgeModel, val counter: Counter) {
|
|||||||
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.getLastModifiedIndex() until counter.size()) {
|
||||||
var start: EdgeModel? = null
|
var start: EdgeModel?
|
||||||
start = if (i == 0)
|
start = if (i == 0)
|
||||||
original
|
original
|
||||||
else
|
else
|
||||||
@ -169,8 +216,14 @@ class EdgeModelFactory(val original: EdgeModel, val counter: Counter) {
|
|||||||
history[i] = start.doMove(Move.values()[counter.digit(i)])
|
history[i] = start.doMove(Move.values()[counter.digit(i)])
|
||||||
}
|
}
|
||||||
// increase the counter for next time
|
// increase the counter for next time
|
||||||
if (!counter.increase()) {
|
if(!skip) {
|
||||||
this.hasNext = false
|
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...
|
// the last item in the history is now the edgemodel we need to test...
|
||||||
return history.last()
|
return history.last()
|
||||||
@ -186,6 +239,7 @@ fun allCrossMoveCount(edgeModel: EdgeModel): Map<Color, List<Move>> {
|
|||||||
|
|
||||||
for (moveCount in 1..8) {
|
for (moveCount in 1..8) {
|
||||||
// build a counter of moveCount big
|
// build a counter of moveCount big
|
||||||
|
println("allCrossMoveCount basic doing $moveCount")
|
||||||
val counter = Counter(moveCount, Move.values().size)
|
val counter = Counter(moveCount, Move.values().size)
|
||||||
|
|
||||||
// count up, each state of the counter corresponds to a combination of moves
|
// count up, each state of the counter corresponds to a combination of moves
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user