-
Notifications
You must be signed in to change notification settings - Fork 0
/
Cube.hs
59 lines (45 loc) · 1.6 KB
/
Cube.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
module Cube where
import Prelude hiding (Left, Right)
import Data.Function (on)
import Numeric.LinearAlgebra (Z, Vector)
import qualified Data.List as List
import qualified Numeric.LinearAlgebra as LA
type SideField = (Int, Int)
fieldsOnSide :: [SideField]
fieldsOnSide = [(x,y)|x <- [0..2], y <- [0..2]]
data Side = Top | Front | Right | Back | Left | Bottom
deriving (Show, Read, Eq, Enum, Ord, Bounded)
data Color = White | Green | Red | Blue | Orange | Yellow
deriving (Show, Read, Eq, Enum, Ord, Bounded)
type Cube = [(Side, Int, Int, Color)]
solvedCube :: Cube
solvedCube = do
(side, color) <- zip [Top ..] [White ..]
(x, y) <- fieldsOnSide
[(side, x, y, color)]
computeIndex :: (Side, Int, Int, Color) -> Int
computeIndex (_, x, y, c) = x * 3 + y + fromEnum c * 9
cubeToVector :: Cube -> Vector Z
cubeToVector = LA.fromList . fmap go . List.sortBy (compare `on` project)
where
project (a,b,c,_) = (a,b,c)
go :: (Side, Int, Int, Color) -> Z
go (_, _, _, c) = fromIntegral $ fromEnum c
vectorToCube :: Vector Z -> Cube
vectorToCube = zipWith go solvedCube . fmap toColor . LA.toList
where
toColor :: Z -> Color
toColor = toEnum . fromIntegral
go :: (Side, Int, Int, Color) -> Color -> (Side, Int, Int, Color)
go (s, x, y, _) c = (s, x, y, c)
oppositeSides :: Side -> Side -> Bool
oppositeSides Top Bottom = True
oppositeSides Front Back = True
oppositeSides Right Left = True
oppositeSides x y
| fromEnum x > fromEnum y = oppositeSides y x
| otherwise = False
adjacentSides :: Side -> Side -> Bool
adjacentSides x y
| x == y = False
| otherwise = not $ oppositeSides x y