作为数独生成器的一部分,我有一个函数用于过滤嵌套列表,以便仅返回某些索引的内部列表和这些列表中某些索引的内部列表元素。我们的想法是返回一个List [Int],它包含一个3x3平方的值,取自一个9x9数独谜题,表示为List [List [Int]],它作为函数的参数提供。
我尝试了两种方法,但未能始终如一地工作。一种方法尝试从列表中过滤掉某些子列表,然后从剩余列表中过滤掉项目。此函数完全适用于某些索引,但对于其他索引,它将从某些子列表中过滤太多或太少的索引值,但不是全部:
def getGroup(indexX: Int, indexY: Int, puzzle: List[List[Int]]): List[Int] = {
val groupX = { //determining row coordinate
if(indexX <= 2) 2
else if(indexX <= 5) 5
else 8
}
val groupY = { //determining column coordinate
if(indexY <= 2) 2
else if(indexY <= 5) 5
else 8
}
// Using filter
val subsection: List[List[Int]] = puzzle.filter(x => puzzle.indexOf(x) <= groupX && puzzle.indexOf(x) >= groupX - 2)
// This sometimes filters out too many or too few items
val group: List[List[Int]] = subsection.map(x => x.filter(y => x.indexOf(y) <= groupY && x.indexOf(y) >= groupY - 2))
val result = group.flatten
println("subsection " + subsection)
println("group " + group)
result
}
以下是测试列表[List [Int]]的一些输出,打印时显示结果。我不清楚为什么从一些子列表中过滤掉不正确的索引,而不是在同一个函数调用中过滤掉所有索引。我不认为我只是选择了错误的索引,否则对于同一函数调用中的所有子列表,它应该以相同的方式不正确。
test: List[List[Int]] = List(List(0, 2, 3, 4, 5, 6, 7, 8, 9), List(1, 2, 3, 4, 5, 6, 7, 8, 9), List(2, 2, 3, 4, 5, 6, 7, 8, 9), List(3, 2, 3, 4, 5, 6, 7, 8, 9), List(4, 2, 3, 4, 5, 6, 7, 8, 9), List(5, 2, 3, 4, 5, 6, 7, 8, 9), List(6, 2, 3, 4, 5, 6, 7, 8, 9), List(7, 2, 3, 4, 5, 6, 7, 8, 9), List(8, 2, 3, 4, 5, 6, 7, 8, 9))
scala> getGroup(2,2,test)
subsection: List(List(0, 2, 3, 4, 5, 6, 7, 8, 9), List(1, 2, 3, 4, 5, 6, 7, 8, 9), List(2, 2, 3, 4, 5, 6, 7, 8, 9))
group: List(List(0, 2, 3), List(1, 2, 3), List(2, 2, 3))
res12: List[Int] = List(0, 2, 3, 1, 2, 3, 2, 2, 3) //Correct
scala> getGroup(2,7,test)
subsection: List(List(0, 2, 3, 4, 5, 6, 7, 8, 9), List(1, 2, 3, 4, 5, 6, 7, 8, 9), List(2, 2, 3, 4, 5, 6, 7, 8, 9))
group: List(List(7, 8, 9), List(7, 8, 9), List(7, 8, 9))
res13: List[Int] = List(7, 8, 9, 7, 8, 9, 7, 8, 9) //Correct
scala> getGroup(7,7,test)
subsection: List(List(6, 2, 3, 4, 5, 6, 7, 8, 9), List(7, 2, 3, 4, 5, 6, 7, 8, 9), List(8, 2, 3, 4, 5, 6, 7, 8, 9))
group: List(List(7, 8, 9), List(8, 9), List(7, 9)) //Missing a 7 and an 8
res14: List[Int] = List(7, 8, 9, 8, 9, 7, 9)
scala> getGroup(4,0,test)
subsection: List(List(3, 2, 3, 4, 5, 6, 7, 8, 9), List(4, 2, 3, 4, 5, 6, 7, 8, 9), List(5, 2, 3, 4, 5, 6, 7, 8, 9))
group: List(List(3, 2, 3), List(4, 2, 3, 4), List(5, 2, 3, 5)) //Not enough values filtered out--unwanted 4 and 5
res32: List[Int] = List(3, 2, 3, 4, 2, 3, 4, 5, 2, 3, 5)
另一种方法使用for循环,它只会产生符合if条件的值:
def getGroup(indexX: Int, indexY: Int, puzzle: List[List[Int]]): List[Int] = {
//this portion is the same as above until the for expression:
val groupX = { //determining row coordinate
if(indexX <= 2) 2
else if(indexX <= 5) 5
else 8
}
val groupY = { //determining column coordinate
if(indexY <= 2) 2
else if(indexY <= 5) 5
else 8
}
// using for expression
val group = for(
outer <- puzzle if puzzle.indexOf(outer) <= groupX && puzzle.indexOf(outer) >= groupX - 2;
inner <- outer if outer.indexOf(inner) <= groupY && outer.indexOf(inner) >= groupY - 2)
yield inner
group
}
我已使用此List [List [Int]]测试了此函数,其中每个列表都以其索引号开头,之后才计数:
val testGrid = List(List(0,2,3,4,5,6,7,8,9),List(1,2,3,4,5,6,7,8,9),List(2,2,3,4,5,6,7,8,9),
List(3,2,3,4,5,6,7,8,9),List(4,2,3,4,5,6,7,8,9),List(5,2,3,4,5,6,7,8,9),
List(6,2,3,4,5,6,7,8,9),List(7,2,3,4,5,6,7,8,9),List(8,2,3,4,5,6,7,8,9))
但是,输出并不总是正确的:
scala> getGroup(0, 0, testGrid)
res0: List[Int] = List(0, 2, 3, 1, 2, 3, 2, 2, 3) (correct)
scala> getGroup(3,3,testGrid)
res1: List[Int] = List(4, 5, 6, 5, 6, 4, 6) (too few)
scala> getGroup(3,7,testGrid)
res2: List[Int] = List(7, 8, 9, 7, 8, 9, 7, 8, 9) (correct)
scala> getGroup(7,7,testGrid)
res3: List[Int] = List(7, 8, 9, 8, 9, 7, 9) (too few)
scala> getGroup(7,0,testGrid)
res5: List[Int] = List(6, 2, 3, 6, 7, 2, 3, 7, 8, 2, 3, 8) (too many)
为什么我得到这个输出可能有一个明显的答案,但它已经逃脱了我。我怀疑它与内部循环有关,因为indexY低于3的所有测试都是正确的,无论indexX的值如何。
我将不胜感激任何有关这些尝试的反馈。我也很感激任何关于替代方法的想法,这种方法可以使这个功能更直观或更简洁。
答案 0 :(得分:1)
您可以使用.slice
按索引过滤列表的某个部分。然后.map(x => x.slice(...))
对内部列表执行相同操作,最后.flatten
将List[List[A]]
转换为List[A]
。一起来:
def getGroup(indexX: Int, indexY: Int, puzzle: List[List[Int]]): List[Int] = {
val xStart = indexX / 3 * 3
val yStart = indexY / 3 * 3
puzzle.slice(xStart, xStart + 3).map(row => row.slice(yStart, yStart + 3)).flatten
}