python实现三阶魔方还原的示例代码

作者:Kikikikii 时间:2021-03-12 08:45:04 

思路

复原魔方困难问题的分解:

1、用合适的数据结构表示出三阶魔方的六个面以及每一面的颜色

2、每一次不同旋转操作的实现

3、复原时如何判断当前魔方应该使用哪一种公式

本次实验实现了前两个操作,具体思路是:

用numpy库中的矩阵将六个面分别表示出来,按上下左右前后的顺序放入列表中。再依据流行公式里的方法编写对每一个面进行旋转操作的函数,调用函数实现魔方的旋转。最后输入指令可得到旋转之后的魔方,以及执行逆序指令后验证魔方还原。

预备知识

矩阵:使用numpy库中的矩阵结构

函数说明:

: 上面顺时针旋转 90°

: 底面顺时针旋转 90°

: 左面顺时针旋转 90°

: 右面顺时针旋转 90°

: 正面顺时针旋转 90°

: 背面顺时针旋转 90°

**注:**字母前加上下划线 ‘_' 表示逆时针

代码详解

本次实验将【上、下、左、右、前、后】六个面用数字【0、1、2、3、4、5】表示原本每个面的颜色,并依次存入列表faces【】里(即:faces[0]中存放的是最上面的数字全为0的三阶矩阵)

注:魔方视角始终固定,即在整个过程中正(左…)面始终是正(左…)面


# 创建六个面,放在faces列表里,顺序为上(0),下(1),左(2),右(3),前(4),后(5)
faces = [np.zeros((3, 3))]

for i in range(1, 6):
   faces.append(np.ones((3, 3)) + faces[i - 1])

python实现三阶魔方还原的示例代码

每一个面的 顺时针逆时针 旋转由函数 clockwise()antiClockwise() 实现


t = np.array([[0, 0, 1],
             [0, 1, 0],
             [1, 0, 0]])

# 该面顺时针旋转 90 度
def clockwise(face):
   face = face.transpose().dot(t)
   return face

# 该面逆时针旋转 90 度
def antiClockwise(face):
   face = face.dot(t).transpose()
   return face

A.transpose() 方法是实现 A 矩阵的转置

A.dot(B) 方法是实现 A乘以矩阵B

通过计算,上述方法可以实现矩阵顺时针或者逆时针旋转的效果

在这里以左面的顺时针旋转 90°为例,其它旋转方式可以类比


def L(FACES):
   FACES[2] = clockwise(FACES[2])
   FACES_new = cp.deepcopy(FACES)
   a, b, c, d = clockwise(FACES_new[4]), clockwise(FACES_new[1]), antiClockwise(FACES_new[5]), clockwise(FACES_new[0])
   e, f, g, h = cp.deepcopy(a), cp.deepcopy(b), cp.deepcopy(c), cp.deepcopy(d)
   e[0], f[0], g[0], h[0] = d[0], a[0], b[0], c[0]
   FACES[4], FACES[1], FACES[5], FACES[0] = antiClockwise(e), antiClockwise(f), clockwise(g), antiClockwise(h)

1、直接调用函数将左面(第2面)顺时针旋转 90°


FACES[2] = clockwise(FACES[2])

2、这里采用深度复制,使用 cp.deepcopy() 的方法,避免直接使用等号 ‘=' 导致不同的变量指向同一个值。这时,【e、f、g、h】和【a、b、c、d】代表魔方的

【正面、底面顺时针旋转90°、背面逆时针旋转90°、上面顺时针旋转90°】


a, b, c, d = clockwise(FACES_new[4]), clockwise(FACES_new[1]), antiClockwise(FACES_new[5]), clockwise(FACES_new[0])

旋转的目的是:

在左面旋转的过程中,左面会影响到其它四个面,但对其它四个面的影响是不同的。例如正面、底面和上面被影响的是第一列,而背面被影响的是第三列。我们为了使各面统一起来,方便数值的改变,我们选择将正、底、上面顺时针旋转90°,将背面逆时针旋转90°。这时,我们只需按顺序交换每一面的第一行,最后再逆时针或顺时针转回来即可。

python实现三阶魔方还原的示例代码

3、按顺序交换:正面第一行传递到底面第一行

上面第一行传递到正面第一行

背面第一行传递到上面第一行

底面第一行传递到背面第一行


e[0], f[0], g[0], h[0] = d[0], a[0], b[0], c[0]

最后再依次根据上述操作逆旋转回去:


FACES[4], FACES[1], FACES[5], FACES[0] = antiClockwise(e), antiClockwise(f), clockwise(g), antiClockwise(h)

代码


import numpy as np
import copy as cp

