Buch Cover Buch Cover Buch Cover Buch Cover

Web-Code: - Webcode Help

Ernö Rubiks Zauberwürfelalgorithmen (Algorithmen)

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.

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.
Netz des Rubiks-Cube
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

Bitte melde dich an um einen Kommentar abzugeben

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

Bewertung

Durchschnittliche Bewertung:

Eigene Bewertung:
Bitte zuerst anmelden

Meta

Zeit: 8
Schwierigkeit: Schwer
Webcode: vymw-b4k7
Autor: Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch)

Download PDF

Download ZIP

Zu Aufgabenblatt hinzufügen