Ernö Rubiks Zauberwürfelalgorithmen (Algorithmen)
Schreiben Sie ein Programm, das von einem Algorithmus für den Zauberwürfel die Ordnugszahl ermittelt.
Die Ordnungszahl ist diejenige Anzahl, wie oft der Algorithmus ausgeführt werden muss, damit der Würfel in seinen Startzustand gelangt. Mit anderen Worten: Wenn ich einen gelösten Würfel habe und immer wieder den selben Algorithmus darauf anwende: Wie lange dauert es, bis der Würfel wieder gelöst ist.
Ein Algorithmus für den Zauberwürfel besteht aus verschiedenen Drehungen. Diese werden meist durch
links
rechts
hinten
vorne
oben
unten
und durch
90, 180 oder 270 Grad Drehungen angegeben.
Natürlich muss noch abgemacht werden ob die mittleren Ebenen auch gedreht werden dürfen, und in welche Richtung jeweils gedreht wird. Doch die Notation überlassen wir in dieser Aufgabe komplett der Programmiererin bzw. dem Programmierer.
Schreiben Sie also nun ein Programm, das einen Algorithmus in einer wohldefinierten Notation entgegen nimmt und den Algorithmus solange anwendet, bis der Würfel wieder gelöst ist. Die Ausgabe des Programmes ist dann die Ordnungszahl des Algorithmus.
Wer lernen will, wie man den Rubiks-Cube löst, kann sich hier schlau machen: https://www.youtube.com/watch?v=3hXWa6eeLSE
0 Kommentare
4 Lösung(en)
package ch.programmieraufgaben.algorithmen.rubiks;
import java.util.*;
/**
* @author phi@gress.ly
* @date 2018-10-15
*
* a) Change something like "r'U2Xb" to a sequence like
* [Move.r_INV, Move.U, Move.U, Move.X, Move.b]
* b) apply an array of Moves to a cube
* c) count how many times you have to apply your algorithmn until
* the cube is solved again (grade).
*/
public class CubeAlgorithm {
public static void main(String[] args) {
new CubeAlgorithm().top();
}
void top() {
Scanner sc = new Scanner(System.in);
System.out.println("Bitte Algorithmus eingeben:");
String algo = sc.nextLine().trim();
sc.close();
List<Move> moves = toMoveArray(algo);
CubeImplementation c = new CubeImplementation();
apply(c, moves);
System.out.println(c);
// move Count until solved again
long cnt = 1;
while(! c.isSolved()) {
apply(c, moves);
cnt++;
}
System.out.println("Algorithm grade: " + cnt + ".") ;
System.out.println("Move count : " + cnt*moves.size() + ".");
}
public void apply(CubeImplementation c, List<Move> algorithm) {
for(Move m : algorithm) {
//System.out.println("Applying " + m);
c.move(m);
}
}
/**
* Converts a Speedcuber String (eg. "RUDU") into a
* List of Moves (see enum Move below).
*/
public List<Move> toMoveArray(String algorithm) {
List<Move> algo = new ArrayList<Move>();
int readPos = 0;
while(readPos < algorithm.length()) {
char mv = algorithm.charAt(readPos);
char modifier = 0; // no Modifier found
if(readPos < algorithm.length() - 1) {
modifier = algorithm.charAt(readPos + 1);
if('\'' != modifier && '2' != modifier) {
// not a Modifier!
modifier = 0;
} else {
readPos++; // valid modifier found, so increase read pos
}
}
Move move;
if('\'' == modifier) {
move = findMoveByNameInverted(mv);
} else {
move = findMoveByName(mv);
}
if(null == move) {
System.out.println("ERROR IN ALGO: " + algorithm );
System.out.println(" at pos: " + (readPos+1));
return null;
}
if('2' == modifier) {
algo.add(move);
}
algo.add(move);
readPos++;
}
return algo;
}
private Move findMoveByName(char move) {
Move m = null;
if('R' == move) m = Move.R;
if('L' == move) m = Move.L;
if('B' == move) m = Move.B;
if('F' == move) m = Move.F;
if('D' == move) m = Move.D;
if('U' == move) m = Move.U;
if('r' == move) m = Move.r;
if('l' == move) m = Move.l;
if('b' == move) m = Move.b;
if('f' == move) m = Move.f;
if('d' == move) m = Move.d;
if('u' == move) m = Move.u;
if('X' == move) m = Move.X;
if('Y' == move) m = Move.Y;
if('Z' == move) m = Move.Z;
if('M' == move) m = Move.M;
if('E' == move) m = Move.E;
if('S' == move) m = Move.S;
if(null == m) {
System.out.println("ERROR: MOVE UNKNOWN: " + move);
}
return m;
}
private Move findMoveByNameInverted(char move) {
Move m = null;
if('R' == move) m = Move.R_INV;
if('L' == move) m = Move.L_INV;
if('B' == move) m = Move.B_INV;
if('F' == move) m = Move.F_INV;
if('D' == move) m = Move.D_INV;
if('U' == move) m = Move.U_INV;
if('r' == move) m = Move.r_INV;
if('l' == move) m = Move.l_INV;
if('b' == move) m = Move.b_INV;
if('f' == move) m = Move.f_INV;
if('d' == move) m = Move.d_INV;
if('u' == move) m = Move.u_INV;
if('X' == move) m = Move.X_INV;
if('Y' == move) m = Move.Y_INV;
if('Z' == move) m = Move.Z_INV;
if('M' == move) m = Move.M_INV;
if('E' == move) m = Move.E_INV;
if('S' == move) m = Move.S_INV;
if(null == m) {
System.out.println("ERROR: MOVE UNKNOWN: " + move);
}
return m;
}
} // end of class Cube
enum Move {
R , L , U , D , F , B ,
R_INV, L_INV, U_INV, D_INV, F_INV, B_INV,
r , l , u , d , f , b ,
r_INV, l_INV, u_INV, d_INV, f_INV, b_INV,
// M (middle) Mitte zwischen R & L (Richtung L)
// E (equator) Mitte zwischen U & D (Richtung D)
// S (standing) Mitte zwischen F & B (Richtung F)
M , E , S ,
M_INV, E_INV, S_INV,
// X, wie R, aber ganzer Würfel
// Y, wie U, aber ganzer Würfel
// Z, wie F, aber ganzer Würfel
X, Y, Z ,
X_INV, Y_INV, Z_INV;
} // end of enum Move
enum Color {
RED, GREEN, ORANGE, BLUE, WHITE, YELLOW;
} // end of enum Color
class CubeImplementation {
Color[][] cube;
public static void main(String[] args) {
new CubeImplementation().top();
}
public CubeImplementation() {
cube = new Color[12][9];
// orange:
cube[3][0] = cube[ 4][0] = cube[ 5][0] =
cube[3][1] = cube[ 4][1] = cube[ 5][1] =
cube[3][2] = cube[ 4][2] = cube[ 5][2] = Color.ORANGE;
// yellow:
cube[3][3] = cube[ 4][3] = cube[ 5][3] =
cube[3][4] = cube[ 4][4] = cube[ 5][4] =
cube[3][5] = cube[ 4][5] = cube[ 5][5] = Color.YELLOW;
// blue:
cube[0][3] = cube[ 1][3] = cube[ 2][3] =
cube[0][4] = cube[ 1][4] = cube[ 2][4] =
cube[0][5] = cube[ 1][5] = cube[ 2][5] = Color.BLUE;
// red;
cube[3][6] = cube[ 4][6] = cube[ 5][6] =
cube[3][7] = cube[ 4][7] = cube[ 5][7] =
cube[3][8] = cube[ 4][8] = cube[ 5][8] = Color.RED;
// green;
cube[6][3] = cube[ 7][3] = cube[ 8][3] =
cube[6][4] = cube[ 7][4] = cube[ 8][4] =
cube[6][5] = cube[ 7][5] = cube[ 8][5] = Color.GREEN;
// white;
cube[9][3] = cube[10][3] = cube[11][3] =
cube[9][4] = cube[10][4] = cube[11][4] =
cube[9][5] = cube[10][5] = cube[11][5] = Color.WHITE;
}
void printNet() {
System.out.println(this.toString());
}
String visible = "rgobwy";
@Override
public String toString() {
String representation = "";
for(int y = 0; y < 9; y++) {
for(int x = 0; x < 12; x ++) {
if(null == cube[x][y]) {
representation += "-";
} else {
representation += visible.charAt(cube[x][y].ordinal());
}
}
representation += '\n';
}
return representation;
}
void top() {
if(isConsistent()) {
System.out.println("Cube initialized");
} else {
System.out.println("Error in Cube Initilisition: not Consistent!");
return;
}
printNet();
int cnt = 1;
move(Move.Y);
move(Move.R); move(Move.B); move(Move.L); move(Move.F);
while(! isSolved()) {
cnt++;
move(Move.R); move(Move.B); move(Move.L); move(Move.F);
}
System.out.println("Used " +4*cnt+ " times the Algorithm = " + cnt + " movements");
printNet();
}
/** Netz des Cube:
-- -- -- 30 40 50 -- -- -- -- -- --
-- -- -- 31 41 51 -- -- -- -- -- --
-- -- -- 32 42 52 -- -- -- -- -- --
03 13 23 33 43 53 63 73 83 93 A3 B3
04 14 24 34 44 54 64 74 84 94 A4 B4
05 15 25 35 45 55 65 75 85 95 A5 B5
-- -- -- 36 46 56 -- -- -- -- -- --
-- -- -- 37 47 57 -- -- -- -- -- --
-- -- -- 38 48 58 -- -- -- -- -- --
*/
public void move(Move m) {
if(Move.r == m) {
move(Move.X); move(Move.L);
}
if(Move.r_INV == m) {move(Move.r); move(Move.r); move(Move.r);}
if(Move.f == m) {
move(Move.Z); move(Move.B);
}
if(Move.f_INV == m) {move(Move.f); move(Move.f); move(Move.f);}
if(Move.l == m) {
move(Move.X_INV); move(Move.R);
}
if(Move.l_INV == m) {move(Move.l); move(Move.l); move(Move.l);}
if(Move.b == m) {
move(Move.Z_INV); move(Move.F);
}
if(Move.b_INV == m) {move(Move.b); move(Move.b); move(Move.b); }
if(Move.u == m) {
move(Move.Y); move(Move.D);
}
if(Move.u_INV == m) {move(Move.u); move(Move.u); move(Move.u);}
if(Move.d == m) {
move(Move.Y_INV); move(Move.U);
}
if(Move.d_INV == m) {move(Move.d); move(Move.d); move(Move.d);}
if(Move.X == m) {
move(Move.L_INV); move(Move.M_INV); move(Move.R);
}
if(Move.X_INV == m) {move(Move.X); move(Move.X); move(Move.X);}
if(Move.Y == m) {
move(Move.D_INV); move(Move.E_INV); move(Move.U);
}
if(Move.Y_INV == m) {move(Move.Y); move(Move.Y); move(Move.Y);}
if(Move.Z == m) {
move(Move.F); move(Move.S); move(Move.B_INV);
}
if(Move.Z_INV == m) {move(Move.Z); move(Move.Z); move(Move.Z);}
if(Move.E == m) { // Equatorial
move("37>75>51>13");
move("47>74>41>14");
move("57>73>31>15");
}
if(Move.E_INV == m) {move(Move.E); move(Move.E); move(Move.E);}
if(Move.M == m) { // Middle
move("43>46>A5>40");
move("44>47>A4>41");
move("45>48>A3>42");
}
if(Move.M_INV == m) {move(Move.M); move(Move.M); move(Move.M);}
if(Move.S == m) { // Standing
move("34>64>94>04");
move("44>74>A4>14");
move("54>84>B4>24");
}
if(Move.S_INV == m) {move(Move.S); move(Move.S); move(Move.S);}
if(Move.R_INV == m) {move(Move.R); move(Move.R); move(Move.R);}
if(Move.L_INV == m) {move(Move.L); move(Move.L); move(Move.L);}
if(Move.D_INV == m) {move(Move.D); move(Move.D); move(Move.D);}
if(Move.U_INV == m) {move(Move.U); move(Move.U); move(Move.U);}
if(Move.F_INV == m) {move(Move.F); move(Move.F); move(Move.F);}
if(Move.B_INV == m) {move(Move.B); move(Move.B); move(Move.B);}
if(Move.D == m) { // D = Down
move("93>B3>B5>95");
move("A3>B4>A5>94");
move("83>30>05>58");
move("84>40>04>48");
move("85>50>03>38");
}
if(Move.B == m) { // B = back, not Bottom!
move("42>31>40>51");
move("32>30>50>52");
move("33>03>93>63");
move("43>13>A3>73");
move("53>23>B3>83");
}
if(Move.F == m) {
move("46>57>48>37");
move("56>58>38>36");
move("35>65>95>05");
move("45>75>A5>15");
move("55>85>B5>25");
}
if(Move.L == m) {
move("24>15>04>13");
move("23>25>05>03");
move("33>36>B5>30");
move("34>37>B4>31");
move("35>38>B3>32");
}
if(Move.R == m) {
move("64>73>84>75");
move("63>83>85>65");
move("53>50>95>56");
move("55>52>93>58");
move("54>51>94>57");
}
if(Move.U == m) {
move("33>53>55>35");
move("43>54>45>34");
move("42>64>46>24");
move("32>63>56>25");
move("52>65>36>23");
}
if(! isConsistent()) {
System.out.println("CubeImpl.move(): inconsistent move: " + m);
}
}
private void move(String seq) {
String[] seqArr = seq.split(">");
Color tmp = getColorFromStringDesc(seqArr[seqArr.length - 1]);
for(int pos = seqArr.length - 1; pos > 0; pos --) {
Color from = getColorFromStringDesc(seqArr[pos - 1]);
setColorToStringDesc(seqArr[pos], from);
}
setColorToStringDesc(seqArr[0], tmp);
}
private void setColorToStringDesc(String pos, Color col) {
int x = getPosFromStringDesc(pos.charAt(0));
int y = getPosFromStringDesc(pos.charAt(1));
cube[x][y] = col;
}
private Color getColorFromStringDesc(String pos) {
int x = getPosFromStringDesc(pos.charAt(0));
int y = getPosFromStringDesc(pos.charAt(1));
return cube[x][y];
}
private int getPosFromStringDesc(char ch) {
if('A' == ch || 'a' == ch) return 10;
if('B' == ch || 'b' == ch) return 11;
if(ch >= '0' && ch <= '9') {
return ch - '0';
}
System.out.println("ERROR: getPosFromString: " + ch + " not Known Position!");
return -1;
}
public boolean isSolved() {
if(!allMiddle( 1, 4)) return false;
if(!allMiddle( 4, 1)) return false;
if(!allMiddle( 4, 4)) return false;
if(!allMiddle( 4, 7)) return false;
if(!allMiddle( 7, 4)) return false;
if(!allMiddle(10, 4)) return false;
return true;
}
private boolean allMiddle(int xCenter, int yCenter) {
for(int x = xCenter-1; x <= xCenter+1; x++) {
for(int y = yCenter-1; y <= yCenter+1; y++) {
if(cube[x][y] != cube[xCenter][yCenter]) {
return false;
}
}
}
return true;
}
public Color get(int x, int y) {
return this.cube[x][y];
}
public boolean isConsistent() {
// check count of each color:
int reds, greens, blues, oranges, yellows, whites;
reds = greens = blues = oranges = yellows = whites = 0;
for(int x = 0; x < 12; x++) {
for(int y = 0; y < 9; y ++) {
if(cube[x][y] == Color.RED ) reds ++;
if(cube[x][y] == Color.GREEN ) greens ++;
if(cube[x][y] == Color.BLUE ) blues ++;
if(cube[x][y] == Color.ORANGE) oranges++;
if(cube[x][y] == Color.YELLOW) yellows++;
if(cube[x][y] == Color.WHITE ) whites ++;
}
}
if(9 != reds || 9 != greens || 9 != blues ||
9 != oranges || 9 != yellows || 9 != whites) {
System.out.println("color count failed: inconsistent");
return false;
}
return true;
}
} // end of class CubeImplementation
Lösung von: Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch)
from copy import deepcopy
class Cube:
def __init__(self):
self.f = [[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8]] # front
self.r = [[10, 11, 12],
[13, 14, 15],
[16, 17, 18]] # right
self.u = [[20, 21, 22],
[23, 24, 25],
[26, 27, 28]] # up
self.b = [[30, 31, 32],
[33, 34, 35],
[36, 37, 38]] # back
self.l = [[40, 41, 42],
[43, 44, 45],
[46, 47, 48]] # left
self.d = [[50, 51, 52],
[53, 54, 55],
[56, 57, 58]] # down
def parser(self, s, original):
finished = 0
s = s.upper()
counter = 0
while finished == 0:
for i in range(0, len(s)):
if s[i] == 'F':
try:
if s[i + 1] == "'":
self.do_f_ccw()
elif s[i + 1] == '2':
self.do_f()
self.do_f()
else:
self.do_f()
except IndexError:
self.do_f()
if s[i] == 'R':
try:
if s[i + 1] == "'":
self.do_r_ccw()
elif s[i + 1] == '2':
self.do_r()
self.do_r()
else:
self.do_r()
except IndexError:
self.do_r()
if s[i] == 'U':
try:
if s[i + 1] == "'":
self.do_u_ccw()
elif s[i + 1] == '2':
self.do_u()
self.do_u()
else:
self.do_u()
except IndexError:
self.do_u()
if s[i] == 'B':
try:
if s[i + 1] == "'":
self.do_b_ccw()
elif s[i + 1] == '2':
self.do_b()
self.do_b()
else:
self.do_b()
except IndexError:
self.do_b()
if s[i] == 'L':
try:
if s[i + 1] == "'":
self.do_l_ccw()
elif s[i + 1] == '2':
self.do_l()
self.do_l()
else:
self.do_l()
except IndexError:
self.do_l()
if s[i] == 'D':
try:
if s[i + 1] == "'":
self.do_d_ccw()
elif s[i + 1] == '2':
self.do_d()
self.do_d()
else:
self.do_d()
except IndexError:
self.do_d()
counter += 1
if self.compare(original) == 0:
return counter
# deprecated
def deep_compare_helper(self, l):
return frozenset(frozenset(p) for p in l)
def compare(self, cube):
if (self.f == cube.f and
self.r == cube.r and
self.u == cube.u and
self.b == cube.b and
self.l == cube.l and
self.d == cube.d):
return 0
return 1
def do_f(self):
# print('f')
temp_f = deepcopy(self.f)
temp_u = deepcopy(self.u)
temp_r = deepcopy(self.r)
temp_d = deepcopy(self.d)
temp_l = deepcopy(self.l)
temp_b = deepcopy(self.b)
self.f = [[temp_f[2][0], temp_f[1][0], temp_f[0][0]],
[temp_f[2][1], temp_f[1][1], temp_f[0][1]],
[temp_f[2][2], temp_f[1][2], temp_f[0][2]]]
self.r[0][0] = temp_u[2][0]
self.r[1][0] = temp_u[2][1]
self.r[2][0] = temp_u[2][2]
self.d[0][0] = temp_r[2][0]
self.d[0][1] = temp_r[1][0]
self.d[0][2] = temp_r[0][0]
self.l[0][2] = temp_d[0][0]
self.l[1][2] = temp_d[0][1]
self.l[2][2] = temp_d[0][2]
self.u[2][0] = temp_l[2][2]
self.u[2][1] = temp_l[1][2]
self.u[2][2] = temp_l[0][2]
def do_f_ccw(self):
# print('f-')
temp_f = deepcopy(self.f)
temp_u = deepcopy(self.u)
temp_r = deepcopy(self.r)
temp_d = deepcopy(self.d)
temp_l = deepcopy(self.l)
temp_b = deepcopy(self.b)
self.f = [[temp_f[0][2], temp_f[1][2], temp_f[2][2]],
[temp_f[0][1], temp_f[1][1], temp_f[2][1]],
[temp_f[0][0], temp_f[1][0], temp_f[2][0]]]
self.r[0][0] = temp_d[0][2]
self.r[1][0] = temp_d[0][1]
self.r[2][0] = temp_d[0][0]
self.d[0][0] = temp_l[0][2]
self.d[0][1] = temp_l[1][2]
self.d[0][2] = temp_l[2][2]
self.l[0][2] = temp_u[2][2]
self.l[1][2] = temp_u[2][1]
self.l[2][2] = temp_u[2][0]
self.u[2][0] = temp_r[0][0]
self.u[2][1] = temp_r[1][0]
self.u[2][2] = temp_r[2][0]
def do_r(self):
# print('r')
temp_f = deepcopy(self.f)
temp_u = deepcopy(self.u)
temp_r = deepcopy(self.r)
temp_d = deepcopy(self.d)
temp_l = deepcopy(self.l)
temp_b = deepcopy(self.b)
self.r = [[temp_r[2][0], temp_r[1][0], temp_r[0][0]],
[temp_r[2][1], temp_r[1][1], temp_r[0][1]],
[temp_r[2][2], temp_r[1][2], temp_r[0][2]]]
self.b[0][0] = temp_u[2][2]
self.b[1][0] = temp_u[1][2]
self.b[2][0] = temp_u[0][2]
self.d[0][2] = temp_b[2][0]
self.d[1][2] = temp_b[1][0]
self.d[2][2] = temp_b[0][0]
self.f[0][2] = temp_d[0][2]
self.f[1][2] = temp_d[1][2]
self.f[2][2] = temp_d[2][2]
self.u[0][2] = temp_f[0][2]
self.u[1][2] = temp_f[1][2]
self.u[2][2] = temp_f[2][2]
def do_r_ccw(self):
# print('r-')
temp_f = deepcopy(self.f)
temp_u = deepcopy(self.u)
temp_r = deepcopy(self.r)
temp_d = deepcopy(self.d)
temp_l = deepcopy(self.l)
temp_b = deepcopy(self.b)
self.r = [[temp_r[0][2], temp_r[1][2], temp_r[2][2]],
[temp_r[0][1], temp_r[1][1], temp_r[2][1]],
[temp_r[0][0], temp_r[1][0], temp_r[2][0]]]
self.b[0][0] = temp_d[2][2]
self.b[1][0] = temp_d[1][2]
self.b[2][0] = temp_d[0][2]
self.d[0][2] = temp_f[0][2]
self.d[1][2] = temp_f[1][2]
self.d[2][2] = temp_f[2][2]
self.f[0][2] = temp_u[0][2]
self.f[1][2] = temp_u[1][2]
self.f[2][2] = temp_u[2][2]
self.u[0][2] = temp_b[2][0]
self.u[1][2] = temp_b[1][0]
self.u[2][2] = temp_b[0][0]
def do_u(self):
# print('u')
temp_f = deepcopy(self.f)
temp_u = deepcopy(self.u)
temp_r = deepcopy(self.r)
temp_d = deepcopy(self.d)
temp_l = deepcopy(self.l)
temp_b = deepcopy(self.b)
self.u = [[temp_u[2][0], temp_u[1][0], temp_u[0][0]],
[temp_u[2][1], temp_u[1][1], temp_u[0][1]],
[temp_u[2][2], temp_u[1][2], temp_u[0][2]]]
self.b[0][0] = temp_l[0][0]
self.b[0][1] = temp_l[0][1]
self.b[0][2] = temp_l[0][2]
self.r[0][0] = temp_b[0][0]
self.r[0][1] = temp_b[0][1]
self.r[0][2] = temp_b[0][2]
self.f[0][0] = temp_r[0][0]
self.f[0][1] = temp_r[0][1]
self.f[0][2] = temp_r[0][2]
self.l[0][0] = temp_f[0][0]
self.l[0][1] = temp_f[0][1]
self.l[0][2] = temp_f[0][2]
def do_u_ccw(self):
# print('u-')
temp_f = deepcopy(self.f)
temp_u = deepcopy(self.u)
temp_r = deepcopy(self.r)
temp_d = deepcopy(self.d)
temp_l = deepcopy(self.l)
temp_b = deepcopy(self.b)
self.u = [[temp_u[0][2], temp_u[1][2], temp_u[2][2]],
[temp_u[0][1], temp_u[1][1], temp_u[2][1]],
[temp_u[0][0], temp_u[1][0], temp_u[2][0]]]
self.b[0][0] = temp_r[0][0]
self.b[0][1] = temp_r[0][1]
self.b[0][2] = temp_r[0][2]
self.r[0][0] = temp_f[0][0]
self.r[0][1] = temp_f[0][1]
self.r[0][2] = temp_f[0][2]
self.f[0][0] = temp_l[0][0]
self.f[0][1] = temp_l[0][1]
self.f[0][2] = temp_l[0][2]
self.l[0][0] = temp_b[0][0]
self.l[0][1] = temp_b[0][1]
self.l[0][2] = temp_b[0][2]
def do_b(self):
# print('b')
temp_f = deepcopy(self.f)
temp_u = deepcopy(self.u)
temp_r = deepcopy(self.r)
temp_d = deepcopy(self.d)
temp_l = deepcopy(self.l)
temp_b = deepcopy(self.b)
self.b = [[temp_b[2][0], temp_b[1][0], temp_b[0][0]],
[temp_b[2][1], temp_b[1][1], temp_b[0][1]],
[temp_b[2][2], temp_b[1][2], temp_b[0][2]]]
self.u[0][0] = temp_r[0][2]
self.u[0][1] = temp_r[1][2]
self.u[0][2] = temp_r[2][2]
self.l[0][0] = temp_u[0][2]
self.l[1][0] = temp_u[0][1]
self.l[2][0] = temp_u[0][0]
self.d[2][0] = temp_l[0][0]
self.d[2][1] = temp_l[1][0]
self.d[2][2] = temp_l[2][0]
self.r[0][2] = temp_d[2][2]
self.r[1][2] = temp_d[2][1]
self.r[2][2] = temp_d[2][0]
def do_b_ccw(self):
# print('b-')
temp_f = deepcopy(self.f)
temp_u = deepcopy(self.u)
temp_r = deepcopy(self.r)
temp_d = deepcopy(self.d)
temp_l = deepcopy(self.l)
temp_b = deepcopy(self.b)
self.b = [[temp_b[0][2], temp_b[1][2], temp_b[2][2]],
[temp_b[0][1], temp_b[1][1], temp_b[2][1]],
[temp_b[0][0], temp_b[1][0], temp_b[2][0]]]
self.u[0][0] = temp_l[2][0]
self.u[0][1] = temp_l[1][0]
self.u[0][2] = temp_l[0][0]
self.l[0][0] = temp_d[2][0]
self.l[1][0] = temp_d[2][1]
self.l[2][0] = temp_d[2][2]
self.d[2][0] = temp_r[0][2]
self.d[2][1] = temp_r[1][2]
self.d[2][2] = temp_r[2][2]
self.r[0][2] = temp_u[0][0]
self.r[1][2] = temp_u[0][1]
self.r[2][2] = temp_u[0][2]
def do_l(self):
# print('l')
temp_f = deepcopy(self.f)
temp_u = deepcopy(self.u)
temp_r = deepcopy(self.r)
temp_d = deepcopy(self.d)
temp_l = deepcopy(self.l)
temp_b = deepcopy(self.b)
self.l = [[temp_l[2][0], temp_l[1][0], temp_l[0][0]],
[temp_l[2][1], temp_l[1][1], temp_l[0][1]],
[temp_l[2][2], temp_l[1][2], temp_l[0][2]]]
self.u[0][0] = temp_b[2][2]
self.u[1][0] = temp_b[1][2]
self.u[2][0] = temp_b[0][2]
self.f[0][0] = temp_u[0][0]
self.f[1][0] = temp_u[1][0]
self.f[2][0] = temp_u[2][0]
self.d[0][0] = temp_f[0][0]
self.d[1][0] = temp_f[1][0]
self.d[2][0] = temp_f[2][0]
self.b[0][2] = temp_d[2][0]
self.b[1][2] = temp_d[1][0]
self.b[2][2] = temp_d[0][0]
def do_l_ccw(self):
# print('l-')
temp_f = deepcopy(self.f)
temp_u = deepcopy(self.u)
temp_r = deepcopy(self.r)
temp_d = deepcopy(self.d)
temp_l = deepcopy(self.l)
temp_b = deepcopy(self.b)
self.l = [[temp_l[0][2], temp_l[1][2], temp_l[2][2]],
[temp_l[0][1], temp_l[1][1], temp_l[2][1]],
[temp_l[0][0], temp_l[1][0], temp_l[2][0]]]
self.u[0][0] = temp_f[0][0]
self.u[1][0] = temp_f[1][0]
self.u[2][0] = temp_f[2][0]
self.f[0][0] = temp_d[0][0]
self.f[1][0] = temp_d[1][0]
self.f[2][0] = temp_d[2][0]
self.d[0][0] = temp_b[2][2]
self.d[1][0] = temp_b[1][2]
self.d[2][0] = temp_b[0][2]
self.b[0][2] = temp_u[2][0]
self.b[1][2] = temp_u[1][0]
self.b[2][2] = temp_u[0][0]
def do_d(self):
# print('d')
temp_f = deepcopy(self.f)
temp_u = deepcopy(self.u)
temp_r = deepcopy(self.r)
temp_d = deepcopy(self.d)
temp_l = deepcopy(self.l)
temp_b = deepcopy(self.b)
self.d = [[temp_d[2][0], temp_d[1][0], temp_d[0][0]],
[temp_d[2][1], temp_d[1][1], temp_d[0][1]],
[temp_d[2][2], temp_d[1][2], temp_d[0][2]]]
self.f[2][0] = temp_l[2][0]
self.f[2][1] = temp_l[2][1]
self.f[2][2] = temp_l[2][2]
self.r[2][0] = temp_f[2][0]
self.r[2][1] = temp_f[2][1]
self.r[2][2] = temp_f[2][2]
self.b[2][0] = temp_r[2][0]
self.b[2][1] = temp_r[2][1]
self.b[2][2] = temp_r[2][2]
self.l[2][0] = temp_b[2][0]
self.l[2][1] = temp_b[2][1]
self.l[2][2] = temp_b[2][2]
def do_d_ccw(self):
# print('d-')
temp_f = deepcopy(self.f)
temp_u = deepcopy(self.u)
temp_r = deepcopy(self.r)
temp_d = deepcopy(self.d)
temp_l = deepcopy(self.l)
temp_b = deepcopy(self.b)
self.d = [[temp_d[0][2], temp_d[1][2], temp_d[2][2]],
[temp_d[0][1], temp_d[1][1], temp_d[2][1]],
[temp_d[0][0], temp_d[1][0], temp_d[2][0]]]
self.f[2][0] = temp_r[2][0]
self.f[2][1] = temp_r[2][1]
self.f[2][2] = temp_r[2][2]
self.r[2][0] = temp_b[2][0]
self.r[2][1] = temp_b[2][1]
self.r[2][2] = temp_b[2][2]
self.b[2][0] = temp_l[2][0]
self.b[2][1] = temp_l[2][1]
self.b[2][2] = temp_l[2][2]
self.l[2][0] = temp_f[2][0]
self.l[2][1] = temp_f[2][1]
self.l[2][2] = temp_f[2][2]
original_cube = Cube()
while 1:
algorithm_cube = Cube()
string = input('gimme some cool algorithm to test: ')
tries = algorithm_cube.parser(string, cube_original)
print('had to use the algorithm {0} times'.format(tries))
Lösung von: Ich Bins (tubs)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Zauberwürfel Ordnungszahl
https://www.programmieraufgaben.ch/aufgabe/ernoe-rubiks-zauberwuerfelalgorithmen/vymwb4k7
"""
# Programmieraufgabe:
# Schreiben Sie ein Programm, das von einem Algorithmus für den Zauberwürfel
# die Ordnugszahl ermittelt.
# Rubiks Cube
# Die Ordnungszahl ist diejenige Anzahl, wie oft der Algorithmus ausgeführt
# werden muss, damit der Würfel in seinen Startzustand gelangt. Mit anderen
# Worten: Wenn ich einen gelösten Würfel habe und immer wieder den selben
# Algorithmus darauf anwende: Wie lange dauert es, bis der Würfel wieder
# gelöst ist.
#
# Autor, Erstellung:
# Ulrich Berntien, 2018-06-08
#
# Sprache:
# Python 3.6.6
import re
from typing import *
# Der Zauberwürfel besteht außen aus 26 Steinen. Jeder Stein ist eindeutig
# durch seine Farben (ein bis drei Farben je Element) identifiziert.
# Die Steine liegen auf einem 3x3x3 Gitter im Raum.
# Von einem Stein muss seine Position und seine Orientierung beachtet werden.
# Anstelle einer farbigen Seite eines Steins könte der Stein auch eine farbige
# Kugel auf seiner Seite haben. Diese farbigen Kugeln würden auf einem 5x5x5
# Gitters im Raum liegen.
# Anstelle der Bewegungen der Steine können die Bewegungen der farbigen Kugel
# beobachtet werden. Von diesen farbigen Kugel müssen nur die Positionen, nicht
# die Orientierungen betrachtet werden.
# In der Klasse Cube wird der Raum, das 5x5x5 Gitter, in einem Feld dargestellt.
# Jede der farbigen Kugeln wird durch eine Nummer identifiziert. Die Nummer im
# Feld bedeutet eine Kugel an dem entsprechenden Ort des Gitters.
# Das 5x5x5 Gitter wird in einer Liste mit 125 dargestellt.
# Die räumlichen Positionen (x,y,z) werden dem Index in der Liste durch die Methode
# 'xyz_to_index' zugeordnet. Jede Koordinate kann die Werte 0,1,2 annehmen. Die x-Achse ist
# nach rechts, die y-Achse nach hinten und die z-Achse nach oben gerichtet.
# Im Startzustand ist im Feld mit dem Index i der Stein mit Nummer i enthalten. Beim
# Drehen verändert sich der Inhalt der Liste 'elements'.
# Für jede Seite des Würfels wird eine Drehfunktion 'rotation_up" usw. bei der
# Initialisierung erzeugt. Die Drehfunktionen arbeiten mit einfachen Tabellen
# in der Art 'von Feld i - nach Feld j'.
def xyz_to_index(xyz: Tuple[int, int, int]) -> int:
"""
Umrechung der Koordinaten in Indexnummer in der Liste.
:param xyz: x Koordinate x,y,z jeweils im Bereich 0 bis 4
:return: Index in der Liste 0...124
"""
assert all(0 <= xyz[i] < 5 for i in range(3))
return ((xyz[2] * 5) + xyz[1]) * 5 + xyz[0]
def index_to_xyz(index: int) -> Tuple[int, int, int]:
"""
Index in der Liste umgerechnet in x,y,z Koordinate.
:param index: Index in der Liste
:return: Die Koordinate x,y,z des zugeordneten Punkts
"""
assert 0 <= index < 125
return index % 5, index // 5 % 5, index // 25
def index_to_str(i: int) -> str:
"""
Indexnummer in kompakte String-Darstellung 'xyz' umwandeln.
Die kompakte String-Darstellung ist anschaulicher als die Index-Nummer.
"""
assert 0 <= i < 125
return str(i % 5) + str((i // 5) % 5) + str(i // 25)
def _generate_rot(source: List[int], dest90: List[int], dest180: List[int], dest270: List[int]) \
-> Callable[[object, int], None]:
"""
Erzeugt eine Drehfunktion basierend auf den Übertragungstabellen.
:param source: Liste der Index-Nummer der Felder die verschoben werden.
:param dest90: Für 90° Rotation: Liste der Index-Nummern auf die die Felder kommen.
:param dest180: Für 180° Rotation: Liste der Index-Nummern auf die die Felder kommen.
:param dest270: Für 200° Rotation: Liste der Index-Nummern auf die die Felder kommen.
:return: Funktion für die Rotation des Würfels mit Drehwinkel in Grad als Argument.
"""
assert len(source) == len(dest90) == len(dest180) == len(dest270)
def rotation(cube: object, angle: int) -> None:
"""
Rotation um 0, +/-90, +/-180 oder +/-270 Grad.
:param cube: Eine Seite dieses Würfels wird gedreht.
:param angle: Um diesen Winkel wird gedreht.
"""
angle %= 360
if angle == 90:
cube.move(source, dest90)
elif angle == 180:
cube.move(source, dest180)
elif angle == 270:
cube.move(source, dest270)
elif angle == 0:
pass
else:
raise ValueError("invalid angle")
return rotation
def rotation_plane(xyz: Tuple[int, int, int]) -> Tuple[int, int, int]:
"""
Rotation des Punktes xyz um 90° im Uhrzeigersinn
um eine z-parallele Achse durch den Punkt (2,2.0).
:param xyz: Diesen Punkt rotieren.
:return: Die Koordinaten nach der Rotation.
"""
return xyz[1], 4 - xyz[0], xyz[2]
def _generate_rotation(side_to_xyz: Callable[[Tuple[int, int, int]], Tuple[int, int, int]]) -> \
Callable[[object, int], None]:
"""
Erzeugt die Drehfunktion für eine Seite des Würfels.
:param side_to_xyz: Liefert die Koordinaten x,y,z für einen Stein im Würfel
als Funktion der x,y,z Koordinaten für einen Stein auf der Seite.
:return: Funktion für die Rotation der Seite mit Parameter: Würfel, Winkel in Grad
"""
# Die Koordinaten der Farbkugeln auf der Seite und an den Rändern der Seite
side = [(x, y, 1) for x in range(1, 4) for y in range(1, 4)] + \
[(x, 0, 0) for x in range(1, 4)] + \
[(x, 4, 0) for x in range(1, 4)] + \
[(0, y, 0) for y in range(1, 4)] + \
[(4, y, 0) for y in range(1, 4)]
# Die Index-Nummer der Felder in der Seite
source = [xyz_to_index(side_to_xyz(xyz)) for xyz in side]
# Diese Felder werden bei 90° Rotation im Uhrzeigersinn zu den Feldern
destination90 = [xyz_to_index(side_to_xyz(rotation_plane(xyz))) for xyz in side]
# in 90° Schritte weiterdrehen. Der Drehwinkel wird um die x,y oder z-Achse angegeben.
# Bei positivem Winkel wird im Uhrzeigersinn gedreht.
destination180 = [xyz_to_index(side_to_xyz(rotation_plane(rotation_plane(xyz)))) for xyz in side]
destination270 = [xyz_to_index(side_to_xyz(rotation_plane(rotation_plane(rotation_plane(xyz))))) for xyz in side]
return _generate_rot(source, destination90, destination180, destination270)
class Cube:
"""
Würfel mit Drehoperationen.
"""
# Der Index in dem Feld folgt über xyz_to_index aus ein Ort im Raum.
# Der Wert des Elements i ist die Nummer des Objeks, der an dem Ort i ist.
elements: ByteString
@property
def is_initial_state(self) -> bool:
"""
Zustand des Würfels mit dem Startzustand vergleichen.
:return: True genau dann, wenn der Würfel im Startzustand ist.
"""
return self.elements == Cube._initial_state
def __repr__(self) -> str:
"""
Die Codenummer der farbigen Kugeln am Würel werden als kompakte Koordinate ausgegeben.
:return: Der Zustand des Würfel. Obere, mittlere und untere Seite.
"""
accu = ""
for z in range(4, -1, -1):
for y in range(4, -1, -1):
for x in range(5):
if 4 <= (2 - x) ** 2 + (2 - y) ** 2 + (2 - z) ** 2 <= 6:
accu += index_to_str(self.elements[xyz_to_index((x, y, z))]) + " "
else:
accu += " . "
accu += "\n"
accu += "\n"
# Das \n am Stringende nicht zurückgeben
return accu[:-2]
def move(self, source: List[int], destination: List[int]) -> None:
"""
Drehen einer Seite anhand einer Bewegungstabelle.
"""
assert len(source) == len(destination)
# Kopieren über Zwischenspeicher, weil die Bereiche überlappen.
buffer = self.elements[:]
for source_index, destination_index in zip(source, destination):
self.elements[destination_index] = buffer[source_index]
# Inhalt des elements Felds, wenn der Würfel im Start-Zustand ist.
_initial_state = bytes(range(5 * 5 * 5))
# Funktionen für die Rotationen der einzelnen Seiten
rotation_up = _generate_rotation(lambda xyz: (xyz[0], xyz[1], 3 + xyz[2]))
rotation_down = _generate_rotation(lambda xyz: (xyz[1], xyz[0], 1 - xyz[2]))
rotation_right = _generate_rotation(lambda xyz: (3 + xyz[2], xyz[0], xyz[1]))
rotation_left = _generate_rotation(lambda xyz: (1 - xyz[2], xyz[1], xyz[0]))
rotation_back = _generate_rotation(lambda xyz: (xyz[1], 3 + xyz[2], xyz[0]))
rotation_front = _generate_rotation(lambda xyz: (xyz[0], 1 - xyz[2], xyz[1]))
def __init__(self) -> None:
"""
Erzeugt den Würfel im Startzustand.
"""
self.elements = bytearray(Cube._initial_state)
class CubeCodes:
"""Interpretieren der Cube Rotationen in Zeichenkette."""
# Tabelle der Rotationsfunktionen für jeden Codebuchstaben.
rotation_table: Dict[str, Callable[[Cube, int], None]] = {
"F": Cube.rotation_front,
"B": Cube.rotation_back,
"R": Cube.rotation_right,
"L": Cube.rotation_left,
"U": Cube.rotation_up,
"D": Cube.rotation_down}
# Tabelle der Rotationswinkel für jeden Zeichencode.
angle_table: Dict[str, int] = {"": 90, "'": -90, "2": 180, "'2": -180}
@classmethod
def compile_code(cls, code: str) -> Callable[[Cube], None]:
"""
Übersetzt einen BewegungsCode in einen Aufruf einer Drehfunktion.
Die Codes der einzelnen Rotationen nach https://speedcube.de/notation.php:
F = front, B = back, R = right, L = left, U = up, D = down
Dem Buchstaben für die Rotation kann ein Zeichen für den Winkel folgen:
kein Zeichen = 90°, ' = -90°, 2 = 180°, '2 = -180°
"""
try:
code = code.strip()
rotation = cls.rotation_table[code[0:1]]
angle = cls.angle_table[code[1:]]
return lambda cube: rotation(cube, angle)
except KeyError:
raise RuntimeError("falscher Bewegungscode: " + code)
@classmethod
def compile_algorithmus(cls, algorithm: str) -> Callable[[Cube], None]:
"""
Übersetzt einen Algorithmus-Code in eine Funktion mit dem Drehungen.
Einzelne Rotationen können mit einem Leerzeichen getrennt sein.
Die Codes sind in der Funktion compile_code beschrieben.
:param algorithm: Algorithmus als String.
:return: Algorithmus in eine Funktion übersetzt.
"""
program = [cls.compile_code(step) for step in re.split("([A-Z]'?2?)", algorithm) if step.istitle()]
def run(cube: Cube) -> None:
for step in program:
step(cube)
return run
def calculate_number(algorithm: Callable[[Cube], None]) -> int:
"""
Berechnen der Ordnungszahl.
:param algorithm: Der Algorithmus in einer Funktion auf dem Würfel.
:return: Die Ordnungszahl des Algorithmus.
"""
cube = Cube()
assert cube.is_initial_state
algorithm(cube)
result: Int = 1
while not cube.is_initial_state:
algorithm(cube)
result += 1
return result
test_cases = ("R", # 4
"L", # 4
"U", # 4
"D", # 4
"F", # 4
"B", # 4
"R L", # 4
"U D", # 4
"F B", # 4
"R2 U R2", # 4
"R' D' R D", # 6
"UUR'LLDDB'R'U'B'R'U'B'R'U", # 336
"RUR'", # 4
"RULD", # 315
"RUF", # 80
"RUF2", # 36
"RUUFU") # 420
for test in test_cases:
algo = CubeCodes.compile_algorithmus(test)
number = calculate_number(algo)
print("Algorithmus: {:15} Ordnungszahl: {:4}".format(test, number))
Lösung von: Ulrich Berntien ()
f = [[0,0,0],[0,0,0],[0,0,0]] # Definiere Seiten des Würfels als 3x3 Matrizen
b = [[1,1,1],[1,1,1],[1,1,1]]
l = [[2,2,2],[2,2,2],[2,2,2]]
r = [[3,3,3],[3,3,3],[3,3,3]]
u = [[4,4,4],[4,4,4],[4,4,4]]
d = [[5,5,5],[5,5,5],[5,5,5]]
cube =[f,b,l,r,u,d] # Zusammenfassung der Matrizen zu Einem Würfel
from copy import deepcopy
def F(cube): # Definiere Operationen auf dem Würfel
f= cube[0]
b= cube[1]
l= cube[2]
r= cube[3]
u= cube[4]
d= cube[5]
tempf = deepcopy(cube[0])
tempb = deepcopy(cube[1])
templ = deepcopy(cube[2])
tempr = deepcopy(cube[3])
tempu = deepcopy(cube[4])
tempd = deepcopy(cube[5])
f[0][2]= tempf[0][0] # Austausch der Elemente gemäß Rotationsvorgaben
f[2][2]= tempf[0][2]
f[2][0]= tempf[2][2]
f[0][0]= tempf[2][0]
f[1][2]= tempf[0][1]
f[2][1]= tempf[1][2]
f[1][0]= tempf[2][1]
f[0][1]= tempf[1][0]
r[2][0]= tempu[2][0]
d[0][2]= tempr[2][0]
l[2][0]= tempd[0][2]
u[2][0]= templ[2][0]
r[2][1]= tempu[2][1]
d[0][1]= tempr[2][1]
l[2][1]= tempd[0][1]
u[2][1]= templ[2][1]
r[2][2]= tempu[2][2]
d[0][0]= tempr[2][2]
l[2][2]= tempd[0][0]
u[2][2]= templ[2][2]
cube =[f,b,l,r,u,d]
return cube
def L(cube): # Definiere Operationen auf dem Würfel
f= cube[0]
b= cube[1]
l= cube[2]
r= cube[3]
u= cube[4]
d= cube[5]
tempf = deepcopy(cube[0])
tempb = deepcopy(cube[1])
templ = deepcopy(cube[2])
tempr = deepcopy(cube[3])
tempu = deepcopy(cube[4])
tempd = deepcopy(cube[5])
l[0][2]= templ[0][0] # Austausch der Elemente gemäß Rotationsvorgaben
l[2][2]= templ[0][2]
l[2][0]= templ[2][2]
l[0][0]= templ[2][0]
l[1][2]= templ[0][1]
l[2][1]= templ[1][2]
l[1][0]= templ[2][1]
l[0][1]= templ[1][0]
f[0][0]= tempu[0][0]
d[0][0]= tempf[0][0]
b[0][0]= tempd[0][0]
u[0][0]= tempb[0][0]
f[1][0]= tempu[1][0]
d[1][0]= tempf[1][0]
b[1][0]= tempd[1][0]
u[1][0]= tempb[1][0]
f[2][0]= tempu[2][0]
d[2][0]= tempf[2][0]
b[2][0]= tempd[2][0]
u[2][0]= tempb[2][0]
cube =[f,b,l,r,u,d]
return cube
def R(cube):
f= cube[0]
b= cube[1]
l= cube[2]
r= cube[3]
u= cube[4]
d= cube[5]
tempf = deepcopy(cube[0])
tempb = deepcopy(cube[1])
templ = deepcopy(cube[2])
tempr = deepcopy(cube[3])
tempu = deepcopy(cube[4])
tempd = deepcopy(cube[5])
r[0][2]= tempr[0][0]
r[2][2]= tempr[0][2]
r[2][0]= tempr[2][2]
r[0][0]= tempr[2][0]
r[1][2]= tempr[0][1]
r[2][1]= tempr[1][2]
r[1][0]= tempr[2][1]
r[0][1]= tempr[1][0]
u[0][2]= tempf[0][2]
b[0][2]= tempu[0][2]
d[0][2]= tempb[0][2]
f[0][2]= tempd[0][2]
u[1][2]= tempf[1][2]
b[1][2]= tempu[1][2]
d[1][2]= tempb[1][2]
f[1][2]= tempd[1][2]
u[2][2]= tempf[2][2]
b[2][2]= tempu[2][2]
d[2][2]= tempb[2][2]
f[2][2]= tempd[2][2]
cube =[f,b,l,r,u,d]
return cube
def U(cube):
f= cube[0]
b= cube[1]
l= cube[2]
r= cube[3]
u= cube[4]
d= cube[5]
tempf = deepcopy(cube[0])
tempb = deepcopy(cube[1])
templ = deepcopy(cube[2])
tempr = deepcopy(cube[3])
tempu = deepcopy(cube[4])
tempd = deepcopy(cube[5])
u[0][2]= tempu[0][0]
u[2][2]= tempu[0][2]
u[2][0]= tempu[2][2]
u[0][0]= tempu[2][0]
u[1][2]= tempu[0][1]
u[2][1]= tempu[1][2]
u[1][0]= tempu[2][1]
u[0][1]= tempu[1][0]
l[2][2]= tempf[0][2]
b[2][0]= templ[2][2]
r[0][0]= tempb[2][0]
f[0][2]= tempr[0][0]
l[1][2]= tempf[0][1]
b[2][1]= templ[1][2]
r[1][0]= tempb[2][1]
f[0][1]= tempr[1][0]
l[0][2]= tempf[0][0]
b[2][2]= templ[0][2]
r[2][0]= tempb[2][2]
f[0][0]= tempr[2][0]
cube =[f,b,l,r,u,d]
return cube
def D(cube):
f= cube[0]
b= cube[1]
l= cube[2]
r= cube[3]
u= cube[4]
d= cube[5]
tempf = deepcopy(cube[0])
tempb = deepcopy(cube[1])
templ = deepcopy(cube[2])
tempr = deepcopy(cube[3])
tempu = deepcopy(cube[4])
tempd = deepcopy(cube[5])
d[0][2]= tempd[0][0]
d[2][2]= tempd[0][2]
d[2][0]= tempd[2][2]
d[0][0]= tempd[2][0]
d[1][2]= tempd[0][1]
d[2][1]= tempd[1][2]
d[1][0]= tempd[2][1]
d[0][1]= tempd[1][0]
r[2][2]= tempf[2][0]
b[0][2]= tempr[2][2]
l[0][0]= tempb[0][2]
f[2][0]= templ[0][0]
r[1][2]= tempf[2][1]
b[0][1]= tempr[1][2]
l[1][0]= tempb[0][1]
f[2][1]= templ[1][0]
r[0][2]= tempf[2][2]
b[0][0]= tempr[0][2]
l[2][0]= tempb[0][0]
f[2][2]= templ[2][0]
cube =[f,b,l,r,u,d]
return cube
def B(cube):
f= cube[0]
b= cube[1]
l= cube[2]
r= cube[3]
u= cube[4]
d= cube[5]
tempf = deepcopy(cube[0])
tempb = deepcopy(cube[1])
templ = deepcopy(cube[2])
tempr = deepcopy(cube[3])
tempu = deepcopy(cube[4])
tempd = deepcopy(cube[5])
b[0][2]= tempb[0][0]
b[2][2]= tempb[0][2]
b[2][0]= tempb[2][2]
b[0][0]= tempb[2][0]
b[1][2]= tempb[0][1]
b[2][1]= tempb[1][2]
b[1][0]= tempb[2][1]
b[0][1]= tempb[1][0]
r[0][2]= tempd[2][0]
u[0][2]= tempr[0][2]
l[0][2]= tempu[0][2]
d[2][0]= templ[0][2]
r[0][1]= tempd[2][1]
u[0][1]= tempr[0][1]
l[0][1]= tempu[0][1]
d[2][1]= templ[0][1]
r[0][0]= tempd[2][2]
u[0][0]= tempr[0][0]
l[0][0]= tempu[0][0]
d[2][2]= templ[0][0]
cube =[f,b,l,r,u,d]
return cube
def Finv(cube): # Definition der inversen Drehungen entgegen dem Uhrzeigersinn
cube = F(cube)
cube = F(cube)
cube = F(cube)
return cube
def Rinv(cube):
cube = R(cube)
cube = R(cube)
cube = R(cube)
return cube
def Linv(cube):
cube = L(cube)
cube = L(cube)
cube = L(cube)
return cube
def Uinv(cube):
cube = U(cube)
cube = U(cube)
cube = U(cube)
return cube
def Dinv(cube):
cube = D(cube)
cube = D(cube)
cube = D(cube)
return cube
def Binv(cube):
cube = B(cube)
cube = B(cube)
cube = B(cube)
return cube
def KontrolleMatrix (A): # Kontrolliere Einträge der Matrizen, falls a_ij=a_22 forall i,j -> true
for k in range (0,3): # Farben der Seiten sind durch Farbe des jeweiligen Zentrums gegeben
for l in range (0,3):
if A[k][l] != A[1][1]:
return False
return True
def KontrolleCube(cube): # Kontrolle des gesamten Würfels durch Iteration von KontrolleMatrix über jede Seite
for k in range (0,6):
if KontrolleMatrix(cube[k])== False:
return False
return True
def ZugAnpassen(String): #Funktion zur Anpassung des eingebenen Strings im Falle von inversen Zügen
L = list(String)
l = len(L)
for k in range (0,l-1):
if L[k+1] =='`':
L[k] = L[k]+'`'
return L
def ZugKontrollieren(String): # Funktion zur Kontrolle der gültigen Eingaben
L = ZugAnpassen(String) # Umwandlng des String in Liste
l = len(L)
check = True # Definition eines Kontrollschalters
ErlaubteEingaben = ['F','R','L','U','D','B','F`','R`','L`','U`','D`','B`','`']
for k in range (0,l): # Iteration über alle Listeneinträge
if L[k] in ErlaubteEingaben: # Falls Listenelement korrenkt -> nächster Eintrag
k = k+1
else: # Falls Listenelement falsch -> ändere Kontrollschalter
check = False
if check == True: # Prüfe Kontrollschalter mit entsprechender Ausgabe
return True
else:
return False
def Operation(cube,string):
A = ZugAnpassen(string)
a = len(A)
for k in range (0,a):
if A[k] == 'F':
cube = F(cube)
elif A[k] == 'L':
cube = L(cube)
elif A[k] == 'R':
cube = R(cube)
elif A[k] == 'U':
cube = U(cube)
elif A[k] == 'D':
cube = D(cube)
elif A[k] == 'B':
cube = B(cube)
elif A[k] == 'F`':
cube = Finv(cube)
elif A[k] == 'R`':
cube = Rinv(cube)
elif A[k] == 'L`':
cube = Linv(cube)
elif A[k] == 'U`':
cube = Uinv(cube)
elif A[k] == 'D`':
cube = Dinv(cube)
elif A[k] == 'B`':
cube = Binv(cube)
return (cube)
def ZugGrad (cube, string): # Funktion zur Bestimmung des Zuggrades, Eingaben = Würfel als Array und Zug als String
if ZugKontrollieren(string) == False: # Kontrolliere Eingabe des String
print ("Ungültige Eingabe")
else:
k=0 # Counter zum Zählen der ausgeführten Operationen
check = False # Schalter zum Beenden der Schleife, falls Würfen gelöst
while check == False:
cube = Operation(cube,string)
k = k+1
if KontrolleCube(cube) == True:
check = True
print (k)
ZugGrad(cube,'L')
Lösung von: Name nicht veröffentlicht
Verifikation/Checksumme:
Die Speedcuber-Notation steht z. B. hier:
https://speedcube.de/notation.php
Move | Orndungszahl
----------------
RUR' | 4
RULD | 315
RUF | 80
RUF2 | 36
RUUFU | 420
Aktionen
Neue Lösung hinzufügen
Bewertung
Durchschnittliche Bewertung:
Meta
Zeit: | 8 |
Schwierigkeit: | Schwer |
Webcode: | vymw-b4k7 |
Autor: | Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch) |