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])
每一个面的 顺时针 和 逆时针 旋转由函数 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°。这时,我们只需按顺序交换每一面的第一行,最后再逆时针或顺时针转回来即可。
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


猜你喜欢
- JSON 格式可以使对象(object)、数组(array)、值(value)、字符串(string)、数值(number)。 <sc
- 任意给出一个数,求该数以内的所有质数.(使用筛选法做的)先看看什么叫做质数?质数的定义:一个大于1的自然数,除了1与它自身外,再没有其它的正
- 安装pip install websocket-client先来看一下,长连接调用方式:ws = websocket.WebSocketAp
- 其实之前笔者写代码的时候用到模型的保存和加载,需要用的时候就去度娘搜一下大致代码,现在有时间就来整理下整个pytorch模型的保存和加载,开
- 【原文地址】My "First Look at Orcas" Presentation 【原文发表日期】 Th
- 使用cpan安装Net::SSH::Perl:cpan>install Net::SSH::Perl期间遇到了一些问题,记录在此,以备
- NumPy矩阵和向量矩阵在NumPy中,矩阵可以看作是一个二维数组,其中每个元素都可以通过行列坐标来定位。它表示为一个m×
- exec sp_configure 'show advanced options',1 reconfigure exec s
- 1、概述在《Golang常用语法糖》这篇博文中我们讲解Golang中常用的12种语法糖,在本文我们主要讲解下接收者方法语法糖。在介绍Gola
- 1、信息表新建立一个字段,并用0、1的方法判断信息的状态。 2、新建一个页面,定时刷新,并查询表中是否有字段值为0的记录。 3、当管理员点击
- 1、打开指定的网页地址我们使用selenium进行自动化测试时,打开浏览器之后,第一步就是让浏览器访问我们指定的地址,可使用get方法实现f
- docutils 的官方工具地址为:https://docutils.sourceforge.io/目前的更新主要是在版本和使用手册的更新上
- javascript的字符集:javascript程序是使用Unicode字符集编写的。Unicode是ASCII和Latin-1的超集,并
- 通过结构体生成jsonbuf, err := json.MarshalIndent(s, "", " &quo
- 前言在小程序中,e.target与e.currentTarget是非常重要的,尤其是涉及到页面传值时currentTarget和target
- 语法: ROW_NUMBER() OVER([ <partition_by_clause>] <order_by_clau
- 基本环境:Snow Leopard10.6.2,Oracle10.2.0.4打开Mac的终端,执行:sudo -i创建oinstall组和o
- 1.安装wkhtmltopdf下载地址:https://wkhtmltopdf.org/downloads.html我测试用的是window
- 在上一篇文章里已经写过如何安装python和在eclipse中配置python插件,这篇就不多说了,开始入门。1.先新建一个python工程
- 这是个“懒人”用的办法,你没有时间更新主页,却又不能让三个月前的更新还标着"new",那么用这个js可以帮你的大忙!这个