簡體   English   中英

如何在Haskell中實現Thistlethwaite算法?

[英]How to implement the Thistlethwaite's algorithm in Haskell?

我試圖按照此處的描述在Haskell中實現Thistlethwaite的算法,但遇到了困難。

到目前為止,我設法表示了多維數據集,使其隨意移動,並在終端上顯示(二維表示),但是在嘗試將通用多維數據集簡化為可以從中獲得的多維數據集時遇到了問題通過在組(R,L,F,B,U2,D2)中移動來移動標准立方體(如鏈接中的符號所示),因為要考慮的情況太多:上層有多少種顏色方向錯誤,這只是描述的第一步,但是我已經在代碼中發現一團糟,所以我一定錯過了一些東西。

由於我不確定上面的描述是否清楚,因此我在下面提供了相關的代碼,雖然它們不正確,但可以指出問題所在。

--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分別位於立方體的三層中,我認為這不是“正確的”。

所以我的問題是如何以一種不錯的方式實現一種可以處理很多情況的算法?

如果不清楚說明,請告訴我,以便我可以解釋自己在做什么和問題所在。

非常感謝任何想法和建議,非常感謝。

PS我最初想實現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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM