Skip to content

Commit

Permalink
Uses Set<IntArray> instead of List<IntArray> to represent possible co…
Browse files Browse the repository at this point in the history
…mbinations
  • Loading branch information
meikpiep committed Jan 2, 2025
1 parent d6438fc commit 18bb29f
Show file tree
Hide file tree
Showing 13 changed files with 112 additions and 110 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@ class GridSingleCageCreator(
) {
val id = cage.id

val possibleCombinations: List<IntArray> by lazy {
val possibleCombinations: Set<IntArray> by lazy {
if (variant.options.showOperators) {
possibleCombinations()
} else {
possibleCombinationsNoOperator()
}
}

private fun possibleCombinationsNoOperator(): List<IntArray> {
private fun possibleCombinationsNoOperator(): Set<IntArray> {
if (cage.numberOfCells == 1) {
val number = intArrayOf(cage.result)
return listOf(number)
return setOf(number)
}
if (cage.numberOfCells == 2) {
return possibleNumsNoOperatorTwoCells()
Expand All @@ -53,10 +53,10 @@ class GridSingleCageCreator(
allResults.add(possibleset)
}
}
return allResults
return allResults.toSet()
}

private fun possibleNumsNoOperatorTwoCells(): List<IntArray> {
private fun possibleNumsNoOperatorTwoCells(): Set<IntArray> {
val allResults = mutableListOf<IntArray>()

for (i1 in variant.possibleDigits) {
Expand All @@ -77,12 +77,12 @@ class GridSingleCageCreator(
}
}

return allResults.toList()
return allResults.toSet()
}

private fun possibleCombinations(): List<IntArray> =
private fun possibleCombinations(): Set<IntArray> =
when (cage.action) {
GridCageAction.ACTION_NONE -> listOf(intArrayOf(cage.result))
GridCageAction.ACTION_NONE -> setOf(intArrayOf(cage.result))
GridCageAction.ACTION_SUBTRACT -> SubtractionCreator(variant, cage.result).create()
GridCageAction.ACTION_DIVIDE -> DivideCreator(variant, cage.result).create()
GridCageAction.ACTION_ADD -> getalladdcombos(cage.result, cage.numberOfCells)
Expand All @@ -96,12 +96,12 @@ class GridSingleCageCreator(
private fun getalladdcombos(
targetSum: Int,
numberOfCells: Int,
): List<IntArray> = AdditionCreator(this, variant, targetSum, numberOfCells).create()
): Set<IntArray> = AdditionCreator(this, variant, targetSum, numberOfCells).create()

private fun getallmultcombos(
targetSum: Int,
numberOfCells: Int,
): List<IntArray> = MultiplicationCreator(cage, variant, targetSum, numberOfCells).create()
): Set<IntArray> = MultiplicationCreator(cage, variant, targetSum, numberOfCells).create()

val numberOfCells: Int
get() = cage.numberOfCells
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ class AdditionCreator(
private val numberOfCells: Int,
) {
private val numbers = IntArray(numberOfCells)
private val possibleCombinations = ArrayList<IntArray>()
private val possibleCombinations = mutableSetOf<IntArray>()

fun create(): ArrayList<IntArray> {
fun create(): Set<IntArray> {
getaddcombos(targetSum, numberOfCells)

return possibleCombinations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ class DivideCreator(
private val variant: GameVariant,
private val result: Int,
) {
fun create(): List<IntArray> {
val results = mutableListOf<IntArray>()
fun create(): Set<IntArray> {
val results = mutableSetOf<IntArray>()

for (digit in variant.possibleDigits) {
if (result == 0 || digit % result == 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ internal class MultiplicationCreator(
private val targetSum: Int,
private val numberOfCells: Int,
) {
fun create(): List<IntArray> {
return if (targetSum == 0) {
fun create(): Set<IntArray> =
if (targetSum == 0) {
MultiplicationZeroCreator(
cage,
variant.possibleDigits,
Expand All @@ -24,5 +24,4 @@ internal class MultiplicationCreator(
numberOfCells,
).create()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ class MultiplicationNonZeroCreator(
private val numberOfCells: Int,
) {
private var numbers: IntArray = IntArray(numberOfCells)
private var combinations = emptyList<IntArray>()
private var combinations = emptySet<IntArray>()

fun create(): List<IntArray> {
fun create(): Set<IntArray> {
fillCombinations(targetValue, numberOfCells)
return combinations
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ internal class MultiplicationZeroCreator(
private val numberOfCells: Int,
) {
private val numbers: IntArray = IntArray(numberOfCells)
private var combinations = emptyList<IntArray>()
private var combinations = emptySet<IntArray>()

fun create(): List<IntArray> {
fun create(): Set<IntArray> {
fillCombinations(false, numberOfCells)
return combinations
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ class SubtractionCreator(
private val variant: GameVariant,
private val result: Int,
) {
fun create(): List<IntArray> {
val possibles = mutableListOf<IntArray>()
fun create(): Set<IntArray> {
val possibles = mutableSetOf<IntArray>()

for (digit in variant.possibleDigits) {
for (otherDigit in variant.possibleDigits) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class HumanSolverCache(
possiblesCache.validateEntries()
}

fun possibles(cage: GridCage): List<IntArray> = possiblesCache.possibles(cage)
fun possibles(cage: GridCage): Set<IntArray> = possiblesCache.possibles(cage)

fun adjacentlinesWithEachPossibleValue(numberOfLines: Int): Set<GridLines> =
gridinesCache.adjacentlinesWithEachPossibleValue(numberOfLines)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,35 @@ import org.piepmeyer.gauguin.grid.GridCage
internal class PossiblesCache(
private val grid: Grid,
) {
private val cageToPossibles = mutableMapOf<GridCage, List<IntArray>>()
private var cageToPossibles = mapOf<GridCage, Set<IntArray>>()

fun initialize() {
cageToPossibles +=
cageToPossibles =
grid.cages.associateWith {
val creator = GridSingleCageCreator(grid.variant, it)
creator.possibleCombinations
}
}

fun validateEntries() {
cageToPossibles.forEach { (cage, possibles) ->
val possiblesToDelete =
possibles.filterNot {
cage.cells.withIndex().all { cell ->
if (cell.value.isUserValueSet) {
cell.value.userValue == it[cell.index]
} else {
cell.value.possibles.contains(it[cell.index])
}
}
}
cageToPossibles =
cageToPossibles
.map { (cage, possibles) ->
val newPossibles =
possibles
.filter {
cage.cells.withIndex().all { cell ->
if (cell.value.isUserValueSet) {
cell.value.userValue == it[cell.index]
} else {
cell.value.possibles.contains(it[cell.index])
}
}
}.toSet()

if (possiblesToDelete.isNotEmpty()) {
cageToPossibles[cage] = possibles - possiblesToDelete.toSet()
}
}
Pair(cage, newPossibles)
}.toMap()
}

fun possibles(cage: GridCage): List<IntArray> = cageToPossibles[cage]!!
fun possibles(cage: GridCage): Set<IntArray> = cageToPossibles[cage]!!
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import org.piepmeyer.gauguin.grid.GridCage
class PossiblesReducer(
private val cage: GridCage,
) {
fun reduceToPossibleCombinations(possibleCombinations: List<IntArray>): Boolean {
fun reduceToPossibleCombinations(possibleCombinations: Collection<IntArray>): Boolean {
var foundPossibles = false

cage.cells.forEachIndexed { cellIndex, cell ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class DetectPossiblesBreakingOtherCagesPossiblesDualLines : HumanSolverStrategy

private fun calculateDualPossibles(
combination: IntArray,
combinations: List<IntArray>,
combinations: Set<IntArray>,
cage: GridCage,
) = combination
.groupBy { it }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,50 +7,51 @@ import org.piepmeyer.gauguin.options.DigitSetting
import org.piepmeyer.gauguin.options.GameOptionsVariant
import org.piepmeyer.gauguin.options.GameVariant

class TestDivideCreator : FunSpec({
test("allDivideResultsWithoutZero") {
val variant =
GameVariant(
GridSize(4, 4),
GameOptionsVariant.createClassic(),
)

val possibleNums = DivideCreator(variant, 2).create()

possibleNums.size shouldBe 4

possibleNums[0][0] shouldBe 2
possibleNums[0][1] shouldBe 1
possibleNums[1][0] shouldBe 1
possibleNums[1][1] shouldBe 2
possibleNums[2][0] shouldBe 4
possibleNums[2][1] shouldBe 2
possibleNums[3][0] shouldBe 2
possibleNums[3][1] shouldBe 4
}

test("allDivideResultsWithZero") {
val variant =
GameVariant(
GridSize(4, 4),
GameOptionsVariant.createClassic(DigitSetting.FIRST_DIGIT_ZERO),
)

val possibleNums = DivideCreator(variant, 0).create()

possibleNums.size shouldBe 6

possibleNums[0][0] shouldBe 1
possibleNums[0][1] shouldBe 0
possibleNums[1][0] shouldBe 0
possibleNums[1][1] shouldBe 1
possibleNums[2][0] shouldBe 2
possibleNums[2][1] shouldBe 0
possibleNums[3][0] shouldBe 0
possibleNums[3][1] shouldBe 2
possibleNums[4][0] shouldBe 3
possibleNums[4][1] shouldBe 0
possibleNums[5][0] shouldBe 0
possibleNums[5][1] shouldBe 3
}
})
class TestDivideCreator :
FunSpec({
test("allDivideResultsWithoutZero") {
val variant =
GameVariant(
GridSize(4, 4),
GameOptionsVariant.createClassic(),
)

val possibleNums = DivideCreator(variant, 2).create().toList()

possibleNums.size shouldBe 4

possibleNums[0][0] shouldBe 2
possibleNums[0][1] shouldBe 1
possibleNums[1][0] shouldBe 1
possibleNums[1][1] shouldBe 2
possibleNums[2][0] shouldBe 4
possibleNums[2][1] shouldBe 2
possibleNums[3][0] shouldBe 2
possibleNums[3][1] shouldBe 4
}

test("allDivideResultsWithZero") {
val variant =
GameVariant(
GridSize(4, 4),
GameOptionsVariant.createClassic(DigitSetting.FIRST_DIGIT_ZERO),
)

val possibleNums = DivideCreator(variant, 0).create().toList()

possibleNums.size shouldBe 6

possibleNums[0][0] shouldBe 1
possibleNums[0][1] shouldBe 0
possibleNums[1][0] shouldBe 0
possibleNums[1][1] shouldBe 1
possibleNums[2][0] shouldBe 2
possibleNums[2][1] shouldBe 0
possibleNums[3][0] shouldBe 0
possibleNums[3][1] shouldBe 2
possibleNums[4][0] shouldBe 3
possibleNums[4][1] shouldBe 0
possibleNums[5][0] shouldBe 0
possibleNums[5][1] shouldBe 3
}
})
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,26 @@ import org.piepmeyer.gauguin.grid.GridSize
import org.piepmeyer.gauguin.options.GameOptionsVariant
import org.piepmeyer.gauguin.options.GameVariant

class TestSubtractionCreator : FunSpec({
test("allSubtractResults") {
val variant =
GameVariant(
GridSize(4, 4),
GameOptionsVariant.createClassic(),
)
class TestSubtractionCreator :
FunSpec({
test("allSubtractResults") {
val variant =
GameVariant(
GridSize(4, 4),
GameOptionsVariant.createClassic(),
)

val possibleNums = SubtractionCreator(variant, 2).create()
val possibleNums = SubtractionCreator(variant, 2).create().toList()

possibleNums.size shouldBe 4
possibleNums.size shouldBe 4

possibleNums[0][0] shouldBe 1
possibleNums[0][1] shouldBe 3
possibleNums[1][0] shouldBe 2
possibleNums[1][1] shouldBe 4
possibleNums[2][0] shouldBe 3
possibleNums[2][1] shouldBe 1
possibleNums[3][0] shouldBe 4
possibleNums[3][1] shouldBe 2
}
})
possibleNums[0][0] shouldBe 1
possibleNums[0][1] shouldBe 3
possibleNums[1][0] shouldBe 2
possibleNums[1][1] shouldBe 4
possibleNums[2][0] shouldBe 3
possibleNums[2][1] shouldBe 1
possibleNums[3][0] shouldBe 4
possibleNums[3][1] shouldBe 2
}
})

0 comments on commit 18bb29f

Please sign in to comment.