PureScriptでルービックキューブを作って回す

# はじめに

何だか世間ではElmが流行っているようですが、こちらは同じく純粋関数型AltJSのPureScriptでルービックキューブを作って回してみました。リポジトリは[コチラ](https://github.com/matoruru/purescript-rubikscube)にあります。ソースコードの全文は本記事の下部にも掲載しています。

ルービックキューブの概要をWikipediaより引用します。

> *ルービックキューブ（英: Rubik's Cube）はハンガリーの建築学者ルビク・エルネー（エルノー・ルービック）が考案した立体パズル。ルービックキューブの愛好家は日本ではキュービスト（英: Rubik's cubist）、日本国外ではキューバー（英: Rubik's cuber）と呼ばれる。 なお「ルービックキューブ」はメガハウスの登録商標であり、「Rubik's」はルービックス・ブランド社（イギリス）の登録商標である。*

> *各面は3×3=9個の色の付いた正方形で構成されているが、立方体全体を見ると、頂点にあるコーナーキューブ8個、辺にあるエッジキューブ12個、各面の中央にあるセンターキューブ6個で構成されているのがわかる。*

# ルービックキューブの型の定義

ルービックキューブを表す型として、Cube型とC型を用意しました。今回はキューブの構造ではなく、表面の色の並びに着目して設計しました。Cube型がキューブ本体、C型が色の付いたマスを表します。

```haskell
data C = W | O | Y | G | R | B

data Cube = Cube C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
```

Cube型の定義がとても見づらいので、以下のように変えます。意味は同じです。

```haskell

data C = W | O | Y | G | R | B

data Cube = Cube C C C  C C C  C C C  C C C  C C C  C C C
                 C C C  C C C  C C C  C C C  C C C  C C C
                 C C C  C C C  C C C  C C C  C C C  C C C
```

次は、以下のようになっている部分を1面として考え、回転操作を定義していきます。

```haskell
C C C
C C C
C C C
```

# 回転操作の定義

回転操作を定義するために、面とマス(本来はそれぞれエッジ・コーナー・センターの「キューブ」という構造になっていますが、今回は表し易さのためにマスとして考えます)の位置関係を考える必要があります。各マスに番号を振ります。

回転操作はf(ront)、r(ight)、b(ack)のような面の名前を使ったものになっています。各回転操作は、名前の面を時計回りに回すことを意味します(「'」が付いた操作は逆回転です)。スピードキューブ(ルービックキューブを解く速さを競う競技)で用いられる回転記号と同等のものです。また、少し例外的ですが、s、m、eは中段の回転、x、y、zはキューブの持ち替え(回転軸の中央マスを除き全マスの位置を変える)を意味します。

回転記号と意味の対応表を以下に示します。

| 回転記号 | 意味 |
|---|---|
| f | 前面を時計回りに回す |
| b | 後面を時計回りに回す |
| r | 右面を時計回りに回す |
| l | 左面を時計回りに回す |
| u | 上面を時計回りに回す |
| d | 下面を時計回りに回す |
| s | 中面(横)を時計回りに回す |
| m | 中面(縦)を時計回りに回す |
| e | 中段を時計回りに回す |
| x | 下面が正面になるように持ち替え |
| y | 右面が正面になるように持ち替え |
| z | 左面が上面になるように持ち替え |
| ○' | ○の逆 |

また、回転操作は「ある状態のキューブを受け取って別の状態のキューブを返す関数」として考えられます。

回転記号に対応する回転操作の関数は次のように定義しました。

```haskell
f_ :: Cube -> Cube
f_   (Cube f1 f2 f3  r1 r2 r3  b1 b2 b3  u1 u2 u3  l1 l2 l3  d1 d2 d3
           f4 f5 f6  r4 r5 r6  b4 b5 b6  u4 u5 u6  l4 l5 l6  d4 d5 d6
           f7 f8 f9  r7 r8 r9  b7 b8 b9  u7 u8 u9  l7 l8 l9  d7 d8 d9)
   =  Cube f7 f4 f1  r1 r2 r3  b1 b2 b3  l1 u2 u3  d3 l2 l3  r9 r8 r7
           f8 f5 f2  r4 r5 r6  b4 b5 b6  l4 u5 u6  d2 l5 l6  d4 d5 d6
           f9 f6 f3  u1 u4 u7  b7 b8 b9  l7 u8 u9  d1 l8 l9  d7 d8 d9

s_ :: Cube -> Cube
s_   (Cube f1 f2 f3  r1 r2 r3  b1 b2 b3  u1 u2 u3  l1 l2 l3  d1 d2 d3
           f4 f5 f6  r4 r5 r6  b4 b5 b6  u4 u5 u6  l4 l5 l6  d4 d5 d6
           f7 f8 f9  r7 r8 r9  b7 b8 b9  u7 u8 u9  l7 l8 l9  d7 d8 d9)
   =  Cube f1 f2 f3  r1 r2 r3  b1 b2 b3  u1 l2 u3  l1 d6 l3  d1 d2 d3
           f4 f5 f6  u2 u5 u8  b4 b5 b6  u4 l5 u6  l4 d5 l6  r6 r5 r4
           f7 f8 f9  r7 r8 r9  b7 b8 b9  u7 l8 u9  l7 d4 l9  d7 d8 d9

x_ :: Cube -> Cube
x_   (Cube f1 f2 f3  r1 r2 r3  b1 b2 b3  u1 u2 u3  l1 l2 l3  d1 d2 d3
           f4 f5 f6  r4 r5 r6  b4 b5 b6  u4 u5 u6  l4 l5 l6  d4 d5 d6
           f7 f8 f9  r7 r8 r9  b7 b8 b9  u7 u8 u9  l7 l8 l9  d7 d8 d9)
   =  Cube d3 d6 d9  r7 r4 r1  u7 u4 u1  f9 f8 f7  l3 l6 l9  b9 b8 b7
           d2 d5 d8  r8 r5 r2  u8 u5 u2  f6 f5 f4  l2 l5 l8  b6 b5 b4
           d1 d4 d7  r9 r6 r3  u9 u6 u3  f3 f2 f1  l1 l4 l7  b3 b2 b1

reverse :: (Cube -> Cube) -> (Cube -> Cube)
reverse f = f >>> f >>> f

f :: Cube -> Cube
f = f_

f' :: Cube -> Cube
f' = reverse f

r :: Cube -> Cube
r = y >>> f >>> y'

r' :: Cube -> Cube
r' = reverse r

b :: Cube -> Cube
b = y >>> y >>> f >>> y >>> y

b' :: Cube -> Cube
b' = reverse b

u :: Cube -> Cube
u = x' >>> f >>> x

u' :: Cube -> Cube
u' = reverse u

l :: Cube -> Cube
l = y' >>> f >>> y

l' :: Cube -> Cube
l' = reverse l

d :: Cube -> Cube
d = x >>> f >>> x'

d' :: Cube -> Cube
d' = reverse d

s :: Cube -> Cube
s = s_

s' :: Cube -> Cube
s' = reverse s

m :: Cube -> Cube
m = y' >>> s >>> y

m' :: Cube -> Cube
m' = reverse m

e :: Cube -> Cube
e = x >>> s >>> x'

e' :: Cube -> Cube
e' = reverse e

x :: Cube -> Cube
x = x_

x' :: Cube -> Cube
x' = reverse x

y :: Cube -> Cube
y = u >>> e' >>> d'

y' :: Cube -> Cube
y' = reverse y

z :: Cube -> Cube
z = f >>> s >>> b'

z' :: Cube -> Cube
z' = reverse z
```

前面(f)と中列(s)、持ち替え(x)の3つを定義すれば、残りはそれらの組み合わせで表現できます。ルービックキューブの動作を直感的に記述することができ、関数型言語の表現力の高さを実感できます。

また、ルービックキューブは回転を4回行うと元に戻るので、逆回転の操作は元の操作を3回行うことで表現できます(reverse関数)。持ち替えは3列全てを回すことで表現できます。

# 動作確認

定義した型と回転操作を使って、実際にキューブを回してみます。

結果を見るために、Cube型とC型をShow型クラスのインスタンスにします。

```haskell
instance showC :: Show C where
   show W = "W"
   show O = "O"
   show Y = "Y"
   show G = "G"
   show R = "R"
   show B = "B"

instance showCube :: Show Cube where
   show (Cube f1 f2 f3  r1 r2 r3  b1 b2 b3  u1 u2 u3  l1 l2 l3  d1 d2 d3
              f4 f5 f6  r4 r5 r6  b4 b5 b6  u4 u5 u6  l4 l5 l6  d4 d5 d6
              f7 f8 f9  r7 r8 r9  b7 b8 b9  u7 u8 u9  l7 l8 l9  d7 d8 d9)
        = line1 <> line2 <> line3 <> line4 <> line5 <> line6 <> line7 <> line8 <> line9
             where
                line1 = "    " <> show l7 <> show l8 <> show l9 <> "\n"
                line2 = "    " <> show l4 <> show l5 <> show l6 <> "\n"
                line3 = "    " <> show l1 <> show l2 <> show l3 <> "\n"
                line4 = show f7 <> show f8 <> show f9 <> " " <>
                        show d1 <> show d4 <> show d7 <> " " <>
                        show b9 <> show b6 <> show b3 <> " " <>
                        show u3 <> show u2 <> show u1 <> "\n"
                line5 = show f4 <> show f5 <> show f6 <> " " <>
                        show d2 <> show d5 <> show d8 <> " " <>
                        show b8 <> show b5 <> show b2 <> " " <>
                        show u6 <> show u5 <> show u4 <> "\n"
                line6 = show f1 <> show f2 <> show f3 <> " " <>
                        show d3 <> show d6 <> show d9 <> " " <>
                        show b7 <> show b4 <> show b1 <> " " <>
                        show u9 <> show u8 <> show u7 <> "\n"
                line7 = "    " <> show r9 <> show r6 <> show r3 <> "\n"
                line8 = "    " <> show r8 <> show r5 <> show r2 <> "\n"
                line9 = "    " <> show r7 <> show r4 <> show r1
```

早速replを使って、キューブの状態を確認していきたいところですが、キューブの作成を楽に(そして確実に)するために、次のような関数を用意します。

```haskell
createCube :: Cube
createCube = Cube W W W  O O O  Y Y Y  G G G  R R R  B B B
                  W W W  O O O  Y Y Y  G G G  R R R  B B B
                  W W W  O O O  Y Y Y  G G G  R R R  B B B
```

replを起動してキューブの状態を確認していきます。

```bash
└> pulp repl
PSCi, version 0.13.0
Type :? for help

import Prelude

> import RubiksCube 
> cube = createCube 
> cube
    RRR
    RRR
    RRR
WWW BBB YYY GGG
WWW BBB YYY GGG
WWW BBB YYY GGG
    OOO
    OOO
    OOO
```

まずは正しくキューブの状態が表示されました。これが全面揃った状態です。

次はいよいよ回転させていきます。

```haskell
> cube # u              -- 上段を1回回す
    WWW
    RRR
    RRR
OWW BBB YYR GGG
OWW BBB YYR GGG
OWW BBB YYR GGG
    OOO
    OOO
    YYY

> cube # u # u          -- 上段を2回回す
    OOO
    RRR
    RRR
YWW BBB YYW GGG
YWW BBB YYW GGG
YWW BBB YYW GGG
    OOO
    OOO
    RRR

> cube # u # u # u      -- 上段を3回回す
    YYY
    RRR
    RRR
RWW BBB YYO GGG
RWW BBB YYO GGG
RWW BBB YYO GGG
    OOO
    OOO
    WWW

> cube # u # u # u # u  -- 上段を4回回す(元に戻った！)
    RRR
    RRR
    RRR
WWW BBB YYY GGG
WWW BBB YYY GGG
WWW BBB YYY GGG
    OOO
    OOO
    OOO
```

うまく回転しています！４回回すと元に戻ってくることを確認できました。

他にもいろいろ試してみます。

```haskell
> cube # d # r # r # f # s # e # r' # u'  -- 単なるシャッフル
    YYG
    YYW
    GGY
RRY OOB OOO WGG
BBY OOB OGW GRY
BRR WBO WWW RRY
    GRB
    GWB
    RWB

> cube # d # r # r # f # s # e # r' # u' # u # r # e' # s' # f' # r' # r' # d'  -- 上のシャッフルの逆操作によって戻ることを確認
    RRR
    RRR
    RRR
WWW BBB YYY GGG
WWW BBB YYY GGG
WWW BBB YYY GGG
    OOO
    OOO
    OOO

> cube # d # r # d # f # f # s # e # r' # u' # r # s' # r' # r' # f' # d' # s # e # z # s' # e  -- 長めのシャッフル
    WYY
    GWW
    BYY
RYO YOO GRG RRB
GGO BOW GBB WRO
GWB RRR WYB ORO
    YBG
    OYB
    WGW

> cube # z # x # y # x # y # z # z  -- 持ち替え操作では位置関係(視点)が変わるだけで崩れない
    WWW
    WWW
    WWW
RRR GGG OOO BBB
RRR GGG OOO BBB
RRR GGG OOO BBB
    YYY
    YYY
    YYY
```

# 動作確認（オマケ）

ルービックキューブには、パターンキューブと呼ばれる、完成した状態からある決まった回し方をすることによって得られる美しい模様があります。これらを作ることで本記事の動作確認を締めくくりたいと思います。

## チェッカーキューブ

市松模様とも呼ばれます。作り方は非常に簡単ですが、美しい模様です。

![20190622_001648~01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/843266fb-6071-89a5-66ec-6ac7ea2de9e1.jpeg)


**作り方：中段全てを2回ずつ回す。**

```haskell
> cube # e # e # m # m # s # s
    ROR
    ORO
    ROR
WYW BGB YWY GBG
YWY GBG WYW BGB
WYW BGB YWY GBG
    ORO
    ROR
    ORO

> cube # m # m # e # e # s # s
    ROR
    ORO
    ROR
WYW BGB YWY GBG
YWY GBG WYW BGB
WYW BGB YWY GBG
    ORO
    ROR
    ORO
```

美しい市松模様が得られました。続けて2回ずつ回せば、順番は関係ありません。また、このパターンは再び同じように回せば元に戻ることが知られています。

```haskell
> cube # m # m # e # e # s # s # e # e # m # m # s # s
    RRR
    RRR
    RRR
WWW BBB YYY GGG
WWW BBB YYY GGG
WWW BBB YYY GGG
    OOO
    OOO
    OOO
```

持ち替えを駆使することで、一方向の回転操作だけで再現することも可能です。

```haskell
> cube # e # e # z # e # e # x # e # e
    BGB
    GBG
    BGB
ORO YWY ROR WYW
ROR WYW ORO YWY
ORO YWY ROR WYW
    GBG
    BGB
    GBG
```

## ヘソキューブ

真ん中だけが別の色になったパターンです。

![20190622_001713~01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/dbb9aed8-a28d-b2a8-ba73-98109fc185ee.jpeg)

**作り方：中段aを1回回す→中段bを1回回す→中段aを逆に回す→中段bを逆に回す**

```haskell
> cube # m # e # m' # e'
    RRR
    RWR
    RRR
WWW BBB YYY GGG
WGW BOB YBY GRG
WWW BBB YYY GGG
    OOO
    OYO
    OOO

> cube # s # e # s' # e'
    RRR
    RBR
    RRR
WWW BBB YYY GGG
WOW BYB YRY GWG
WWW BBB YYY GGG
    OOO
    OGO
    OOO

> cube # e # s' # e' # s
    RRR
    RYR
    RRR
WWW BBB YYY GGG
WBW BOB YGY GRG
WWW BBB YYY GGG
    OOO
    OWO
    OOO
```

## 6面T字

全ての面の模様が「T」になったものです。

![Tji.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/a0fd318c-a2a2-2bfa-4a38-86d73c8c60d1.jpeg)

**作り方：左列を180°回す→上面を180°回す→前面を180°回す→下面を180°回す→右列を180°回す→上面を180°回す→右列を180°回す→前面を180°回す→右列を180°回す→上面を180°回す**

```haskell
> cube # l # l # u # u # f # f # d # d # r # r # u # u # r # r # f # f # r # r # u # u
    ROO
    RRR
    ROO
WYY GBG YWW GGG
WWW GBG YYY BGB
WYY BBB YWW BGB
    RRO
    OOO
    RRO
```

## 6面H字

全ての面の模様が「H」になったものです。

![20190623_012522~01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/b4fb6ec1-2652-c575-4c8c-312bfbb9d945.jpeg)

**作り方：縦中列を90°回す→上面を180°回す→縦中列を180°回す→下面を180°回す縦中列を90°回す→水平中列を90°回す→後ろ面を180°回す→水平中列を180°回す→前面を180°回す→水平中列を90°回す→横中列を90°回す→左列を180°回す→横中列を180°回す→右列を180°回す→横中列を90°回す→縦中列を180°回す**

```haskell
> cube # m' # u # u # m # m # d # d # m' # e # b # b # e # e # f # f # e' # s # l # l # s # s # r # r # s' # m # m
    RRR
    ORO
    RRR
WWW BGB YYY GBG
YWY BBB WYW GGG
WWW BGB YYY GBG
    OOO
    ROR
    OOO
```

## パターンの組み合わせ(チェッカー&ヘソ)

上で紹介したチェッカーキューブとヘソキューブを組み合わせると、市松模様の真ん中の色を変えることができます。

![cheandheso.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/582d942f-0999-6e99-e40f-0cbae8007ac6.jpeg)


```haskell
> cube # e # e # m # m # s # s  -- チェッカー
    ROR
    ORO
    ROR
WYW BGB YWY GBG
YWY GBG WYW BGB
WYW BGB YWY GBG
    ORO
    ROR
    ORO

> cube # m # e # m' # e'  -- ヘソ
    RRR
    RWR
    RRR
WWW BBB YYY GGG
WGW BOB YBY GRG
WWW BBB YYY GGG
    OOO
    OYO
    OOO

> cube # e # e # m # m # s # s # m # e # m' # e'  -- 上2つの組み合わせ
    ROR
    OWO
    ROR
WYW BGB YWY GBG
YGY GOG WBW BRB
WYW BGB YWY GBG
    ORO
    RYR
    ORO
```

# ソースコード全文

[GitHub](https://github.com/matoruru/purescript-rubikscube)にもあります。

上で紹介したパターンキューブ用の関数群も用意したので(Pattern.purs)、手軽にパターンキューブを楽しむことができます。

```haskell:RubiksCube.purs
module RubiksCube
   ( Cube
   , createCube
   , f
   , f'
   , r
   , r'
   , b
   , b'
   , u
   , u'
   , l
   , l'
   , d
   , d'
   , s
   , s'
   , m
   , m'
   , e
   , e'
   , x
   , x'
   , y
   , y'
   , z
   , z'
   ) where

import Prelude

data C = W | O | Y | G | R | B

instance showC :: Show C where
   show W = "W"
   show O = "O"
   show Y = "Y"
   show G = "G"
   show R = "R"
   show B = "B"

derive instance eqC :: Eq C

data Cube = Cube C C C  C C C  C C C  C C C  C C C  C C C
                 C C C  C C C  C C C  C C C  C C C  C C C
                 C C C  C C C  C C C  C C C  C C C  C C C

instance showCube :: Show Cube where
   show (Cube f1 f2 f3  r1 r2 r3  b1 b2 b3  u1 u2 u3  l1 l2 l3  d1 d2 d3
              f4 f5 f6  r4 r5 r6  b4 b5 b6  u4 u5 u6  l4 l5 l6  d4 d5 d6
              f7 f8 f9  r7 r8 r9  b7 b8 b9  u7 u8 u9  l7 l8 l9  d7 d8 d9)
        = line1 <> line2 <> line3 <> line4 <> line5 <> line6 <> line7 <> line8 <> line9
             where
                line1 = "    " <> show l7 <> show l8 <> show l9 <> "\n"
                line2 = "    " <> show l4 <> show l5 <> show l6 <> "\n"
                line3 = "    " <> show l1 <> show l2 <> show l3 <> "\n"
                line4 = show f7 <> show f8 <> show f9 <> " " <>
                        show d1 <> show d4 <> show d7 <> " " <>
                        show b9 <> show b6 <> show b3 <> " " <>
                        show u3 <> show u2 <> show u1 <> "\n"
                line5 = show f4 <> show f5 <> show f6 <> " " <>
                        show d2 <> show d5 <> show d8 <> " " <>
                        show b8 <> show b5 <> show b2 <> " " <>
                        show u6 <> show u5 <> show u4 <> "\n"
                line6 = show f1 <> show f2 <> show f3 <> " " <>
                        show d3 <> show d6 <> show d9 <> " " <>
                        show b7 <> show b4 <> show b1 <> " " <>
                        show u9 <> show u8 <> show u7 <> "\n"
                line7 = "    " <> show r9 <> show r6 <> show r3 <> "\n"
                line8 = "    " <> show r8 <> show r5 <> show r2 <> "\n"
                line9 = "    " <> show r7 <> show r4 <> show r1

derive instance eqCube :: Eq Cube

createCube :: Cube
createCube = Cube W W W  O O O  Y Y Y  G G G  R R R  B B B
                  W W W  O O O  Y Y Y  G G G  R R R  B B B
                  W W W  O O O  Y Y Y  G G G  R R R  B B B

f_ :: Cube -> Cube
f_   (Cube f1 f2 f3  r1 r2 r3  b1 b2 b3  u1 u2 u3  l1 l2 l3  d1 d2 d3
           f4 f5 f6  r4 r5 r6  b4 b5 b6  u4 u5 u6  l4 l5 l6  d4 d5 d6
           f7 f8 f9  r7 r8 r9  b7 b8 b9  u7 u8 u9  l7 l8 l9  d7 d8 d9)
   =  Cube f7 f4 f1  r1 r2 r3  b1 b2 b3  l1 u2 u3  d3 l2 l3  r9 r8 r7
           f8 f5 f2  r4 r5 r6  b4 b5 b6  l4 u5 u6  d2 l5 l6  d4 d5 d6
           f9 f6 f3  u1 u4 u7  b7 b8 b9  l7 u8 u9  d1 l8 l9  d7 d8 d9

s_ :: Cube -> Cube
s_   (Cube f1 f2 f3  r1 r2 r3  b1 b2 b3  u1 u2 u3  l1 l2 l3  d1 d2 d3
           f4 f5 f6  r4 r5 r6  b4 b5 b6  u4 u5 u6  l4 l5 l6  d4 d5 d6
           f7 f8 f9  r7 r8 r9  b7 b8 b9  u7 u8 u9  l7 l8 l9  d7 d8 d9)
   =  Cube f1 f2 f3  r1 r2 r3  b1 b2 b3  u1 l2 u3  l1 d6 l3  d1 d2 d3
           f4 f5 f6  u2 u5 u8  b4 b5 b6  u4 l5 u6  l4 d5 l6  r6 r5 r4
           f7 f8 f9  r7 r8 r9  b7 b8 b9  u7 l8 u9  l7 d4 l9  d7 d8 d9

x_ :: Cube -> Cube
x_   (Cube f1 f2 f3  r1 r2 r3  b1 b2 b3  u1 u2 u3  l1 l2 l3  d1 d2 d3
           f4 f5 f6  r4 r5 r6  b4 b5 b6  u4 u5 u6  l4 l5 l6  d4 d5 d6
           f7 f8 f9  r7 r8 r9  b7 b8 b9  u7 u8 u9  l7 l8 l9  d7 d8 d9)
   =  Cube d3 d6 d9  r7 r4 r1  u7 u4 u1  f9 f8 f7  l3 l6 l9  b9 b8 b7
           d2 d5 d8  r8 r5 r2  u8 u5 u2  f6 f5 f4  l2 l5 l8  b6 b5 b4
           d1 d4 d7  r9 r6 r3  u9 u6 u3  f3 f2 f1  l1 l4 l7  b3 b2 b1

reverse :: (Cube -> Cube) -> (Cube -> Cube)
reverse f = f >>> f >>> f

f :: Cube -> Cube
f = f_

f' :: Cube -> Cube
f' = reverse f

r :: Cube -> Cube
r = y >>> f >>> y'

r' :: Cube -> Cube
r' = reverse r

b :: Cube -> Cube
b = y >>> y >>> f >>> y >>> y

b' :: Cube -> Cube
b' = reverse b

u :: Cube -> Cube
u = x' >>> f >>> x

u' :: Cube -> Cube
u' = reverse u

l :: Cube -> Cube
l = y' >>> f >>> y

l' :: Cube -> Cube
l' = reverse l

d :: Cube -> Cube
d = x >>> f >>> x'

d' :: Cube -> Cube
d' = reverse d

s :: Cube -> Cube
s = s_

s' :: Cube -> Cube
s' = reverse s

m :: Cube -> Cube
m = y' >>> s >>> y

m' :: Cube -> Cube
m' = reverse m

e :: Cube -> Cube
e = x >>> s >>> x'

e' :: Cube -> Cube
e' = reverse e

x :: Cube -> Cube
x = x_

x' :: Cube -> Cube
x' = reverse x

y :: Cube -> Cube
y = u >>> e' >>> d'

y' :: Cube -> Cube
y' = reverse y

z :: Cube -> Cube
z = f >>> s >>> b'

z' :: Cube -> Cube
z' = reverse z
```

```haskell:Pattern.purs
module RubiksCube.Pattern where

import Prelude

import RubiksCube

checkerCube :: Cube -> Cube
checkerCube = m >>> m >>> e >>> e >>> s >>> s

cross :: Cube -> Cube
cross = r >>> r >>> l' >>> d >>> f >>> f >>> r' >>> d' >>> r' >>> l >>> u' >>> d >>> r >>> d >>> b >>> b >>> r' >>> u >>> d >>> d

cross4 :: Cube -> Cube
cross4 = u >>> u >>> r >>> r >>> l >>> l >>> f >>> f >>> b >>> b >>> d >>> d >>> l >>> l >>> r >>> r >>> f >>> f >>> b >>> b

cu6 :: Cube -> Cube
cu6 = u' >>> b >>> b >>> u >>> l >>> l >>> d >>> l >>> l >>> r >>> r >>> d' >>> b' >>> r >>> d' >>> l >>> r' >>> b >>> b >>> u >>> u >>> f' >>> l' >>> u'

cubeInCube :: Cube -> Cube
cubeInCube = f >>> l >>> f >>> u' >>> r >>> u >>> f >>> f >>> l >>> l >>> u' >>> l' >>> b >>> d' >>> b' >>> l >>> l >>> u

cubeInCubeInCube :: Cube -> Cube
cubeInCubeInCube = u' >>> l' >>> u' >>> f' >>> r >>> r >>> b' >>> r >>> f >>> u >>> b >>> b >>> u >>> b' >>> l >>> u' >>> f >>> u >>> r >>> f'

deckerboard :: Cube -> Cube
deckerboard = u >>> d >>> r >>> l' >>> f' >>> b >>> u >>> d' >>> r >>> r >>> u >>> r >>> r >>> l >>> l >>> d >>> d >>> f >>> f >>> b >>> b >>> d

giftBox :: Cube -> Cube
giftBox = u >>> b >>> b >>> r >>> r >>> b >>> b >>> l >>> l >>> f >>> f >>> r >>> r >>> d' >>> f >>> f >>> l >>> l >>> b >>> f' >>> l >>> f >>> f >>> d >>> u' >>> r >>> r >>> f' >>> l' >>> r'

h6 :: Cube -> Cube
h6 = u >>> u >>> d >>> d >>> l >>> l >>> u >>> u >>> d >>> d >>> r >>> r >>> f >>> f >>> b >>> b >>> l >>> l >>> f >>> f >>> b >>> b >>> r >>> r >>> u >>> u >>> d >>> d >>> f >>> f >>> u >>> u >>> d >>> d >>> b >>> b

plusMinus :: Cube -> Cube
plusMinus = u >>> u >>> r >>> r >>> l >>> l >>> u >>> u >>> r >>> r >>> l >>> l

plusMinusCheck :: Cube -> Cube
plusMinusCheck = u >>> d >>> r >>> r >>> l >>> l >>> u >>> d >>> r >>> r >>> l >>> l

spot4 :: Cube -> Cube
spot4 = f >>> f >>> b >>> b >>> u >>> d' >>> r >>> r >>> l >>> l >>> u >>> d'

spot6 :: Cube -> Cube
spot6 = e >>> m >>> e' >>> m'

superflip :: Cube -> Cube
superflip = u >>> r >>> r >>> f >>> b >>> r >>> b >>> b >>> r >>> u >>> u >>> l >>> b >>> b >>> r >>> u' >>> d' >>> r >>> r >>> f >>> r' >>> l >>> b >>> b >>> u >>> u >>> f >>> f

t4 :: Cube -> Cube
t4 = f >>> f >>> d >>> d >>> f' >>> l >>> l >>> d >>> d >>> u >>> u >>> r >>> r >>> b' >>> u >>> u >>> f >>> f

t6 :: Cube -> Cube
t6 = l >>> l >>> u >>> u >>> f >>> f >>> d >>> d >>> r >>> r >>> u >>> u >>> r >>> r >>> f >>> f >>> r >>> r >>> u >>> u

tablecloth :: Cube -> Cube
tablecloth = r >>> l >>> u >>> u >>> f' >>> u >>> u >>> d >>> d >>> r >>> r >>> l >>> l >>> f' >>> d >>> d >>> f >>> f >>> d >>> r >>> r >>> l >>> l >>> f >>> f >>> b >>> b >>> d >>> b >>> b >>> l >>> l

vertialStripes :: Cube -> Cube
vertialStripes = f >>> u >>> f >>> r >>> l >>> l >>> b >>> d' >>> r >>> d >>> d >>> l >>> d' >>> b >>> r >>> r >>> l >>> f >>> u >>> f

```

# まとめ

ここまで読んでくださってありがとうございます！

Twitterフォローしていただけると嬉しいです！
https://twitter.com/_matoruru

# 参考

「はじめに」の文をこちらから引用しました。
https://ja.wikipedia.org/wiki/%E3%83%AB%E3%83%BC%E3%83%93%E3%83%83%E3%82%AF%E3%82%AD%E3%83%A5%E3%83%BC%E3%83%96

回転記号とパターンキューブの情報をこちらの本から得ました(素晴らしい本です！)。
https://www.amazon.co.jp/%E3%83%AB%E3%83%BC%E3%83%93%E3%83%83%E3%82%AF%E3%82%AD%E3%83%A5%E3%83%BC%E3%83%96%E5%AE%8C%E5%85%A8%E6%94%BB%E7%95%A5%E5%85%AC%E5%BC%8F%E3%82%AC%E3%82%A4%E3%83%89%E3%83%96%E3%83%83%E3%82%AF-%E4%BF%9D%E5%AD%98%E7%89%88-%E7%99%BE%E7%94%B0-%E9%83%81%E5%A4%AB/dp/4522485506/ref=cm_cr_arp_d_product_top?ie=UTF8

コチラのサイトは非常に多くのパターンキューブを紹介しています。
https://ruwix.com/the-rubiks-cube/rubiks-cube-patterns-algorithms/