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.
|
||||
*/
|
||||
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 solveCrosses = solveCrosses(edgeModel)
|
||||
val between = Duration.between(now, Instant.now())
|
||||
@ -18,7 +18,7 @@ open abstract class CrossSolver {
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun printResults(results: Map<Int, List<Int>>) {
|
||||
fun printResults(results: Map<Int, IntArray>) {
|
||||
println("results: ")
|
||||
results.forEach { color, moveList ->
|
||||
println("> color ${colorLetter(color)}, moves (${moveList.size}) ${moveList.map { it -> decodeMove(it) }}")
|
||||
|
||||
@ -1,14 +1,13 @@
|
||||
package be.nielandt
|
||||
|
||||
import be.nielandt.counter.CounterBasic
|
||||
import be.nielandt.counter.CounterTieredFactory
|
||||
|
||||
class CrossSolverBase : CrossSolver() {
|
||||
/**
|
||||
* Solve the minimal cross for all colors.
|
||||
*/
|
||||
override fun solveCrosses(edgeModel: EdgeModel): Map<Int, List<Int>> {
|
||||
val moveCounts = mutableMapOf<Int, List<Int>>()
|
||||
override fun solveCrosses(edgeModel: EdgeModel): Map<Int, IntArray> {
|
||||
val moveCounts = mutableMapOf<Int, IntArray>()
|
||||
|
||||
for (moveCount in 1..8) {
|
||||
// build a counter of moveCount big
|
||||
@ -24,7 +23,7 @@ class CrossSolverBase : CrossSolver() {
|
||||
if (!moveCounts.containsKey(color)) {
|
||||
val crossSolved = afterMoves.crossSolved(color)
|
||||
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() {
|
||||
|
||||
override fun solveCrosses(edgeModel: EdgeModel): Map<Int, List<Int>> {
|
||||
val moveCounts = mutableMapOf<Int, List<Int>>()
|
||||
override fun solveCrosses(edgeModel: EdgeModel): Map<Int, IntArray> {
|
||||
val moveCounts = mutableMapOf<Int, IntArray>()
|
||||
for (moveCount in 1..8) {
|
||||
println("all cross move count upgrade doing $moveCount")
|
||||
// build a counter of moveCount big
|
||||
@ -25,7 +25,7 @@ class CrossSolverUpgraded : CrossSolver() {
|
||||
val crossSolved = next.crossSolved(color)
|
||||
if (crossSolved) {
|
||||
// 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() {
|
||||
|
||||
override fun solveCrosses(edgeModel: EdgeModel): Map<Int, List<Int>> {
|
||||
val moveCounts = mutableMapOf<Int, List<Int>>()
|
||||
override fun solveCrosses(edgeModel: EdgeModel): Map<Int, IntArray> {
|
||||
val moveCounts = mutableMapOf<Int, IntArray>()
|
||||
for (moveCount in 1..8) {
|
||||
println("all cross move count upgrade doing $moveCount")
|
||||
// build a counter of moveCount big
|
||||
@ -25,7 +25,7 @@ class CrossSolverUpgradedSkip : CrossSolver() {
|
||||
val crossSolved = next.crossSolved(color)
|
||||
if (crossSolved) {
|
||||
// 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) {
|
||||
val edgeModel = EdgeModel()
|
||||
val r: Array<Int> = randomMoves(randomMoves)
|
||||
val doMoves = edgeModel.doMoves(r)
|
||||
val r: IntArray = randomMoves(randomMoves)
|
||||
val doMoves = edgeModel.doMoves(r.toList())
|
||||
this.model = doMoves.model
|
||||
}
|
||||
|
||||
@ -171,14 +171,6 @@ class EdgeModel {
|
||||
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 {
|
||||
var edgeModel = this
|
||||
f.forEach {
|
||||
@ -187,8 +179,12 @@ class EdgeModel {
|
||||
return edgeModel
|
||||
}
|
||||
|
||||
fun doMoves(vararg f: Int): EdgeModel {
|
||||
return this.doMoves(f.toList())
|
||||
fun doMoves(f: IntArray): EdgeModel {
|
||||
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()
|
||||
return Array(amount) {
|
||||
return IntArray(amount) {
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
|
||||
@ -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) {
|
||||
|
||||
val buffer = mutableListOf<Array<Int>>()
|
||||
val buffer = mutableListOf<IntArray>()
|
||||
|
||||
init {
|
||||
// initialise the buffer of valid counters
|
||||
val counterBasic = CounterBasic(size)
|
||||
do {
|
||||
if (counterBasic.isValid()) {
|
||||
buffer.add(counterBasic.counter)
|
||||
buffer.add(counterBasic.counter.copyOf())
|
||||
}
|
||||
} while (counterBasic.increase())
|
||||
println("Init of counter buffer, ${buffer.size} valid combos")
|
||||
|
||||
@ -9,7 +9,7 @@ import be.nielandt.decodeMove
|
||||
*/
|
||||
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 {
|
||||
if (!this.moveIterator.hasNext())
|
||||
@ -22,10 +22,10 @@ class CounterTiered : Counter(8) {
|
||||
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
|
||||
lateinit var currentMoves: Iterator<Array<Int>>
|
||||
lateinit var currentMoves: Iterator<IntArray>
|
||||
|
||||
|
||||
init {
|
||||
@ -34,11 +34,11 @@ class CounterTiered : Counter(8) {
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
override fun next(): Array<Int> {
|
||||
override fun next(): IntArray {
|
||||
val next = currentMoves.next()
|
||||
if (!currentMoves.hasNext()) {
|
||||
nextClass()
|
||||
@ -97,8 +97,8 @@ const val D2 = 15
|
||||
const val L2 = 16
|
||||
const val R2 = 17
|
||||
*/
|
||||
fun fillIn(index: Int, classes: List<Int>, moveList: Array<Int>): List<Array<Int>> {
|
||||
val result = mutableListOf<Array<Int>>()
|
||||
fun fillIn(index: Int, classes: IntArray, moveList: IntArray): List<IntArray> {
|
||||
val result = mutableListOf<IntArray>()
|
||||
|
||||
// if the movelist is complete, finish it
|
||||
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
|
||||
val intArray = IntArray(classes.size)
|
||||
var i = 0
|
||||
while (i < classes.size - 1) {
|
||||
while (i < classes.size) {
|
||||
if (i < classes.size - 1 && classes[i] == classes[i + 1]) {
|
||||
intArray[i] = 3
|
||||
intArray[i + 1] = 3
|
||||
@ -36,12 +36,11 @@ class ValidMoveIterator(val classes: List<Int>) : Iterator<IntArray> {
|
||||
|
||||
override fun next(): IntArray {
|
||||
val next = this.expansionCounter.next()
|
||||
println("Expansioncounter next = ${Arrays.toString(next)}")
|
||||
// translate this state into a list of moves
|
||||
var i = 0
|
||||
while (i < next.size) {
|
||||
// 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
|
||||
// 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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user