# 创建六个面,放在faces列表里,顺序为上(0),下(1),左(2),右(3),前(4),后(5)
faces = [np.zeros((3, 3))]

for i in range(1, 6):
   faces.append(np.ones((3, 3)) + faces[i - 1])

t = np.array([[0, 0, 1],
             [0, 1, 0],
             [1, 0, 0]])

# 该面顺时针旋转 90 度
def clockwise(face):
   face = face.transpose().dot(t)
   return face

# 该面逆时针旋转 90 度
def antiClockwise(face):
   face = face.dot(t).transpose()
   return face

def U(FACES):
   FACES[0] = clockwise(FACES[0])
   FACES_new = cp.deepcopy(FACES)
   a, b, c, d = FACES_new[4], FACES_new[2], FACES_new[5], FACES_new[3]
   FACES[4][0], FACES[2][0], FACES[5][0], FACES[3][0] = d[0], a[0], b[0], c[0]

def _U(FACES):
   FACES[0] = antiClockwise(FACES[0])
   FACES_new = cp.deepcopy(FACES)
   a, b, c, d = FACES_new[4], FACES_new[2], FACES_new[5], FACES_new[3]
   FACES[4][0], FACES[2][0], FACES[5][0], FACES[3][0] = b[0], c[0], d[0], a[0]

def U2(FACES):
   for i in range(2):
       U(FACES)
   '''
   FACES[0] = clockwise(clockwise(FACES[0]))
   FACES_new = cp.deepcopy(FACES)
   a, b, c, d = FACES_new[4], FACES_new[2], FACES_new[5], FACES_new[3]
   FACES[4][0], FACES[2][0], FACES[5][0], FACES[3][0] = c[0], d[0], a[0], b[0]
   '''

def D(FACES):
   FACES[1] = clockwise(FACES[1])
   FACES_new = cp.deepcopy(FACES)
   a, b, c, d = FACES_new[4], FACES_new[2], FACES_new[5], FACES_new[3]
   FACES[4][2], FACES[2][2], FACES[5][2], FACES[3][2] = b[2], c[2], d[2], a[2]

def _D(FACES):
   FACES[1] = antiClockwise(FACES[1])
   FACES_new = cp.deepcopy(FACES)
   a, b, c, d = FACES_new[4], FACES_new[2], FACES_new[5], FACES_new[3]
   FACES[4][2], FACES[2][2], FACES[5][2], FACES[3][2] = d[2], a[2], b[2], c[2]

def D2(FACES):
   for i in range(2):
       D(FACES)
   '''
   FACES[1] = clockwise(clockwise(FACES[1]))
   FACES_new = cp.deepcopy(FACES)
   a, b, c, d = FACES_new[4], FACES_new[2], FACES_new[5], FACES_new[3]
   FACES[4][2], FACES[2][2], FACES[5][2], FACES[3][2] = c[2], d[2], a[2], b[2]
   '''

def L(FACES):
   FACES[2] = clockwise(FACES[2])
   FACES_new = cp.deepcopy(FACES)
   a, b, c, d = clockwise(FACES_new[4]), clockwise(FACES_new[1]), antiClockwise(FACES_new[5]), clockwise(FACES_new[0])
   e, f, g, h = cp.deepcopy(a), cp.deepcopy(b), cp.deepcopy(c), cp.deepcopy(d)
   e[0], f[0], g[0], h[0] = d[0], a[0], b[0], c[0]
   FACES[4], FACES[1], FACES[5], FACES[0] = antiClockwise(e), antiClockwise(f), clockwise(g), antiClockwise(h)

def _L(FACES):
   FACES[2] = antiClockwise(FACES[2])
   FACES_new = cp.deepcopy(FACES)
   a, b, c, d = clockwise(FACES_new[4]), clockwise(FACES_new[1]), antiClockwise(FACES_new[5]), clockwise(FACES_new[0])
   e, f, g, h = cp.deepcopy(a), cp.deepcopy(b), cp.deepcopy(c), cp.deepcopy(d)
   e[0], f[0], g[0], h[0] = b[0], c[0], d[0], a[0]
   FACES[4], FACES[1], FACES[5], FACES[0] = antiClockwise(e), antiClockwise(f), clockwise(g), antiClockwise(h)

def L2(FACES):
   for i in range(2):
       L(FACES)

# 上(0),下(1),左(2),右(3),前(4),后(5)
def R(FACES):
   FACES[3] = clockwise(FACES[3])
   FACES_new = cp.deepcopy(FACES)
   a, b, c, d = antiClockwise(FACES_new[4]), antiClockwise(FACES_new[1]), clockwise(FACES_new[5]), antiClockwise(
       FACES_new[0])
   e, f, g, h = cp.deepcopy(a), cp.deepcopy(b), cp.deepcopy(c), cp.deepcopy(d)
   g[0], f[0], e[0], h[0] = d[0], c[0], b[0], a[0]
   FACES[4], FACES[1], FACES[5], FACES[0] = clockwise(e), clockwise(f), antiClockwise(g), clockwise(h)

