From ad83922d26a7ee859f12422b1e02c5bcca8dec05 Mon Sep 17 00:00:00 2001 From: swerg110 Date: Sun, 1 Feb 2026 21:46:34 +0300 Subject: [PATCH 1/3] Test --- .../hse/java/practice/task1/RubiksCube.java | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/main/java/hse/java/practice/task1/RubiksCube.java b/src/main/java/hse/java/practice/task1/RubiksCube.java index 2091b657..a608dda5 100644 --- a/src/main/java/hse/java/practice/task1/RubiksCube.java +++ b/src/main/java/hse/java/practice/task1/RubiksCube.java @@ -6,7 +6,7 @@ * Необходимо реализовать интерфейс Cube * При повороте передней грани, меняются верх низ право и лево */ -public class RubiksCube { +public class RubiksCube implements Cube{ private static final int EDGES_COUNT = 6; @@ -38,4 +38,34 @@ public Edge[] getEdges() { public String toString() { return Arrays.toString(edges); } + + @Override + public void back(RotateDirection direction) { + // TODO Auto-generated method stub + + } + + @Override + public void down(RotateDirection direction) { + // TODO Auto-generated method stub + + } + + @Override + public void left(RotateDirection direction) { + // TODO Auto-generated method stub + + } + + @Override + public void right(RotateDirection direction) { + // TODO Auto-generated method stub + + } + + @Override + public void up(RotateDirection direction) { + // TODO Auto-generated method stub + + } } From b47c63e27c29adeb645d2ed8f92bb7cd2007a518 Mon Sep 17 00:00:00 2001 From: swerg110 Date: Mon, 2 Feb 2026 02:22:27 +0300 Subject: [PATCH 2/3] Work tests --- .../hse/java/practice/task1/Permutations.java | 84 ++++++++++++++++ .../hse/java/practice/task1/RubiksCube.java | 99 ++++++++++++++----- 2 files changed, 157 insertions(+), 26 deletions(-) create mode 100644 src/main/java/hse/java/practice/task1/Permutations.java diff --git a/src/main/java/hse/java/practice/task1/Permutations.java b/src/main/java/hse/java/practice/task1/Permutations.java new file mode 100644 index 00000000..e1a9dc37 --- /dev/null +++ b/src/main/java/hse/java/practice/task1/Permutations.java @@ -0,0 +1,84 @@ +package hse.java.practice.task1; + +import java.util.Arrays; +import java.util.stream.*; +import java.util.stream.IntStream; + +public class Permutations { + static final int[] CURR_EDGES_ORDER = {2, 4, 3, 5, 0, 1}; + public static final int G_SIZE = 48; + + // Циклы перестановок для левой грани по часовой стрелке + static final int[][] L_CW = { + {1, 3, 8, 6}, + {2, 5, 7, 4}, + {33, 9, 41, 32}, + {36, 12, 44, 29}, + {38, 14, 46, 27} + }; + + // Циклы перестановок для передней грани по часовой стрелке + static final int[][] F_CW = { + {9, 11, 16, 14}, + {10, 13, 15, 12}, + {38, 17, 43, 8}, + {39, 20, 42, 5}, + {40, 22, 41, 3} + }; + + // Циклы перестановок для правой грани по часовой стрелке + static final int[][] R_CW = { + {17, 19, 24, 22}, + {18, 21, 23, 20}, + {48, 16, 40, 25}, + {45, 13, 37, 28}, + {43, 11, 35, 30} + }; + + // Циклы перестановок для задней грани по часовой стрелке + static final int[][] B_CW = { + {25, 27, 32, 30}, + {26, 29, 31, 28}, + {19, 33, 6, 48}, + {21, 34, 4, 47}, + {24, 35, 1, 46} + }; + + // Циклы перестановок для верхней грани по часовой стрелке + static final int[][] U_CW = { + {33, 35, 40, 38}, + {34, 37, 39, 36}, + {25, 17, 9, 1}, + {26, 18, 10, 2}, + {27, 19, 11, 3} + }; + + // Циклы перестановок для нижней грани по часовой стрелке + static final int[][] D_CW = { + {41, 43, 48, 46}, + {42, 45, 47, 44}, + {6, 14, 22, 30}, + {7, 15, 23, 31}, + {8, 16, 24, 32} + }; + + // То же самое, но против часовой + static final int[][] U_CCW = reverseCycles(U_CW); + static final int[][] D_CCW = reverseCycles(D_CW); + static final int[][] L_CCW = reverseCycles(L_CW); + static final int[][] R_CCW = reverseCycles(R_CW); + static final int[][] F_CCW = reverseCycles(F_CW); + static final int[][] B_CCW = reverseCycles(B_CW); + + private static int[][] reverseCycles(int[][] cs) { + return Arrays.stream(cs) + .map(c -> { + int cLen = c.length; + int[] rev = new int[cLen]; + rev[0] = c[0]; + IntStream.range(1, cLen).forEach(i -> rev[i] = c[cLen - i]); + return rev; + }) + .toArray(int[][]::new); + } +} diff --git a/src/main/java/hse/java/practice/task1/RubiksCube.java b/src/main/java/hse/java/practice/task1/RubiksCube.java index a608dda5..7389d55a 100644 --- a/src/main/java/hse/java/practice/task1/RubiksCube.java +++ b/src/main/java/hse/java/practice/task1/RubiksCube.java @@ -6,11 +6,17 @@ * Необходимо реализовать интерфейс Cube * При повороте передней грани, меняются верх низ право и лево */ -public class RubiksCube implements Cube{ +public class RubiksCube implements Cube{ + + private static final int EDGES_COUNT = 6; + private static final int EDGE_SIZE = 3; + private static final int CENTER_INDEX = 5; + private static final int FIXED_ELEM = 8; + private static final int ELEMENTS_COUNT = 54; - private static final int EDGES_COUNT = 6; private final Edge[] edges = new Edge[EDGES_COUNT]; + private final int[] states; /** * Создать валидный собранный кубик @@ -20,18 +26,26 @@ public class RubiksCube implements Cube{ * ... */ public RubiksCube() { - CubeColor[] colors = CubeColor.values(); - for (int i = 0; i < 6; i++) { - edges[i] = new Edge(colors[i]); - } + CubeColor[] colors = CubeColor.values(); + for (int i = 0; i < EDGES_COUNT; i++) edges[i] = new Edge(colors[i]); + + states = new int[Permutations.G_SIZE + 1]; + for (int i = 1; i < Permutations.G_SIZE + 1; i++) states[i] = i; } - public void front(RotateDirection direction) { + public Edge[] getEdges() { + for (int i = 0; i < EDGES_COUNT; i++) edges[Permutations.CURR_EDGES_ORDER[i]].setParts(buildEdge(i)); + return edges; + } + @Override + public void front(RotateDirection direction) { + applyCycleToStates(direction == RotateDirection.CLOCKWISE ? Permutations.F_CW : Permutations.F_CCW); } - public Edge[] getEdges() { - return edges; + @Override + public void back(RotateDirection direction) { + applyCycleToStates(direction == RotateDirection.CLOCKWISE ? Permutations.B_CW : Permutations.B_CCW); } @Override @@ -40,32 +54,65 @@ public String toString() { } @Override - public void back(RotateDirection direction) { - // TODO Auto-generated method stub - + public void left(RotateDirection direction) { + applyCycleToStates(direction == RotateDirection.CLOCKWISE ? Permutations.L_CW : Permutations.L_CCW); } @Override - public void down(RotateDirection direction) { - // TODO Auto-generated method stub - - } + public void right(RotateDirection direction) { + applyCycleToStates(direction == RotateDirection.CLOCKWISE ? Permutations.R_CW : Permutations.R_CCW); + } @Override - public void left(RotateDirection direction) { - // TODO Auto-generated method stub - + public void up(RotateDirection direction) { + applyCycleToStates(direction == RotateDirection.CLOCKWISE ? Permutations.U_CW : Permutations.U_CCW); + } + + @Override + public void down(RotateDirection direction) { + applyCycleToStates(direction == RotateDirection.CLOCKWISE ? Permutations.D_CW : Permutations.D_CCW); + } + + private void applyCycleToState(int[] c) { + final int cLen = c.length; + int prev = states[c[cLen - 1]]; + for (int i = 0; i < cLen; i++) { + int cur = states[c[i]]; + states[c[i]] = prev; + prev = cur; + } } - @Override - public void right(RotateDirection direction) { - // TODO Auto-generated method stub - + private void applyCycleToStates(int[][] cs) { + for (int[] c : cs) applyCycleToState(c); } - @Override - public void up(RotateDirection direction) { - // TODO Auto-generated method stub + private static int toElemPos(int x, int y) { + int pos = x + y * EDGE_SIZE + 1; + return pos > CENTER_INDEX ? pos - 1 : pos; + } + + private static boolean isCenter(int x, int y) { + return x == 1 && y == 1; + } + + private CubeColor centerColor(int edgeIndex) { + return CubeColor.values()[Permutations.CURR_EDGES_ORDER[edgeIndex]]; + } + + private CubeColor elemColor(int edgeIndex, int pos) { + int stateIndex = states[edgeIndex * FIXED_ELEM + pos]; + int front = (stateIndex - 1) / FIXED_ELEM; + return CubeColor.values()[Permutations.CURR_EDGES_ORDER[front]]; + } + + private CubeColor[][] buildEdge(int edgeIndex) { + CubeColor[][] newEdge = new CubeColor[EDGE_SIZE][EDGE_SIZE]; + for (int y = 0; y < EDGE_SIZE; y++) { + for (int x = 0; x < EDGE_SIZE; x++) + newEdge[y][x] = isCenter(x, y) ? centerColor(edgeIndex) : elemColor(edgeIndex, toElemPos(x, y)); + } + return newEdge; } } From 0992f179a081846274f31544db4ac4adcd45fce9 Mon Sep 17 00:00:00 2001 From: swerg110 Date: Mon, 2 Feb 2026 02:29:17 +0300 Subject: [PATCH 3/3] Clean Up --- .../hse/java/practice/task1/Permutations.java | 2 +- .../hse/java/practice/task1/RubiksCube.java | 17 +++++++---------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/main/java/hse/java/practice/task1/Permutations.java b/src/main/java/hse/java/practice/task1/Permutations.java index e1a9dc37..8af34961 100644 --- a/src/main/java/hse/java/practice/task1/Permutations.java +++ b/src/main/java/hse/java/practice/task1/Permutations.java @@ -73,7 +73,7 @@ public class Permutations { private static int[][] reverseCycles(int[][] cs) { return Arrays.stream(cs) .map(c -> { - int cLen = c.length; + final int cLen = c.length; int[] rev = new int[cLen]; rev[0] = c[0]; IntStream.range(1, cLen).forEach(i -> rev[i] = c[cLen - i]); diff --git a/src/main/java/hse/java/practice/task1/RubiksCube.java b/src/main/java/hse/java/practice/task1/RubiksCube.java index 7389d55a..6fa9dda5 100644 --- a/src/main/java/hse/java/practice/task1/RubiksCube.java +++ b/src/main/java/hse/java/practice/task1/RubiksCube.java @@ -12,8 +12,6 @@ public class RubiksCube implements Cube{ private static final int EDGE_SIZE = 3; private static final int CENTER_INDEX = 5; private static final int FIXED_ELEM = 8; - private static final int ELEMENTS_COUNT = 54; - private final Edge[] edges = new Edge[EDGES_COUNT]; private final int[] states; @@ -40,12 +38,12 @@ public Edge[] getEdges() { @Override public void front(RotateDirection direction) { - applyCycleToStates(direction == RotateDirection.CLOCKWISE ? Permutations.F_CW : Permutations.F_CCW); + applyCyclesToStates(direction == RotateDirection.CLOCKWISE ? Permutations.F_CW : Permutations.F_CCW); } @Override public void back(RotateDirection direction) { - applyCycleToStates(direction == RotateDirection.CLOCKWISE ? Permutations.B_CW : Permutations.B_CCW); + applyCyclesToStates(direction == RotateDirection.CLOCKWISE ? Permutations.B_CW : Permutations.B_CCW); } @Override @@ -55,22 +53,22 @@ public String toString() { @Override public void left(RotateDirection direction) { - applyCycleToStates(direction == RotateDirection.CLOCKWISE ? Permutations.L_CW : Permutations.L_CCW); + applyCyclesToStates(direction == RotateDirection.CLOCKWISE ? Permutations.L_CW : Permutations.L_CCW); } @Override public void right(RotateDirection direction) { - applyCycleToStates(direction == RotateDirection.CLOCKWISE ? Permutations.R_CW : Permutations.R_CCW); + applyCyclesToStates(direction == RotateDirection.CLOCKWISE ? Permutations.R_CW : Permutations.R_CCW); } @Override public void up(RotateDirection direction) { - applyCycleToStates(direction == RotateDirection.CLOCKWISE ? Permutations.U_CW : Permutations.U_CCW); + applyCyclesToStates(direction == RotateDirection.CLOCKWISE ? Permutations.U_CW : Permutations.U_CCW); } @Override public void down(RotateDirection direction) { - applyCycleToStates(direction == RotateDirection.CLOCKWISE ? Permutations.D_CW : Permutations.D_CCW); + applyCyclesToStates(direction == RotateDirection.CLOCKWISE ? Permutations.D_CW : Permutations.D_CCW); } private void applyCycleToState(int[] c) { @@ -83,7 +81,7 @@ private void applyCycleToState(int[] c) { } } - private void applyCycleToStates(int[][] cs) { + private void applyCyclesToStates(int[][] cs) { for (int[] c : cs) applyCycleToState(c); } @@ -101,7 +99,6 @@ private CubeColor centerColor(int edgeIndex) { } private CubeColor elemColor(int edgeIndex, int pos) { - int stateIndex = states[edgeIndex * FIXED_ELEM + pos]; int front = (stateIndex - 1) / FIXED_ELEM; return CubeColor.values()[Permutations.CURR_EDGES_ORDER[front]];