我正尝试在 Haskell 中实现 ThiSTLethwaite 的算法,按照找到的描述 here , 但遇到了困难。
到目前为止,我已经设法表示立方体,让它随心所欲地移动,并将其显示在终端上(二维表示),但是在尝试将通用立方体简化为可以通过组中的移动(R,L,F,B,U2,D2)(如链接中的符号)从标准立方体中获得,因为有太多情况需要考虑:上层有多少种颜色是错误的-oriented,在中间层等等。这只是描述的第一阶段,但我发现我的代码已经乱七八糟了,所以我一定是漏掉了什么。
由于我不确定我上面的描述是否清楚,所以我将相关代码贴在下面,这些代码不正确,但指出问题所在。
--To intersect lists, of which the sizes are not very large, I chose to import the Data.List
import Data.List
--Some type declarations
data Colors = R | B | W | Y | G | O
type R3 = (Int, Int, Int)
type Cube = R3 -> Colors
points :: [R3] --list of coordinates of facelets of a cube; there are 48 of them.
mU :: Cube -> Cube --and other 5 moves.
type Actions = [Cube -> Cube]
turn :: Cube -> Actions -> Cube --chains the actions and turns the cube.
edges :: [R3] --The edges of cubes
criterion :: Colors -> R3 -> Bool -- determine if the edges are mis-placed.
criterion co p@(x, y, z) = case co of --W and Y are up and down faces respectively.
R -> not (or [abs(x) == 3, abs(y) == 3])
B -> not (or [abs(y) == 3, abs(z) == 3])
O -> not (or [abs(x) == 3, abs(y) == 3])
G -> not (or [abs(y) == 3, abs(z) == 3])
_ -> True
stage1 :: Cube -> Cube
stage1 c = turn c opes where
wrongs = do
res <- [[]]
eg <- edges
if criterion (c eg) eg
then res
else res ++ [eg]
ups = filter (\(x, y, z) -> y == 3) points
downs = filter (\(x, y, z) -> y == -3) points
middles = filter (\(x, y, z) -> y == 0) points
opes = do
res <- [[]]
case length (intersect middles wrongs) of
0 -> case [length (intersect ups wrongs) == 0, length (intersect downs wrongs) == 0] of
[True, True] -> res
[True, False] -> [mD] --A quarter turn of the downside of the cube.
[False, True] -> [mU]
_ -> [mD, mU]
1 -> let [(x, y, z)] = intersect middles wrongs in
if x == 3 then case [length (intersect ups wrongs) == 0, length (intersect downs wrongs) == 0] of
[True, True] -> if z > 0 then [mR, mU] else [mR, mD]
[True, False] -> if z > 0 then [mD, mR, mU] else [mD, mR, mD]
[False, True] -> if z > 0 then [mU, mR, mU] else [mU, mR, mD]
_ -> if z > 0 then [mD, mU, mR, mU] else [mD, mU, mR, mD]
else []
然后我意识到上面的代码是错误的,因为我不能简单地转四分之一圈 U 或 D 使正确的边缘(如果有的话)变得不正确,我将根据如何讨论 125 = 5 * 5 * 5 的情况立方体的三层每一层都有很多错误的边缘,我认为这不“正确”。
所以我的问题是如何实现一个可以处理如此多情况的算法,并且以一种很好的方式?
如果有关描述的内容不清楚,请告诉我,以便我可以解释我在做什么以及我的问题是什么。
非常感谢任何想法和建议,非常感谢。
附言我本来想实现 Korf 或 Kociemba 的算法,结果证明我连最简单的情况都无法处理。
最佳答案
一件事——这段代码:
wrongs = do
res <- [[]]
eg <- edges
if criterion (c eg) eg
then res
else res ++ [eg]
最好写成 filter (\eg -> not (criterion (c eg) eg)) edges
。
关于algorithm - 如何在 Haskell 中实现 ThiSTLEthwaite 算法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31583603/