def _R(FACES):
   FACES[3] = antiClockwise(FACES[3])
   FACES_new = cp.deepcopy(FACES)
   a, b, c, d = antiClockwise(FACES_new[4]), antiClockwise(FACES_new[1]), clockwise(FACES_new[5]), antiClockwise(
       FACES_new[0])
   e, f, g, h = cp.deepcopy(a), cp.deepcopy(b), cp.deepcopy(c), cp.deepcopy(d)
   f[0], g[0], h[0], e[0] = a[0], b[0], c[0], d[0]
   FACES[4], FACES[1], FACES[5], FACES[0] = clockwise(e), clockwise(f), antiClockwise(g), clockwise(h)

def R2(FACES):
   for i in range(2):
       R(FACES)

def F(FACES):
   FACES[4] = clockwise(FACES[4])
   FACES_new = cp.deepcopy(FACES)
   a, b, c, d = clockwise(clockwise(FACES_new[0])), FACES_new[1], antiClockwise(FACES_new[2]), clockwise(FACES_new[3])
   e, f, g, h = cp.deepcopy(a), cp.deepcopy(b), cp.deepcopy(c), cp.deepcopy(d)
   e[0], g[0], f[0], h[0] = c[0], b[0], d[0], a[0]
   FACES[0], FACES[1], FACES[2], FACES[3] = clockwise(clockwise(e)), f, clockwise(g), antiClockwise(h)

def _F(FACES):
   FACES[4] = antiClockwise(FACES[4])
   FACES_new = cp.deepcopy(FACES)
   a, b, c, d = clockwise(clockwise(FACES_new[0])), FACES_new[1], antiClockwise(FACES_new[2]), clockwise(FACES_new[3])
   e, f, g, h = cp.deepcopy(a), cp.deepcopy(b), cp.deepcopy(c), cp.deepcopy(d)
   g[0], f[0], h[0], e[0] = a[0], c[0], b[0], d[0]
   FACES[0], FACES[1], FACES[2], FACES[3] = clockwise(clockwise(e)), f, clockwise(g), antiClockwise(h)

def F2(FACES):
   for _ in range(2):
       F(FACES)

# 上(0),下(1),左(2),右(3),前(4),后(5)
def B(FACES):
   FACES[5] = clockwise(FACES[5])
   FACES_new = cp.deepcopy(FACES)
   a, b, c, d = FACES_new[0], clockwise(clockwise(FACES_new[1])), clockwise(FACES_new[2]), antiClockwise(FACES_new[3])
   e, f, g, h = cp.deepcopy(a), cp.deepcopy(b), cp.deepcopy(c), cp.deepcopy(d)
   g[0], f[0], h[0], e[0] = a[0], c[0], b[0], d[0]
   FACES[0], FACES[1], FACES[2], FACES[3] = e, clockwise(clockwise(f)), antiClockwise(g), clockwise(h)

def _B(FACES):
   FACES[5] = antiClockwise(FACES[5])
   FACES_new = cp.deepcopy(FACES)
   a, b, c, d = FACES_new[0], clockwise(clockwise(FACES_new[1])), clockwise(FACES_new[2]), antiClockwise(FACES_new[3])
   e, f, g, h = cp.deepcopy(a), cp.deepcopy(b), cp.deepcopy(c), cp.deepcopy(d)
   e[0], g[0], f[0], h[0] = c[0], b[0], d[0], a[0]
   FACES[0], FACES[1], FACES[2], FACES[3] = e, clockwise(clockwise(f)), antiClockwise(g), clockwise(h)

def B2(FACES):
   for i in range(2):
       B(FACES)

'''
                         |************|
                         |*U1**U2**U3*|
                         |************|
                         |*U4**U5**U6*|
                         |************|
                         |*U7**U8**U9*|
                         |************|
             ************|************|************|************|
             *L1**L2**L3*|*F1**F2**F3*|*R1**R2**R3*|*B1**B2**B3*|
             ************|************|************|************|
             *L4**L5**L6*|*F4**F5**F6*|*R4**R5**R6*|*B4**B5**B6*|
             ************|************|************|************|
             *L7**L8**L9*|*F7**F8**F9*|*R7**R8**R9*|*B7**B8**B9*|
             ************|************|************|************|
                         |************|
                         |*D1**D2**D3*|
                         |************|
                         |*D4**D5**D6*|
                         |************|
                         |*D7**D8**D9*|
                         |************|
'''

