2x2x2 Rubik's cube
Geplaatst: di 12 mar 2013, 09:15
Ik heb meer "Rubik's cubes" dan een normaal mens nodig heeft (meer dan nul dus). Een van de kubussen die ik heb is een Pocket cube. Nu vroeg ik mij af hoeveel stappen je maximaal nodig hebt om de kubus op te lossen. Nou zou ik natuurlijk de wiki-pagina kunnen lezen en dan staat daar dat je maximaal 14 kwart-slagen nodig hebt (11 als je ook half-slagen toestaat), maar helaas heb ik bedacht dat ik het zelf uit wil rekenen.
Hoe ik dit aanpak: ik begin met een opgeloste Pocket cube. Nu genereer ik 6 nieuwe toestanden door het rechtervlak met de klok mee te draaien en tegen de klok in te draaien, en zo ook met het achtervlak en het ondervlak. Ik heb nu alle toestanden die ik vanuit de opgeloste kubus kan bereiken.
Nu herhaal ik de procedure voor elk van de nieuwe toestanden. Hiermee vind ik de kubustoestanden op afstand 2 van de oplossing. Dit proces herhaal ik, waarbij ik eerder gepasseerde toestanden negeer, totdat er geen nieuwe toestanden meer ontstaan.
Mijn haskell-programma:
En dan nu het probleem: Mijn oplossing wijkt af van wat op wikipedia staat. Ik vermoed dus dat er ergens iets foutgaat bij mij. Het alternatief is dat wiki fout is (acht ik onwaarschijnlijk). Heeft iemand goede suggesties?
Hoe ik dit aanpak: ik begin met een opgeloste Pocket cube. Nu genereer ik 6 nieuwe toestanden door het rechtervlak met de klok mee te draaien en tegen de klok in te draaien, en zo ook met het achtervlak en het ondervlak. Ik heb nu alle toestanden die ik vanuit de opgeloste kubus kan bereiken.
Nu herhaal ik de procedure voor elk van de nieuwe toestanden. Hiermee vind ik de kubustoestanden op afstand 2 van de oplossing. Dit proces herhaal ik, waarbij ik eerder gepasseerde toestanden negeer, totdat er geen nieuwe toestanden meer ontstaan.
Mijn haskell-programma:
Code: Selecteer alles
import qualified Data.Set as Set
cube2x2 = [(2,-1,1,0),(2,1,1,1),(2,1,-1,2),(2,-1,1,3),(-2,-1,1,4),(-2,1,1,5),(-2,1,-1,6),(-2,-1,1,7)]
rotateR = map (\(x,y,z,n) -> if (y>0) then (-z,y,x,n) else (x,y,z,n))
rotateRinv = rotateR . rotateR . rotateR
rotateD = map (\(x,y,z,n) -> if (z<0) then (-y,x,z,n) else (x,y,z,n))
rotateDinv = rotateD . rotateD . rotateD
rotateB = map (\(x,y,z,n) -> if (x<0) then (x,-z,y,n) else (x,y,z,n))
rotateBinv = rotateB . rotateB . rotateB
nextStep (us,ts) = (Set.filter (\a -> False == Set.member a ts) ns, Set.union ts ns)
where
ns = applyfs us [rotateR, rotateRinv, rotateB, rotateBinv, rotateD, rotateDinv]
startSet = (Set.fromList [cube2x2], Set.fromList [cube2x2])
countSteps n (us,ts) | Set.null us = (n, Set.size ts)
| otherwise = countSteps (n+1) (nextStep (us,ts))
applyfs us [] = Set.empty
applyfs us (f:fs) = Set.union (Set.map f us) (applyfs us fs)
solution = countSteps 0 startSet