Cross solver iterator seems to be working.
This commit is contained in:
parent
9617ed1a02
commit
80179e9b68
@ -7,9 +7,9 @@ open abstract class CrossSolver {
|
|||||||
/**
|
/**
|
||||||
* Solve all crosses, look for a minimal set of moves for each color's cross.
|
* Solve all crosses, look for a minimal set of moves for each color's cross.
|
||||||
*/
|
*/
|
||||||
abstract fun solveCrosses(edgeModel: EdgeModel): Map<Int, List<Int>>
|
abstract fun solveCrosses(edgeModel: EdgeModel): Map<Int, IntArray>
|
||||||
|
|
||||||
fun solveCrossesTimed(edgeModel: EdgeModel): Map<Int, List<Int>> {
|
fun solveCrossesTimed(edgeModel: EdgeModel): Map<Int, IntArray> {
|
||||||
val now = Instant.now()
|
val now = Instant.now()
|
||||||
val solveCrosses = solveCrosses(edgeModel)
|
val solveCrosses = solveCrosses(edgeModel)
|
||||||
val between = Duration.between(now, Instant.now())
|
val between = Duration.between(now, Instant.now())
|
||||||
@ -18,7 +18,7 @@ open abstract class CrossSolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun printResults(results: Map<Int, List<Int>>) {
|
fun printResults(results: Map<Int, IntArray>) {
|
||||||
println("results: ")
|
println("results: ")
|
||||||
results.forEach { color, moveList ->
|
results.forEach { color, moveList ->
|
||||||
println("> color ${colorLetter(color)}, moves (${moveList.size}) ${moveList.map { it -> decodeMove(it) }}")
|
println("> color ${colorLetter(color)}, moves (${moveList.size}) ${moveList.map { it -> decodeMove(it) }}")
|
||||||
|
|||||||
@ -1,14 +1,13 @@
|
|||||||
package be.nielandt
|
package be.nielandt
|
||||||
|
|
||||||
import be.nielandt.counter.CounterBasic
|
|
||||||
import be.nielandt.counter.CounterTieredFactory
|
import be.nielandt.counter.CounterTieredFactory
|
||||||
|
|
||||||
class CrossSolverBase : CrossSolver() {
|
class CrossSolverBase : CrossSolver() {
|
||||||
/**
|
/**
|
||||||
* Solve the minimal cross for all colors.
|
* Solve the minimal cross for all colors.
|
||||||
*/
|
*/
|
||||||
override fun solveCrosses(edgeModel: EdgeModel): Map<Int, List<Int>> {
|
override fun solveCrosses(edgeModel: EdgeModel): Map<Int, IntArray> {
|
||||||
val moveCounts = mutableMapOf<Int, List<Int>>()
|
val moveCounts = mutableMapOf<Int, IntArray>()
|
||||||
|
|
||||||
for (moveCount in 1..8) {
|
for (moveCount in 1..8) {
|
||||||
// build a counter of moveCount big
|
// build a counter of moveCount big
|
||||||
@ -24,7 +23,7 @@ class CrossSolverBase : CrossSolver() {
|
|||||||
if (!moveCounts.containsKey(color)) {
|
if (!moveCounts.containsKey(color)) {
|
||||||
val crossSolved = afterMoves.crossSolved(color)
|
val crossSolved = afterMoves.crossSolved(color)
|
||||||
if (crossSolved) {
|
if (crossSolved) {
|
||||||
moveCounts[color] = counter.counter.toList()
|
moveCounts[color] = counter.counter.copyOf()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
48
src/main/kotlin/be/nielandt/CrossSolverIterator.kt
Normal file
48
src/main/kotlin/be/nielandt/CrossSolverIterator.kt
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package be.nielandt
|
||||||
|
|
||||||
|
import be.nielandt.iterator.ValidClassMoveIterator
|
||||||
|
|
||||||
|
class CrossSolverIterator : CrossSolver() {
|
||||||
|
/**
|
||||||
|
* Solve the minimal cross for all colors.
|
||||||
|
*/
|
||||||
|
override fun solveCrosses(edgeModel: EdgeModel): Map<Int, IntArray> {
|
||||||
|
val moveCounts = mutableMapOf<Int, IntArray>()
|
||||||
|
|
||||||
|
for (moveCount in 1..8) {
|
||||||
|
// build a counter of moveCount big
|
||||||
|
println("crossSolverIterator doing $moveCount")
|
||||||
|
val iterator = ValidClassMoveIterator(moveCount)
|
||||||
|
|
||||||
|
// count up, each state of the counter corresponds to a combination of moves
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
val moves = iterator.next()
|
||||||
|
// execute the moves
|
||||||
|
val afterMoves = edgeModel.doMoves(moves.toList())
|
||||||
|
// check crosses that have not been found yet
|
||||||
|
(0..5).forEach { color ->
|
||||||
|
if (!moveCounts.containsKey(color)) {
|
||||||
|
val crossSolved = afterMoves.crossSolved(color)
|
||||||
|
if (crossSolved) {
|
||||||
|
moveCounts[color] = moves
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (moveCounts.keys.size == 6) {
|
||||||
|
return@solveCrosses moveCounts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return moveCounts
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val start = EdgeModel().doMoves(randomMoves(20))
|
||||||
|
val solver = CrossSolverIterator()
|
||||||
|
val solveCrossesTimed = solver.solveCrossesTimed(start)
|
||||||
|
solveCrossesTimed.forEach { t, u ->
|
||||||
|
println("t $t u ${u.map { decodeMove(it) }}")
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,8 +7,8 @@ import be.nielandt.counter.CounterBasic
|
|||||||
*/
|
*/
|
||||||
class CrossSolverUpgraded : CrossSolver() {
|
class CrossSolverUpgraded : CrossSolver() {
|
||||||
|
|
||||||
override fun solveCrosses(edgeModel: EdgeModel): Map<Int, List<Int>> {
|
override fun solveCrosses(edgeModel: EdgeModel): Map<Int, IntArray> {
|
||||||
val moveCounts = mutableMapOf<Int, List<Int>>()
|
val moveCounts = mutableMapOf<Int, IntArray>()
|
||||||
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
|
||||||
@ -25,7 +25,7 @@ class CrossSolverUpgraded : CrossSolver() {
|
|||||||
val crossSolved = next.crossSolved(color)
|
val crossSolved = next.crossSolved(color)
|
||||||
if (crossSolved) {
|
if (crossSolved) {
|
||||||
// what is the move combination we're looking at?
|
// what is the move combination we're looking at?
|
||||||
moveCounts[color] = counter.counter.toList()
|
moveCounts[color] = counter.counter.copyOf()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,8 +7,8 @@ import be.nielandt.counter.CounterSkip
|
|||||||
*/
|
*/
|
||||||
class CrossSolverUpgradedSkip : CrossSolver() {
|
class CrossSolverUpgradedSkip : CrossSolver() {
|
||||||
|
|
||||||
override fun solveCrosses(edgeModel: EdgeModel): Map<Int, List<Int>> {
|
override fun solveCrosses(edgeModel: EdgeModel): Map<Int, IntArray> {
|
||||||
val moveCounts = mutableMapOf<Int, List<Int>>()
|
val moveCounts = mutableMapOf<Int, IntArray>()
|
||||||
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
|
||||||
@ -25,7 +25,7 @@ class CrossSolverUpgradedSkip : CrossSolver() {
|
|||||||
val crossSolved = next.crossSolved(color)
|
val crossSolved = next.crossSolved(color)
|
||||||
if (crossSolved) {
|
if (crossSolved) {
|
||||||
// what is the move combination we're looking at?
|
// what is the move combination we're looking at?
|
||||||
moveCounts[color] = counter.counter.toList()
|
moveCounts[color] = counter.counter.copyOf()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,8 +57,8 @@ class EdgeModel {
|
|||||||
|
|
||||||
constructor(randomMoves: Int) {
|
constructor(randomMoves: Int) {
|
||||||
val edgeModel = EdgeModel()
|
val edgeModel = EdgeModel()
|
||||||
val r: Array<Int> = randomMoves(randomMoves)
|
val r: IntArray = randomMoves(randomMoves)
|
||||||
val doMoves = edgeModel.doMoves(r)
|
val doMoves = edgeModel.doMoves(r.toList())
|
||||||
this.model = doMoves.model
|
this.model = doMoves.model
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,14 +171,6 @@ class EdgeModel {
|
|||||||
return trimMargin
|
return trimMargin
|
||||||
}
|
}
|
||||||
|
|
||||||
fun doMoves(f: Array<Int>) : EdgeModel {
|
|
||||||
var edgeModel = this
|
|
||||||
f.forEach {
|
|
||||||
edgeModel = edgeModel.doMove(it)
|
|
||||||
}
|
|
||||||
return edgeModel
|
|
||||||
}
|
|
||||||
|
|
||||||
fun doMoves(f: Collection<Int>): EdgeModel {
|
fun doMoves(f: Collection<Int>): EdgeModel {
|
||||||
var edgeModel = this
|
var edgeModel = this
|
||||||
f.forEach {
|
f.forEach {
|
||||||
@ -187,8 +179,12 @@ class EdgeModel {
|
|||||||
return edgeModel
|
return edgeModel
|
||||||
}
|
}
|
||||||
|
|
||||||
fun doMoves(vararg f: Int): EdgeModel {
|
fun doMoves(f: IntArray): EdgeModel {
|
||||||
return this.doMoves(f.toList())
|
var edgeModel = this
|
||||||
|
f.forEach {
|
||||||
|
edgeModel = edgeModel.doMove(it)
|
||||||
|
}
|
||||||
|
return edgeModel
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -91,9 +91,9 @@ fun parseMove(s: String): Int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun randomMoves(amount: Int): Array<Int> {
|
fun randomMoves(amount: Int): IntArray {
|
||||||
val rgen = Random()
|
val rgen = Random()
|
||||||
return Array(amount) {
|
return IntArray(amount) {
|
||||||
rgen.nextInt(18)
|
rgen.nextInt(18)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ open abstract class Counter(size: Int, val base: Int = 18) {
|
|||||||
/**
|
/**
|
||||||
* Empty counter, all 0 values for each digit.
|
* Empty counter, all 0 values for each digit.
|
||||||
*/
|
*/
|
||||||
var counter: Array<Int> = Array(size) { 0 }
|
var counter: IntArray = IntArray(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.
|
||||||
|
|||||||
@ -61,3 +61,12 @@ class CounterBasic(size: Int) : Counter(size, 18) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val counterBasic = CounterBasic(7)
|
||||||
|
var count = 0
|
||||||
|
while(counterBasic.increase())
|
||||||
|
count++
|
||||||
|
println("count = ${count}")
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -7,14 +7,14 @@ import be.nielandt.classOf
|
|||||||
*/
|
*/
|
||||||
class CounterBuffer(size: Int) : Counter(size, 18) {
|
class CounterBuffer(size: Int) : Counter(size, 18) {
|
||||||
|
|
||||||
val buffer = mutableListOf<Array<Int>>()
|
val buffer = mutableListOf<IntArray>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
// initialise the buffer of valid counters
|
// initialise the buffer of valid counters
|
||||||
val counterBasic = CounterBasic(size)
|
val counterBasic = CounterBasic(size)
|
||||||
do {
|
do {
|
||||||
if (counterBasic.isValid()) {
|
if (counterBasic.isValid()) {
|
||||||
buffer.add(counterBasic.counter)
|
buffer.add(counterBasic.counter.copyOf())
|
||||||
}
|
}
|
||||||
} while (counterBasic.increase())
|
} while (counterBasic.increase())
|
||||||
println("Init of counter buffer, ${buffer.size} valid combos")
|
println("Init of counter buffer, ${buffer.size} valid combos")
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import be.nielandt.decodeMove
|
|||||||
*/
|
*/
|
||||||
class CounterTiered : Counter(8) {
|
class CounterTiered : Counter(8) {
|
||||||
|
|
||||||
private val moveIterator: Iterator<Array<Int>> = listOf<Array<Int>>().iterator()
|
private val moveIterator: Iterator<IntArray> = listOf<IntArray>().iterator()
|
||||||
|
|
||||||
override fun increase(): Boolean {
|
override fun increase(): Boolean {
|
||||||
if (!this.moveIterator.hasNext())
|
if (!this.moveIterator.hasNext())
|
||||||
@ -22,10 +22,10 @@ class CounterTiered : Counter(8) {
|
|||||||
return !this.moveIterator.hasNext()
|
return !this.moveIterator.hasNext()
|
||||||
}
|
}
|
||||||
|
|
||||||
private class MoveIterator(val classes: List<List<Int>>) : Iterator<Array<Int>> {
|
private class MoveIterator(val classes: List<IntArray>) : Iterator<IntArray> {
|
||||||
|
|
||||||
var currentClassIndex = 0
|
var currentClassIndex = 0
|
||||||
lateinit var currentMoves: Iterator<Array<Int>>
|
lateinit var currentMoves: Iterator<IntArray>
|
||||||
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -34,11 +34,11 @@ class CounterTiered : Counter(8) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun doClass(index: Int) {
|
private fun doClass(index: Int) {
|
||||||
val fillIn = fillIn(0, classes[index], Array(classes.size) { 0 })
|
val fillIn = fillIn(0, classes[index], IntArray(classes.size) { 0 })
|
||||||
currentMoves = fillIn.toList().iterator()
|
currentMoves = fillIn.toList().iterator()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun next(): Array<Int> {
|
override fun next(): IntArray {
|
||||||
val next = currentMoves.next()
|
val next = currentMoves.next()
|
||||||
if (!currentMoves.hasNext()) {
|
if (!currentMoves.hasNext()) {
|
||||||
nextClass()
|
nextClass()
|
||||||
@ -97,8 +97,8 @@ const val D2 = 15
|
|||||||
const val L2 = 16
|
const val L2 = 16
|
||||||
const val R2 = 17
|
const val R2 = 17
|
||||||
*/
|
*/
|
||||||
fun fillIn(index: Int, classes: List<Int>, moveList: Array<Int>): List<Array<Int>> {
|
fun fillIn(index: Int, classes: IntArray, moveList: IntArray): List<IntArray> {
|
||||||
val result = mutableListOf<Array<Int>>()
|
val result = mutableListOf<IntArray>()
|
||||||
|
|
||||||
// if the movelist is complete, finish it
|
// if the movelist is complete, finish it
|
||||||
if (index == classes.size) {
|
if (index == classes.size) {
|
||||||
|
|||||||
@ -0,0 +1,57 @@
|
|||||||
|
package be.nielandt.iterator
|
||||||
|
|
||||||
|
import be.nielandt.decodeMove
|
||||||
|
|
||||||
|
class ValidClassMoveIterator(val size: Int) : Iterator<IntArray> {
|
||||||
|
|
||||||
|
// current level of the iterator
|
||||||
|
var classesIterator = ValidClassesIterator(size)
|
||||||
|
var movesIterator: ValidMoveIterator
|
||||||
|
|
||||||
|
init {
|
||||||
|
this.movesIterator = ValidMoveIterator(classesIterator.next())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hasNext(): Boolean {
|
||||||
|
// check if we have another move in the move iterator
|
||||||
|
return if (this.movesIterator.hasNext()) {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
// the moves iterator does not has any more juice, move to the next class
|
||||||
|
if (!this.classesIterator.hasNext()) {
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
nextClass()
|
||||||
|
this.movesIterator.hasNext()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun next(): IntArray {
|
||||||
|
// check if there's a valid move left
|
||||||
|
if (!this.movesIterator.hasNext()) {
|
||||||
|
nextClass()
|
||||||
|
}
|
||||||
|
// now we're sure there's something left
|
||||||
|
return this.movesIterator.next()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bump the 'current class'. This means we have a new moves iterator at our disposal.
|
||||||
|
*/
|
||||||
|
private fun nextClass() {
|
||||||
|
val next = this.classesIterator.next()
|
||||||
|
this.movesIterator = ValidMoveIterator(next)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val validClassMoveIterator = ValidClassMoveIterator(8)
|
||||||
|
var count=0
|
||||||
|
while (validClassMoveIterator.hasNext()) {
|
||||||
|
validClassMoveIterator.next()
|
||||||
|
// println("Arrays.toString(validClassMoveIterator.next()) = ${validClassMoveIterator.next().map { decodeMove(it) }}")
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
println("count = ${count}")
|
||||||
|
}
|
||||||
@ -19,7 +19,7 @@ class ValidMoveIterator(val classes: List<Int>) : Iterator<IntArray> {
|
|||||||
// create the variable counter: if a class is 'alone', it can iterate over all 6 values. otherwise, each part can iterate over 3
|
// create the variable counter: if a class is 'alone', it can iterate over all 6 values. otherwise, each part can iterate over 3
|
||||||
val intArray = IntArray(classes.size)
|
val intArray = IntArray(classes.size)
|
||||||
var i = 0
|
var i = 0
|
||||||
while (i < classes.size - 1) {
|
while (i < classes.size) {
|
||||||
if (i < classes.size - 1 && classes[i] == classes[i + 1]) {
|
if (i < classes.size - 1 && classes[i] == classes[i + 1]) {
|
||||||
intArray[i] = 3
|
intArray[i] = 3
|
||||||
intArray[i + 1] = 3
|
intArray[i + 1] = 3
|
||||||
@ -36,12 +36,11 @@ class ValidMoveIterator(val classes: List<Int>) : Iterator<IntArray> {
|
|||||||
|
|
||||||
override fun next(): IntArray {
|
override fun next(): IntArray {
|
||||||
val next = this.expansionCounter.next()
|
val next = this.expansionCounter.next()
|
||||||
println("Expansioncounter next = ${Arrays.toString(next)}")
|
|
||||||
// translate this state into a list of moves
|
// translate this state into a list of moves
|
||||||
var i = 0
|
var i = 0
|
||||||
while (i < next.size) {
|
while (i < next.size) {
|
||||||
// process the double situation
|
// process the double situation
|
||||||
if (classes[i] == classes[i + 1]) {
|
if (i < classes.size-1 && classes[i] == classes[i + 1]) {
|
||||||
// so, we're in the same state, the first counter will get the 'low' value, the second the 'high' value
|
// so, we're in the same state, the first counter will get the 'low' value, the second the 'high' value
|
||||||
// for class FB, that would be F and B respectively
|
// for class FB, that would be F and B respectively
|
||||||
// class 0 (FB) has to expand to 0,6,12 (F,F_F2) and 1,7,13 (B,B_,B2) respectively
|
// class 0 (FB) has to expand to 0,6,12 (F,F_F2) and 1,7,13 (B,B_,B2) respectively
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user