def toString(FACES):
   print()
   for i in range(3):
       print("     ", int(FACES[0][i][0]), int(FACES[0][i][1]), int(FACES[0][i][2]))
   for i in range(3):
       print(int(FACES[2][i][0]), int(FACES[2][i][1]), int(FACES[2][i][2]), end=" ")
       print(int(FACES[4][i][0]), int(FACES[4][i][1]), int(FACES[4][i][2]), end=" ")
       print(int(FACES[3][i][0]), int(FACES[3][i][1]), int(FACES[3][i][2]), end=" ")
       print(int(FACES[5][i][0]), int(FACES[5][i][1]), int(FACES[5][i][2]))
   for i in range(3):
       print("     ", int(FACES[1][i][0]), int(FACES[1][i][1]), int(FACES[1][i][2]))
   print()

def moves(FACES, lst):
   for x in lst:
       if x == 'U':
           U(faces)
       elif x == 'u':
           _U(faces)
       elif x == 'D':
           D(faces)
       elif x == 'd':
           _D(faces)
       elif x == 'L':
           L(faces)
       elif x == 'l':
           _L(faces)
       elif x == 'R':
           R(faces)
       elif x == 'r':
           _R(faces)
       elif x == 'F':
           F(faces)
       elif x == 'f':
           _F(faces)
       elif x == 'B':
           B(faces)
       elif x == 'b':
           _B(faces)

lst = input("请输入步骤:")
moves(faces, lst)
print("执行后的魔方为")
toString(faces)
reverse = ''.join(map(chr, map(lambda x: ord(x) ^ 32, lst)))[::-1]
moves(faces, reverse)
print("魔方恢复步骤:", reverse)
toString(faces)

示例


请输入步骤:UBLDFRULFDRULBGBVFDRLLBFLLDSSDBVDJFRUDLRFBDLFBbdj
执行后的魔方为

2 5 3
     5 0 2
     5 0 5
5 2 3 1 2 1 2 4 0 4 0 0
1 2 3 1 4 5 1 3 1 4 5 2
2 5 2 4 4 3 1 0 5 3 4 4
     1 0 4
     3 1 3
     0 3 0

魔方恢复步骤: JDBbfldbfrldurfjdvbdssdllfbllrdfvbgblurdflurfdlbu

0 0 0
     0 0 0
     0 0 0
2 2 2 4 4 4 3 3 3 5 5 5
2 2 2 4 4 4 3 3 3 5 5 5
2 2 2 4 4 4 3 3 3 5 5 5
     1 1 1
     1 1 1
     1 1 1

Process finished with exit code 0

注:大写为顺时针,小写为逆时针

来源:https://blog.csdn.net/weixin_44946961/article/details/116210122

标签:python,三阶魔方
0
投稿

猜你喜欢

  • 一个取图片尺寸的类,支持jpg,gif,png

    2007-10-18 10:25:00
  • 微信小程序与php 实现微信支付的简单实例

    2023-11-14 15:22:07
  • 也谈javascript程序优化问题

    2008-10-29 11:30:00
  • 倾斜的鼠标翻转导航制作上的烦恼

    2007-06-20 16:39:00
  • 上传组件 ASPUpload 使用说明

    2008-09-11 14:38:00
  • PHP格式化显示时间date()函数代码

    2023-06-10 17:55:01
  • 解决出现SoapFault (looks like we got no XML document)的问题

    2023-11-19 04:21:01
  • Python有序查找算法之二分法实例分析

    2023-04-09 00:02:37
  • PyQT5之使用QT Designer创建基本窗口方式

    2023-10-06 05:59:41
  • mysql myisam 优化设置

    2010-03-25 10:18:00
  • 在不能中寻找可能 QZONE个性相册设计的始末

    2009-07-13 12:27:00
  • asp如何读取服务器上的驱动器?

    2009-11-18 20:50:00
  • Sql Server表死锁的解决方法分享

    2011-09-01 19:08:00
  • 让你知道codepage的重要,关于多语言编码

    2008-01-31 12:04:00
  • 利用Python实现学生信息管理系统的完整实例

    2022-03-12 10:35:03
  • 以图换字的几个方法及思路

    2007-10-17 18:07:00
  • pygame编写音乐播放器的实现代码示例

    2021-08-12 18:08:48
  • response.setHeader()方法设置http文件头的值

    2010-03-11 22:43:00
  • 在ORACLE移动数据库文件

    2010-08-02 12:54:00
  • Go/Python/Erlang编程语言对比分析及示例代码

    2022-08-15 17:19:12
  • asp之家 网络编程 m.aspxhome.com