Cross solver iterator seems to be working.

This commit is contained in:
Joachim 2018-08-27 22:31:02 +02:00
parent 9617ed1a02
commit 80179e9b68
13 changed files with 148 additions and 40 deletions

View File

@ -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) }}")

View File

@ -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()
}
}
}

View 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) }}")
}
}

View File

@ -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()
}
}
}

View File

@ -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()
}
}
}

View File

@ -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
}
/**

View File

@ -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)
}
}

View File

@ -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.

View File

@ -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}")
}

View File

@ -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")

View File

@ -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) {

View File

@ -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}")
}

View File

@ -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