From ed949326b717f59dde180bba6e5b80ac09d42bc0 Mon Sep 17 00:00:00 2001 From: marr97 Date: Fri, 6 Feb 2026 22:24:16 +0300 Subject: [PATCH 01/13] added front --- .../hse/java/practice/task1/RubiksCube.java | 74 ++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/src/main/java/hse/java/practice/task1/RubiksCube.java b/src/main/java/hse/java/practice/task1/RubiksCube.java index 2091b657..4dda8125 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; @@ -26,10 +26,80 @@ public RubiksCube() { } } + @Override + public void up(RotateDirection direction) { + + } + + @Override + public void down(RotateDirection direction) { + + } + + @Override + public void left(RotateDirection direction) { + + } + + @Override + public void right(RotateDirection direction) { + + } + + @Override public void front(RotateDirection direction) { + Edge[] edges_copy = CopyArray(); + rotateFace(edges[4], edges_copy[4], direction); + switch (direction) { + case RotateDirection.CLOCKWISE: + for (int i = 0; i < 3; i++) { + edges[0].getParts()[2][i] = edges_copy[2].getParts()[i][2]; + edges[1].getParts()[0][i] = edges_copy[3].getParts()[i][0]; + edges[2].getParts()[i][2] = edges_copy[1].getParts()[0][i]; + edges[3].getParts()[i][0] = edges_copy[0].getParts()[2][i]; + } + break; + + case RotateDirection.COUNTERCLOCKWISE: + for (int i = 0; i < 3; i++) { + edges[2].getParts()[i][2] = edges_copy[0].getParts()[2][i]; + edges[3].getParts()[i][0] = edges_copy[1].getParts()[0][i]; + edges[1].getParts()[0][i] = edges_copy[2].getParts()[i][2]; + edges[0].getParts()[2][i] = edges_copy[3].getParts()[i][0]; + } + } + } + + @Override + public void back(RotateDirection direction) { } - + + public void rotateFace(Edge Orig, Edge Copy, RotateDirection direction) { + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + if (direction == RotateDirection.CLOCKWISE) { + Orig.getParts()[j][2 - i] = Copy.getParts()[i][j]; + } else { + Orig.getParts()[2 - j][i] = Copy.getParts()[i][j]; + } + } + } + } + + public Edge[] CopyArray() { + Edge[] edges_copy = new Edge[edges.length]; + for (int i = 0; i < 6; i++) { + CubeColor[][] parts = new CubeColor[3][3]; + for (int j = 0; j < 3; j++) { + parts[j] = Arrays.copyOf(edges[i].getParts()[j], 3); + } + edges_copy[i] = new Edge(parts); + } + return edges_copy; + } + + public Edge[] getEdges() { return edges; } From 0d81696a6d021aa7c01cf5a856b32e64235a47b6 Mon Sep 17 00:00:00 2001 From: marr97 Date: Fri, 6 Feb 2026 22:30:35 +0300 Subject: [PATCH 02/13] fixed enum name --- src/main/java/hse/java/practice/task1/RubiksCube.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/hse/java/practice/task1/RubiksCube.java b/src/main/java/hse/java/practice/task1/RubiksCube.java index 4dda8125..f52628af 100644 --- a/src/main/java/hse/java/practice/task1/RubiksCube.java +++ b/src/main/java/hse/java/practice/task1/RubiksCube.java @@ -51,7 +51,7 @@ public void front(RotateDirection direction) { Edge[] edges_copy = CopyArray(); rotateFace(edges[4], edges_copy[4], direction); switch (direction) { - case RotateDirection.CLOCKWISE: + case CLOCKWISE: for (int i = 0; i < 3; i++) { edges[0].getParts()[2][i] = edges_copy[2].getParts()[i][2]; edges[1].getParts()[0][i] = edges_copy[3].getParts()[i][0]; @@ -60,7 +60,7 @@ public void front(RotateDirection direction) { } break; - case RotateDirection.COUNTERCLOCKWISE: + case COUNTERCLOCKWISE: for (int i = 0; i < 3; i++) { edges[2].getParts()[i][2] = edges_copy[0].getParts()[2][i]; edges[3].getParts()[i][0] = edges_copy[1].getParts()[0][i]; From 137109430e414c66edf4c54a3dde63c27a794eea Mon Sep 17 00:00:00 2001 From: marr97 Date: Fri, 6 Feb 2026 22:39:41 +0300 Subject: [PATCH 03/13] checking tests.... --- src/main/java/hse/java/practice/task1/RubiksCube.java | 2 +- 1 file changed, 1 insertion(+), 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 f52628af..c7b3f2fb 100644 --- a/src/main/java/hse/java/practice/task1/RubiksCube.java +++ b/src/main/java/hse/java/practice/task1/RubiksCube.java @@ -28,7 +28,7 @@ public RubiksCube() { @Override public void up(RotateDirection direction) { - + System.out.println("1, 2, 3"); } @Override From 77625b43a122c8eac4f7ef29b38dd4877ebd017d Mon Sep 17 00:00:00 2001 From: marr97 Date: Fri, 6 Feb 2026 22:51:32 +0300 Subject: [PATCH 04/13] added other methods --- .../hse/java/practice/task1/RubiksCube.java | 108 +++++++++++++++++- 1 file changed, 107 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 c7b3f2fb..4d50e5b4 100644 --- a/src/main/java/hse/java/practice/task1/RubiksCube.java +++ b/src/main/java/hse/java/practice/task1/RubiksCube.java @@ -28,22 +28,106 @@ public RubiksCube() { @Override public void up(RotateDirection direction) { - System.out.println("1, 2, 3"); + Edge[] edges_copy = CopyArray(); + rotateFace(edges[0], edges_copy[0], direction); + + switch (direction) { + case CLOCKWISE: + for (int i = 0; i < 3; i++) { + edges[2].getParts()[0][i] = edges_copy[4].getParts()[0][i]; + edges[5].getParts()[0][i] = edges_copy[2].getParts()[0][i]; + edges[3].getParts()[0][i] = edges_copy[5].getParts()[0][i]; + edges[4].getParts()[0][i] = edges_copy[3].getParts()[0][i]; + } + break; + + case COUNTERCLOCKWISE: + for (int i = 0; i < 3; i++) { + edges[4].getParts()[0][i] = edges_copy[2].getParts()[0][i]; + edges[2].getParts()[0][i] = edges_copy[5].getParts()[0][i]; + edges[5].getParts()[0][i] = edges_copy[3].getParts()[0][i]; + edges[3].getParts()[0][i] = edges_copy[4].getParts()[0][i]; + } + break; + } } @Override public void down(RotateDirection direction) { + Edge[] edges_copy = CopyArray(); + rotateFace(edges[1], edges_copy[1], direction); + switch (direction) { + case CLOCKWISE: + for (int i = 0; i < 3; i++) { + edges[4].getParts()[2][i] = edges_copy[2].getParts()[2][i]; + edges[3].getParts()[2][i] = edges_copy[4].getParts()[2][i]; + edges[5].getParts()[2][i] = edges_copy[3].getParts()[2][i]; + edges[2].getParts()[2][i] = edges_copy[5].getParts()[2][i]; + } + break; + + case COUNTERCLOCKWISE: + for (int i = 0; i < 3; i++) { + edges[2].getParts()[2][i] = edges_copy[4].getParts()[2][i]; + edges[4].getParts()[2][i] = edges_copy[3].getParts()[2][i]; + edges[3].getParts()[2][i] = edges_copy[5].getParts()[2][i]; + edges[5].getParts()[2][i] = edges_copy[2].getParts()[2][i]; + } + break; + } } @Override public void left(RotateDirection direction) { + Edge[] edges_copy = CopyArray(); + rotateFace(edges[2], edges_copy[2], direction); + + switch (direction) { + case CLOCKWISE: + for (int i = 0; i < 3; i++) { + edges[4].getParts()[i][0] = edges_copy[0].getParts()[i][0]; + edges[1].getParts()[i][0] = edges_copy[4].getParts()[i][0]; + edges[5].getParts()[2 - i][2] = edges_copy[1].getParts()[i][0]; + edges[0].getParts()[i][0] = edges_copy[5].getParts()[2 - i][2]; + } + break; + case COUNTERCLOCKWISE: + for (int i = 0; i < 3; i++) { + edges[0].getParts()[i][0] = edges_copy[4].getParts()[i][0]; + edges[4].getParts()[i][0] = edges_copy[1].getParts()[i][0]; + edges[1].getParts()[i][0] = edges_copy[5].getParts()[2 - i][2]; + edges[5].getParts()[2 - i][2] = edges_copy[0].getParts()[i][0]; + } + break; + } } @Override public void right(RotateDirection direction) { + Edge[] edges_copy = CopyArray(); + rotateFace(edges[3], edges_copy[3], direction); + + switch (direction) { + case CLOCKWISE: + for (int i = 0; i < 3; i++) { + edges[5].getParts()[2 - i][0] = edges_copy[0].getParts()[i][2]; + edges[1].getParts()[i][2] = edges_copy[5].getParts()[2 - i][0]; + edges[4].getParts()[i][2] = edges_copy[1].getParts()[i][2]; + edges[0].getParts()[i][2] = edges_copy[4].getParts()[i][2]; + } + break; + case COUNTERCLOCKWISE: + for (int i = 0; i < 3; i++) { + edges[0].getParts()[i][2] = edges_copy[5].getParts()[2 - i][0]; + edges[5].getParts()[2 - i][0] = edges_copy[1].getParts()[i][2]; + edges[1].getParts()[i][2] = edges_copy[4].getParts()[i][2]; + edges[4].getParts()[i][2] = edges_copy[0].getParts()[i][2]; + } + break; + } } @Override @@ -67,12 +151,34 @@ public void front(RotateDirection direction) { edges[1].getParts()[0][i] = edges_copy[2].getParts()[i][2]; edges[0].getParts()[2][i] = edges_copy[3].getParts()[i][0]; } + break; } } @Override public void back(RotateDirection direction) { + Edge[] edges_copy = CopyArray(); + rotateFace(edges[5], edges_copy[5], direction); + switch (direction) { + case CLOCKWISE: + for (int i = 0; i < 3; i++) { + edges[0].getParts()[0][i] = edges_copy[3].getParts()[i][2]; + edges[2].getParts()[2 - i][0] = edges_copy[0].getParts()[0][i]; + edges[1].getParts()[2][i] = edges_copy[2].getParts()[i][0]; + edges[3].getParts()[2 - i][2] = edges_copy[1].getParts()[2][i]; + } + break; + + case COUNTERCLOCKWISE: + for (int i = 0; i < 3; i++) { + edges[3].getParts()[i][2] = edges_copy[0].getParts()[0][i]; + edges[0].getParts()[0][i] = edges_copy[2].getParts()[2 - i][0]; + edges[2].getParts()[i][0] = edges_copy[1].getParts()[2][i]; + edges[1].getParts()[2][i] = edges_copy[3].getParts()[2 - i][2]; + } + break; + } } public void rotateFace(Edge Orig, Edge Copy, RotateDirection direction) { From c0d3d872e15f1f07545138052aa8eac4e3053cbe Mon Sep 17 00:00:00 2001 From: marr97 Date: Fri, 6 Feb 2026 23:31:17 +0300 Subject: [PATCH 05/13] try with tests --- src/main/java/hse/java/practice/task1/RubiksCube.java | 2 +- 1 file changed, 1 insertion(+), 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 4d50e5b4..7078d40d 100644 --- a/src/main/java/hse/java/practice/task1/RubiksCube.java +++ b/src/main/java/hse/java/practice/task1/RubiksCube.java @@ -198,7 +198,7 @@ public Edge[] CopyArray() { for (int i = 0; i < 6; i++) { CubeColor[][] parts = new CubeColor[3][3]; for (int j = 0; j < 3; j++) { - parts[j] = Arrays.copyOf(edges[i].getParts()[j], 3); + parts[j] = Arrays.copyOf(edges[i].getParts()[j], 3); } edges_copy[i] = new Edge(parts); } From a6d2d20e6789e875b1d610c6d08474655145209d Mon Sep 17 00:00:00 2001 From: marr97 Date: Sat, 7 Feb 2026 21:17:37 +0300 Subject: [PATCH 06/13] cube: once again --- src/main/java/hse/java/practice/task1/RubiksCube.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/main/java/hse/java/practice/task1/RubiksCube.java b/src/main/java/hse/java/practice/task1/RubiksCube.java index 7078d40d..26aaeeaf 100644 --- a/src/main/java/hse/java/practice/task1/RubiksCube.java +++ b/src/main/java/hse/java/practice/task1/RubiksCube.java @@ -2,23 +2,12 @@ import java.util.Arrays; -/** - * Необходимо реализовать интерфейс Cube - * При повороте передней грани, меняются верх низ право и лево - */ public class RubiksCube implements Cube{ private static final int EDGES_COUNT = 6; private final Edge[] edges = new Edge[EDGES_COUNT]; - /** - * Создать валидный собранный кубик - * грани разместить по ордеру в енуме цветов - * грань 0 -> цвет 0 - * грань 1 -> цвет 1 - * ... - */ public RubiksCube() { CubeColor[] colors = CubeColor.values(); for (int i = 0; i < 6; i++) { From 5374f8246cb4862188813cef78684ee0954752f3 Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 7 Feb 2026 13:14:53 +0300 Subject: [PATCH 07/13] lecture 3 --- .../java/lectures/lecture3/examples/Box.java | 14 + .../lectures/lecture3/examples/Generics.java | 43 +++ .../java/lectures/lecture3/examples/Main.java | 18 ++ .../lectures/lecture3/examples/Methods.java | 10 + .../lecture3/examples/TryCatchThrows.java | 79 +++++ .../java/lectures/lecture3/tasks/atm/Atm.java | 19 +- .../hse/java/practice/task1/RubiksCube.java | 15 +- .../lectures/lecture3/tasks/atm/AtmTest.java | 38 +-- .../java/practice/task1/CubeSimpleTest.java | 277 ++++++++++++++++++ 9 files changed, 480 insertions(+), 33 deletions(-) create mode 100644 src/main/java/hse/java/lectures/lecture3/examples/Box.java create mode 100644 src/main/java/hse/java/lectures/lecture3/examples/Generics.java create mode 100644 src/main/java/hse/java/lectures/lecture3/examples/Main.java create mode 100644 src/main/java/hse/java/lectures/lecture3/examples/Methods.java create mode 100644 src/main/java/hse/java/lectures/lecture3/examples/TryCatchThrows.java create mode 100644 src/test/java/hse/java/practice/task1/CubeSimpleTest.java diff --git a/src/main/java/hse/java/lectures/lecture3/examples/Box.java b/src/main/java/hse/java/lectures/lecture3/examples/Box.java new file mode 100644 index 00000000..6c3ccf57 --- /dev/null +++ b/src/main/java/hse/java/lectures/lecture3/examples/Box.java @@ -0,0 +1,14 @@ +package hse.java.lectures.lecture3.examples; + +public class Box { + + private T item; + + public void put(T item) { + this.item = item; + } + + public T get() { + return item; + } +} diff --git a/src/main/java/hse/java/lectures/lecture3/examples/Generics.java b/src/main/java/hse/java/lectures/lecture3/examples/Generics.java new file mode 100644 index 00000000..4fe8a270 --- /dev/null +++ b/src/main/java/hse/java/lectures/lecture3/examples/Generics.java @@ -0,0 +1,43 @@ +package hse.java.lectures.lecture3.examples; + +import java.util.ArrayList; +import java.util.List; + +public class Generics { + + + + public T getType(T type) { + System.out.println(type.getClass()); + return type; + } + + public static void write(List list, T value) { + list.add(value); + } + + public static > T get(T value) { + return value; + } + + public static void testGenerics() { + // get(1.).compareTo() + write(List.of(1), 1); + write(List.of(), 1.2); + List ints = new ArrayList<>(); + ints.add(1); + ints.add(2); + // PECS + List nums = ints; + List si = ints; + si.add(1); + si.get(1); + } + + public static void main(String[] args) { + List il = new ArrayList<>(); + write(il, 5); + System.out.println(il); + } + +} diff --git a/src/main/java/hse/java/lectures/lecture3/examples/Main.java b/src/main/java/hse/java/lectures/lecture3/examples/Main.java new file mode 100644 index 00000000..d4279be4 --- /dev/null +++ b/src/main/java/hse/java/lectures/lecture3/examples/Main.java @@ -0,0 +1,18 @@ +package hse.java.lectures.lecture3.examples; + +import java.util.ArrayList; +import java.util.concurrent.Callable; + +public class Main { + public static void main(String[] args) { + Box box = new Box<>(); + Box dBox = new Box<>(); + Callable callable; + + int x = new Integer(3); + Integer y = 5; + + Box nBox = box; + new Methods().get(new ArrayList()).add(1); + } +} diff --git a/src/main/java/hse/java/lectures/lecture3/examples/Methods.java b/src/main/java/hse/java/lectures/lecture3/examples/Methods.java new file mode 100644 index 00000000..cac365d7 --- /dev/null +++ b/src/main/java/hse/java/lectures/lecture3/examples/Methods.java @@ -0,0 +1,10 @@ +package hse.java.lectures.lecture3.examples; + +public class Methods { + + + public T get(T type) { + return type; + } + +} diff --git a/src/main/java/hse/java/lectures/lecture3/examples/TryCatchThrows.java b/src/main/java/hse/java/lectures/lecture3/examples/TryCatchThrows.java new file mode 100644 index 00000000..0d972ac3 --- /dev/null +++ b/src/main/java/hse/java/lectures/lecture3/examples/TryCatchThrows.java @@ -0,0 +1,79 @@ +package hse.java.lectures.lecture3.examples; + +import java.io.*; + +public class TryCatchThrows { + + public void testRuntime() throws RuntimeException { + throw new RuntimeException("Test runtime"); + } + + public void testException() throws Exception { + throw new Exception("test exception"); + } + + public void testError() throws Error { + throw new Error("test error"); + } + + public void testTryRuntime() { + try { + testRuntime(); + } catch (RuntimeException e) { + System.out.println("Catch " + e.getMessage()); + } finally { + System.out.println("finally"); + } + } + + public void testTryException() { + try { + testException(); + } catch (Exception e) { + System.out.println("Catch " + e.getMessage()); + } finally { + System.out.println("finally"); + } + } + + public void testTryError() { + // testError(); + try { + testError(); + } catch (Error e) { + System.out.println("Catch " + e.getMessage()); + } finally { + System.out.println("finally"); + } + } + + public static void foo() { + throw new RuntimeException("My runtime"); + } + + public static void bar() throws Exception { + throw new Exception("My exception"); + } + + public static void main(String[] args) { + // foo(); +// try { +// bar(); +// } catch (Exception e) { +// System.err.println("Hello exception"); +// } finally { +// +// } + +// try (BufferedReader br = new BufferedReader(new FileReader(""))) { +// +// } catch (IOException e) { +// throw new RuntimeException(e); +// } + + // int x = 1/ 0; + int[] a = new int[1]; + System.out.println(a[2]); + } + +} diff --git a/src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java b/src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java index 3fa91909..08f551e4 100644 --- a/src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java +++ b/src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java @@ -1,14 +1,9 @@ package hse.java.lectures.lecture3.tasks.atm; -import java.util.Collections; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; +import java.util.*; public class Atm { - private enum Denomination { + public enum Denomination { D50(50), D100(100), D500(500), @@ -24,6 +19,12 @@ private enum Denomination { int value() { return value; } + + public static Denomination fromInt(int value) { + return Arrays.stream(values()).filter(v -> v.value == value) + .findFirst() + .orElse(null); + } } private final Map banknotes = new EnumMap<>(Denomination.class); @@ -31,9 +32,9 @@ int value() { public Atm() { } - public void deposit(Map banknotes){} + public void deposit(Map banknotes){} - public Map withdraw(int amount) { + public Map withdraw(int amount) { return Map.of(); } diff --git a/src/main/java/hse/java/practice/task1/RubiksCube.java b/src/main/java/hse/java/practice/task1/RubiksCube.java index 26aaeeaf..a57b2e7e 100644 --- a/src/main/java/hse/java/practice/task1/RubiksCube.java +++ b/src/main/java/hse/java/practice/task1/RubiksCube.java @@ -2,12 +2,23 @@ import java.util.Arrays; +/** + * Необходимо реализовать интерфейс Cube + * При повороте передней грани, меняются верх низ право и лево + */ public class RubiksCube implements Cube{ private static final int EDGES_COUNT = 6; private final Edge[] edges = new Edge[EDGES_COUNT]; + /** + * Создать валидный собранный кубик + * грани разместить по ордеру в енуме цветов + * грань 0 -> цвет 0 + * грань 1 -> цвет 1 + * ... + */ public RubiksCube() { CubeColor[] colors = CubeColor.values(); for (int i = 0; i < 6; i++) { @@ -187,7 +198,7 @@ public Edge[] CopyArray() { for (int i = 0; i < 6; i++) { CubeColor[][] parts = new CubeColor[3][3]; for (int j = 0; j < 3; j++) { - parts[j] = Arrays.copyOf(edges[i].getParts()[j], 3); + parts[j] = Arrays.copyOf(edges[i].getParts()[j], 3); } edges_copy[i] = new Edge(parts); } @@ -203,4 +214,4 @@ public Edge[] getEdges() { public String toString() { return Arrays.toString(edges); } -} +} \ No newline at end of file diff --git a/src/test/java/hse/java/lectures/lecture3/tasks/atm/AtmTest.java b/src/test/java/hse/java/lectures/lecture3/tasks/atm/AtmTest.java index 9e3994a6..5e83fcae 100644 --- a/src/test/java/hse/java/lectures/lecture3/tasks/atm/AtmTest.java +++ b/src/test/java/hse/java/lectures/lecture3/tasks/atm/AtmTest.java @@ -15,6 +15,7 @@ import java.util.Map; import java.util.stream.Stream; +import static hse.java.lectures.lecture3.tasks.atm.Atm.Denomination.*; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -30,18 +31,11 @@ void initialBalanceIsZero() { @Test void depositIncreasesBalance() { Atm atm = new Atm(); - atm.deposit(Map.of(100, 10, 500, 5)); + atm.deposit(Map.of(D100, 10, D500, 5)); assertEquals(3500, atm.getBalance()); } - @Test - void depositRejectsInvalidDenominationAndKeepsState() { - Atm atm = new Atm(); - atm.deposit(Map.of(100, 1)); - assertThrows(InvalidDepositException.class, () -> atm.deposit(Map.of(30, 1))); - assertEquals(100, atm.getBalance()); - } - + @Test void depositRejectsNullMap() { Atm atm = new Atm(); @@ -51,8 +45,8 @@ void depositRejectsNullMap() { @Test void depositRejectsNonPositiveCountAndKeepsState() { Atm atm = new Atm(); - atm.deposit(Map.of(100, 1)); - assertThrows(InvalidDepositException.class, () -> atm.deposit(Map.of(100, 0))); + atm.deposit(Map.of(D100, 1)); + assertThrows(InvalidDepositException.class, () -> atm.deposit(Map.of(D100, 0))); assertEquals(100, atm.getBalance()); } @@ -60,11 +54,11 @@ void depositRejectsNonPositiveCountAndKeepsState() { void withdrawGreedyAndUpdatesBalance() { Atm atm = new Atm(); // 2000 - atm.deposit(Map.of(1000, 1, 500, 1, 100, 5)); + atm.deposit(Map.of(D1000, 1, D500, 1, D100, 5)); - Map result = atm.withdraw(1700); + Map result = atm.withdraw(1700); - assertEquals(Map.of(1000, 1, 500, 1, 100, 2), result); + assertEquals(Map.of(D1000, 1, D500, 1, D100, 2), result); assertEquals(300, atm.getBalance()); } @@ -78,14 +72,14 @@ void withdrawRejectsInvalidAmount() { @Test void withdrawRejectsInsufficientFunds() { Atm atm = new Atm(); - atm.deposit(Map.of(100, 2)); + atm.deposit(Map.of(D100, 2)); assertThrows(InsufficientFundsException.class, () -> atm.withdraw(300)); } @Test void withdrawRejectsUnmakeableAmountAndKeepsState() { Atm atm = new Atm(); - atm.deposit(Map.of(500, 1, 100, 1)); + atm.deposit(Map.of(D500, 1, D100, 1)); assertThrows(CannotDispenseException.class, () -> atm.withdraw(150)); assertEquals(600, atm.getBalance()); } @@ -96,7 +90,7 @@ void additionalTests(AtmCase atmCase) { Atm atm = new Atm(); for (Map deposit : atmCase.deposits) { - atm.deposit(toIntMap(deposit)); + atm.deposit(toMap(deposit)); } if (atmCase.expect.exception != null) { @@ -105,8 +99,8 @@ void additionalTests(AtmCase atmCase) { "Case: " + atmCase.name); assertEquals(atmCase.expect.balance, atm.getBalance(), "Case: " + atmCase.name); } else { - Map result = atm.withdraw(atmCase.withdraw); - assertEquals(toIntMap(atmCase.expect.dispense), result, "Case: " + atmCase.name); + Map result = atm.withdraw(atmCase.withdraw); + assertEquals(toMap(atmCase.expect.dispense), result, "Case: " + atmCase.name); assertEquals(atmCase.expect.balance, atm.getBalance(), "Case: " + atmCase.name); } } @@ -126,10 +120,10 @@ private static List loadCases() throws IOException { } } - private Map toIntMap(Map source) { - Map result = new HashMap<>(); + private Map toMap(Map source) { + Map result = new HashMap<>(); for (Map.Entry entry : source.entrySet()) { - result.put(Integer.parseInt(entry.getKey()), entry.getValue()); + result.put(Atm.Denomination.fromInt(Integer.parseInt(entry.getKey())), entry.getValue()); } return result; } diff --git a/src/test/java/hse/java/practice/task1/CubeSimpleTest.java b/src/test/java/hse/java/practice/task1/CubeSimpleTest.java new file mode 100644 index 00000000..b13c4af7 --- /dev/null +++ b/src/test/java/hse/java/practice/task1/CubeSimpleTest.java @@ -0,0 +1,277 @@ +package hse.java.practice.task1; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +public class CubeSimpleTest { + + private static final ObjectMapper MAPPER = new ObjectMapper(); + + @Test + void printTest() { + RubiksCube cube = new RubiksCube(); + CubeColor[] colors = CubeColor.values(); + for (int i = 0; i < 6; i++) { + Edge edge = cube.getEdges()[i]; + CubeColor[][] edgeColors = edge.getParts(); + for (CubeColor[] row : edgeColors) { + for (CubeColor color : row) { + Assertions.assertEquals(color, colors[i]); + } + } + } + } + + @Test + void frontClockwise() { + RubiksCube cube = new RubiksCube(); + cube.front(RotateDirection.CLOCKWISE); + + CubeColor[][][] state = readStateFromFile("frontClockwieseState.json"); + + CubeColor[][][] actuallyState = Arrays.stream(cube.getEdges()) + .map(Edge::getParts) + .toArray(CubeColor[][][]::new); + + Assertions.assertArrayEquals(state, actuallyState); + } + + @Test + void frontCounterclockwise() { + RubiksCube cube = new RubiksCube(); + // Поворот против часовой стрелки = 3 поворота по часовой стрелке + cube.front(RotateDirection.COUNTERCLOCKWISE); + + // Проверяем, что 4 поворота против часовой возвращают в исходное состояние + cube.front(RotateDirection.COUNTERCLOCKWISE); + cube.front(RotateDirection.COUNTERCLOCKWISE); + cube.front(RotateDirection.COUNTERCLOCKWISE); + + CubeColor[] colors = CubeColor.values(); + for (int i = 0; i < 6; i++) { + Edge edge = cube.getEdges()[i]; + CubeColor[][] edgeColors = edge.getParts(); + for (CubeColor[] row : edgeColors) { + for (CubeColor color : row) { + Assertions.assertEquals(colors[i], color); + } + } + } + } + + @Test + void upClockwise() { + RubiksCube cube = new RubiksCube(); + cube.up(RotateDirection.CLOCKWISE); + + CubeColor[][][] state = readStateFromFile("upClockwiseState.json"); + + CubeColor[][][] actuallyState = Arrays.stream(cube.getEdges()) + .map(Edge::getParts) + .toArray(CubeColor[][][]::new); + + Assertions.assertArrayEquals(state, actuallyState); + } + + @Test + void upCounterclockwise() { + RubiksCube cube = new RubiksCube(); + cube.up(RotateDirection.COUNTERCLOCKWISE); + cube.up(RotateDirection.COUNTERCLOCKWISE); + cube.up(RotateDirection.COUNTERCLOCKWISE); + cube.up(RotateDirection.COUNTERCLOCKWISE); + + CubeColor[] colors = CubeColor.values(); + for (int i = 0; i < 6; i++) { + Edge edge = cube.getEdges()[i]; + CubeColor[][] edgeColors = edge.getParts(); + for (CubeColor[] row : edgeColors) { + for (CubeColor color : row) { + Assertions.assertEquals(colors[i], color); + } + } + } + } + + @Test + void downClockwise() { + RubiksCube cube = new RubiksCube(); + cube.down(RotateDirection.CLOCKWISE); + + CubeColor[][][] state = readStateFromFile("downClockwiseState.json"); + + CubeColor[][][] actuallyState = Arrays.stream(cube.getEdges()) + .map(Edge::getParts) + .toArray(CubeColor[][][]::new); + + Assertions.assertArrayEquals(state, actuallyState); + } + + @Test + void downCounterclockwise() { + RubiksCube cube = new RubiksCube(); + cube.down(RotateDirection.COUNTERCLOCKWISE); + cube.down(RotateDirection.COUNTERCLOCKWISE); + cube.down(RotateDirection.COUNTERCLOCKWISE); + cube.down(RotateDirection.COUNTERCLOCKWISE); + + CubeColor[] colors = CubeColor.values(); + for (int i = 0; i < 6; i++) { + Edge edge = cube.getEdges()[i]; + CubeColor[][] edgeColors = edge.getParts(); + for (CubeColor[] row : edgeColors) { + for (CubeColor color : row) { + Assertions.assertEquals(colors[i], color); + } + } + } + } + + @Test + void leftClockwise() { + RubiksCube cube = new RubiksCube(); + cube.left(RotateDirection.CLOCKWISE); + + CubeColor[][][] state = readStateFromFile("leftClockwiseState.json"); + + CubeColor[][][] actuallyState = Arrays.stream(cube.getEdges()) + .map(Edge::getParts) + .toArray(CubeColor[][][]::new); + + Assertions.assertArrayEquals(state, actuallyState); + } + + @Test + void leftCounterclockwise() { + RubiksCube cube = new RubiksCube(); + cube.left(RotateDirection.COUNTERCLOCKWISE); + cube.left(RotateDirection.COUNTERCLOCKWISE); + cube.left(RotateDirection.COUNTERCLOCKWISE); + cube.left(RotateDirection.COUNTERCLOCKWISE); + + CubeColor[] colors = CubeColor.values(); + for (int i = 0; i < 6; i++) { + Edge edge = cube.getEdges()[i]; + CubeColor[][] edgeColors = edge.getParts(); + for (CubeColor[] row : edgeColors) { + for (CubeColor color : row) { + Assertions.assertEquals(colors[i], color); + } + } + } + } + + @Test + void rightClockwise() { + RubiksCube cube = new RubiksCube(); + cube.right(RotateDirection.CLOCKWISE); + + CubeColor[][][] state = readStateFromFile("rightClockwiseState.json"); + + CubeColor[][][] actuallyState = Arrays.stream(cube.getEdges()) + .map(Edge::getParts) + .toArray(CubeColor[][][]::new); + + Assertions.assertArrayEquals(state, actuallyState); + } + + @Test + void rightCounterclockwise() { + RubiksCube cube = new RubiksCube(); + cube.right(RotateDirection.COUNTERCLOCKWISE); + cube.right(RotateDirection.COUNTERCLOCKWISE); + cube.right(RotateDirection.COUNTERCLOCKWISE); + cube.right(RotateDirection.COUNTERCLOCKWISE); + + CubeColor[] colors = CubeColor.values(); + for (int i = 0; i < 6; i++) { + Edge edge = cube.getEdges()[i]; + CubeColor[][] edgeColors = edge.getParts(); + for (CubeColor[] row : edgeColors) { + for (CubeColor color : row) { + Assertions.assertEquals(colors[i], color); + } + } + } + } + + @Test + void backClockwise() { + RubiksCube cube = new RubiksCube(); + cube.back(RotateDirection.CLOCKWISE); + + CubeColor[][][] state = readStateFromFile("backClockwiseState.json"); + + CubeColor[][][] actuallyState = Arrays.stream(cube.getEdges()) + .map(Edge::getParts) + .toArray(CubeColor[][][]::new); + + Assertions.assertArrayEquals(state, actuallyState); + } + + @Test + void backCounterclockwise() { + RubiksCube cube = new RubiksCube(); + cube.back(RotateDirection.COUNTERCLOCKWISE); + cube.back(RotateDirection.COUNTERCLOCKWISE); + cube.back(RotateDirection.COUNTERCLOCKWISE); + cube.back(RotateDirection.COUNTERCLOCKWISE); + + CubeColor[] colors = CubeColor.values(); + for (int i = 0; i < 6; i++) { + Edge edge = cube.getEdges()[i]; + CubeColor[][] edgeColors = edge.getParts(); + for (CubeColor[] row : edgeColors) { + for (CubeColor color : row) { + Assertions.assertEquals(colors[i], color); + } + } + } + } + + @Test + void combinedRotations() { + RubiksCube cube = new RubiksCube(); + + // Выполняем последовательность поворотов + cube.front(RotateDirection.CLOCKWISE); + cube.right(RotateDirection.CLOCKWISE); + cube.up(RotateDirection.CLOCKWISE); + + // Выполняем обратную последовательность + cube.up(RotateDirection.COUNTERCLOCKWISE); + cube.right(RotateDirection.COUNTERCLOCKWISE); + cube.front(RotateDirection.COUNTERCLOCKWISE); + + // Должны вернуться в исходное состояние + CubeColor[] colors = CubeColor.values(); + for (int i = 0; i < 6; i++) { + Edge edge = cube.getEdges()[i]; + CubeColor[][] edgeColors = edge.getParts(); + for (CubeColor[] row : edgeColors) { + for (CubeColor color : row) { + Assertions.assertEquals(colors[i], color); + } + } + } + } + + private CubeColor[][][] readStateFromFile(String fileName) { + String resourcePath = "hse/java/practice/task1/" + fileName; + try (InputStream is = CubeSimpleTest.class.getClassLoader().getResourceAsStream(resourcePath)) { + if (is == null) { + throw new IllegalArgumentException("Resource not found: " + resourcePath); + } + String json = new String(is.readAllBytes(), StandardCharsets.UTF_8); + return MAPPER.readValue(json, CubeColor[][][].class); + } catch (IOException e) { + throw new RuntimeException("Failed to read/parse state file: " + fileName, e); + } + } +} From 705709a6e311e9a11319ff6b8e377ba4c234969c Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 7 Feb 2026 18:08:33 +0300 Subject: [PATCH 08/13] practice 2: RandomSet --- .github/workflows/pr-tests.yml | 38 ++++++++++++-- commander/commander.iml | 9 ---- pom.xml | 9 +++- .../java/lectures/lecture3/examples/Main.java | 1 + .../practice/randomSet/EmptySetException.java | 7 +++ .../practice/randomSet/RandomSet.java | 21 ++++++++ .../lecture3/practice/randomSet/task.md | 50 +++++++++++++++++++ .../practice/randomSet/RandomSetBaseTest.java | 28 +++++++++++ 8 files changed, 148 insertions(+), 15 deletions(-) delete mode 100644 commander/commander.iml create mode 100644 src/main/java/hse/java/lectures/lecture3/practice/randomSet/EmptySetException.java create mode 100644 src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java create mode 100644 src/main/java/hse/java/lectures/lecture3/practice/randomSet/task.md create mode 100644 src/test/java/hse/java/lectures/lecture3/practice/randomSet/RandomSetBaseTest.java diff --git a/.github/workflows/pr-tests.yml b/.github/workflows/pr-tests.yml index 8c507688..7272e99b 100644 --- a/.github/workflows/pr-tests.yml +++ b/.github/workflows/pr-tests.yml @@ -36,13 +36,41 @@ jobs: - name: Copy test files run: | - echo "Copying test data" - mkdir -p src/test/resources + echo "Copying hidden tests" + mkdir -p src/test/java src/test/resources + cp -R hidden-tests/src/test/java/. src/test/java/ cp -R hidden-tests/src/test/resources/. src/test/resources/ echo "" echo "Скопированы файлы:" - find src/test/resources -type f | sort | while read f; do echo " $f"; done + find src/test/java src/test/resources -type f | sort | while read f; do echo " $f"; done rm -rf hidden-tests - + + - name: Run honors no-collections test + id: honors_test + continue-on-error: true + run: mvn -B -Dtest=hse.java.lectures.lecture3.practice.randomSet.RandomSetBytecodeTest test + + - name: Comment on PR for honors solution + if: steps.honors_test.outcome == 'success' + uses: actions/github-script@v7 + with: + script: | + const pr = context.payload.pull_request; + if (!pr) { + core.info('No PR context, skipping comment.'); + return; + } + const body = [ + 'Поздравляем! 🎉', + '', + 'Вы решили сложную версию: решение прошло проверку «без коллекций».' + ].join('\\n'); + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + body + }); + - name: Run tests - run: mvn -B test + run: mvn -B -Dtest='!**/RandomSetBytecodeTest' test diff --git a/commander/commander.iml b/commander/commander.iml deleted file mode 100644 index 68a9707e..00000000 --- a/commander/commander.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/pom.xml b/pom.xml index ade43fe2..648f8788 100644 --- a/pom.xml +++ b/pom.xml @@ -24,6 +24,13 @@ ${junit.version} test + + + org.ow2.asm + asm + 9.8 + test + com.fasterxml.jackson.core @@ -65,4 +72,4 @@ - \ No newline at end of file + diff --git a/src/main/java/hse/java/lectures/lecture3/examples/Main.java b/src/main/java/hse/java/lectures/lecture3/examples/Main.java index d4279be4..116ff543 100644 --- a/src/main/java/hse/java/lectures/lecture3/examples/Main.java +++ b/src/main/java/hse/java/lectures/lecture3/examples/Main.java @@ -14,5 +14,6 @@ public static void main(String[] args) { Box nBox = box; new Methods().get(new ArrayList()).add(1); + } } diff --git a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/EmptySetException.java b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/EmptySetException.java new file mode 100644 index 00000000..c7820ac5 --- /dev/null +++ b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/EmptySetException.java @@ -0,0 +1,7 @@ +package hse.java.lectures.lecture3.practice.randomSet; + +public class EmptySetException extends RuntimeException { + public EmptySetException(String message) { + super(message); + } +} diff --git a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java new file mode 100644 index 00000000..8af477b5 --- /dev/null +++ b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java @@ -0,0 +1,21 @@ +package hse.java.lectures.lecture3.practice.randomSet; + +public class RandomSet { + + public boolean insert(T value) { + throw new UnsupportedOperationException("Not implemented"); + } + + public boolean remove(T value) { + throw new UnsupportedOperationException("Not implemented"); + } + + public boolean contains(T value) { + throw new UnsupportedOperationException("Not implemented"); + } + + public T getRandom() { + throw new UnsupportedOperationException("Not implemented"); + } + +} diff --git a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/task.md b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/task.md new file mode 100644 index 00000000..05e9740b --- /dev/null +++ b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/task.md @@ -0,0 +1,50 @@ +# Случайное множество (RandomSet) + +## Условие + +Реализовать класс `RandomSet`, который хранит множество целых чисел и поддерживает операции вставки, удаления и получения случайного элемента. + +## Требования к асимптотике + +- `insert(x)` — **O(log n) or O(1)** +- `remove(x)` — **O(log n) or O(1)** +- `contains(x)` — **(log n) or O(1)** +- `getRandom()` — **O(1)** + +Не допускается использование стандартных коллекций Java. + +## Публичный API + +1. `RandomSet()` — создаёт пустое множество. +1. `boolean insert(T value)` — добавляет `value` в множество. + - Возвращает `true`, если элемент добавлен. + - Возвращает `false`, если элемент уже был в множестве. +1. `boolean remove(T value)` — удаляет `value` из множества. + - Возвращает `true`, если элемент был удалён. + - Возвращает `false`, если элемента не было. +1. `boolean contains(T value)` — проверяет наличие `value` в множестве. + - Возвращает `true`, если элемент есть. + - Возвращает `false`, если элемента нет. +1. `T getRandom()` — возвращает случайный элемент из множества. + - Если множество пустое, выбрасывает `EmptySetException`. + +## Исключения + +- `EmptySetException` — попытка получить случайный элемент из пустого множества. + +## Пример + +```java +RandomSet set = new RandomSet<>(); +set.insert(10); // true +set.insert(20); // true +set.insert(10); // false + +int x = set.getRandom(); // 10 или 20 + +set.remove(10); // true +set.remove(10); // false + +set.contains(20); // true +set.contains(30); // false +``` diff --git a/src/test/java/hse/java/lectures/lecture3/practice/randomSet/RandomSetBaseTest.java b/src/test/java/hse/java/lectures/lecture3/practice/randomSet/RandomSetBaseTest.java new file mode 100644 index 00000000..37c38ab1 --- /dev/null +++ b/src/test/java/hse/java/lectures/lecture3/practice/randomSet/RandomSetBaseTest.java @@ -0,0 +1,28 @@ +package hse.java.lectures.lecture3.practice.randomSet; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class RandomSetBaseTest { + + @Test + void insertRemoveContains() { + RandomSet set = new RandomSet<>(); + + assertTrue(set.insert(10)); + assertTrue(set.insert(20)); + assertFalse(set.insert(10)); + + assertTrue(set.contains(10)); + assertTrue(set.contains(20)); + assertFalse(set.contains(30)); + + assertTrue(set.remove(10)); + assertFalse(set.remove(10)); + + assertFalse(set.contains(10)); + assertTrue(set.contains(20)); + } + +} From fa91cf617c81f6ced869b5816396d27ed4923175 Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 7 Feb 2026 18:25:21 +0300 Subject: [PATCH 09/13] fix ci --- .github/workflows/pr-tests.yml | 59 ++++++++++++++++++- README-commit-format.md | 20 +++++++ .../lecture3/practice/randomSet/task.md | 2 + .../java/lectures/lecture3/tasks/atm/task.md | 2 + .../java/lectures/lecture3/tasks/html/task.md | 2 + src/main/java/hse/java/practice/task1/task.md | 2 + 6 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 README-commit-format.md diff --git a/.github/workflows/pr-tests.yml b/.github/workflows/pr-tests.yml index 7272e99b..b296bc45 100644 --- a/.github/workflows/pr-tests.yml +++ b/.github/workflows/pr-tests.yml @@ -45,9 +45,37 @@ jobs: find src/test/java src/test/resources -type f | sort | while read f; do echo " $f"; done rm -rf hidden-tests + - name: Select test pattern from PR labels + id: select_tests + uses: actions/github-script@v7 + with: + script: | + const pr = context.payload.pull_request; + if (!pr) { + core.setOutput('pattern', ''); + return; + } + const repo = { owner: context.repo.owner, repo: context.repo.repo }; + const { data: commit } = await github.rest.repos.getCommit({ + ...repo, + ref: pr.head.sha + }); + const msg = (commit.commit.message || '').toLowerCase(); + + const patterns = []; + const add = (p) => { if (!patterns.includes(p)) patterns.push(p); }; + + if (msg.startsWith('atm:')) add('**/atm/*Test'); + if (msg.startsWith('html:')) add('**/html/*Test'); + if (msg.startsWith('randomset:')) add('**/randomSet/*Test'); + + // If no task prefix, run all tests + core.setOutput('pattern', patterns.length ? patterns.join(',') : ''); + - name: Run honors no-collections test id: honors_test continue-on-error: true + if: steps.select_tests.outputs.pattern == '**/randomSet/*Test' run: mvn -B -Dtest=hse.java.lectures.lecture3.practice.randomSet.RandomSetBytecodeTest test - name: Comment on PR for honors solution @@ -73,4 +101,33 @@ jobs: }); - name: Run tests - run: mvn -B -Dtest='!**/RandomSetBytecodeTest' test + run: | + if [ -n "${{ steps.select_tests.outputs.pattern }}" ]; then + echo "Running selected tests: ${{ steps.select_tests.outputs.pattern }}" + mvn -B -Dtest='${{ steps.select_tests.outputs.pattern }}' test + else + echo "No task prefix found. Skipping tests." + fi + + - name: Comment on PR when no task prefix + if: steps.select_tests.outputs.pattern == '' + uses: actions/github-script@v7 + with: + script: | + const pr = context.payload.pull_request; + if (!pr) { + core.info('No PR context, skipping comment.'); + return; + } + const body = [ + 'Тесты не запускались.', + '', + 'Укажите задачу в начале сообщения коммита:', + '`atm: ...`, `html: ...`, `randomset: ...`' + ].join('\\n'); + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + body + }); diff --git a/README-commit-format.md b/README-commit-format.md new file mode 100644 index 00000000..24c170a4 --- /dev/null +++ b/README-commit-format.md @@ -0,0 +1,20 @@ +# Формат коммитов для запуска тестов + +## Зачем это нужно +CI запускает тесты выборочно. Чтобы он знал, какие тесты запускать, сообщение коммита должно начинаться с названия задачи. + +## Формат +Используйте префикс в начале сообщения коммита: + +- `atm: ...` +- `html: ...` +- `randomset: ...` + +Тег задачи указывается в описании каждой задачи + +Пример: +``` +randomset: implement getRandom and contains +``` + +Если префикс не указан, CI **не запускает тесты** и оставляет комментарий в PR. diff --git a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/task.md b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/task.md index 05e9740b..fb987780 100644 --- a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/task.md +++ b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/task.md @@ -1,5 +1,7 @@ # Случайное множество (RandomSet) +Tag: randomset + ## Условие Реализовать класс `RandomSet`, который хранит множество целых чисел и поддерживает операции вставки, удаления и получения случайного элемента. diff --git a/src/main/java/hse/java/lectures/lecture3/tasks/atm/task.md b/src/main/java/hse/java/lectures/lecture3/tasks/atm/task.md index 3845672e..6d574e19 100644 --- a/src/main/java/hse/java/lectures/lecture3/tasks/atm/task.md +++ b/src/main/java/hse/java/lectures/lecture3/tasks/atm/task.md @@ -1,5 +1,7 @@ # Банкомат (ATM) +Tag: atm + ## Условие Реализовать класс `Atm`, который хранит купюры фиксированных номиналов и выполняет операции пополнения и выдачи наличных. При ошибках операции должны завершаться выбросом исключения без изменения состояния банкомата. diff --git a/src/main/java/hse/java/lectures/lecture3/tasks/html/task.md b/src/main/java/hse/java/lectures/lecture3/tasks/html/task.md index 4ec71b18..2160175f 100644 --- a/src/main/java/hse/java/lectures/lecture3/tasks/html/task.md +++ b/src/main/java/hse/java/lectures/lecture3/tasks/html/task.md @@ -1,5 +1,7 @@ # Валидация HTML-документа +Tag: html + ## Условие Реализовать класс `HtmlDocument`, который читает HTML-текст из файла и проверяет корректность структуры. Если документ невалиден, при создании объекта выбрасывается исключение. diff --git a/src/main/java/hse/java/practice/task1/task.md b/src/main/java/hse/java/practice/task1/task.md index 235cc660..60dc4533 100644 --- a/src/main/java/hse/java/practice/task1/task.md +++ b/src/main/java/hse/java/practice/task1/task.md @@ -1,5 +1,7 @@ Необходимо реализовать методы поворота кубика Рубика. +Tag: cube + Кубик представляет собой классический куб 3×3×3: - 6 граней; - каждая грань состоит из 9 элементов (стикеров); From f296512376ec83b6f846aa67e911da26f00245fa Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 7 Feb 2026 18:27:32 +0300 Subject: [PATCH 10/13] fix ci --- .github/workflows/pr-tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pr-tests.yml b/.github/workflows/pr-tests.yml index b296bc45..aa378cae 100644 --- a/.github/workflows/pr-tests.yml +++ b/.github/workflows/pr-tests.yml @@ -68,6 +68,7 @@ jobs: if (msg.startsWith('atm:')) add('**/atm/*Test'); if (msg.startsWith('html:')) add('**/html/*Test'); if (msg.startsWith('randomset:')) add('**/randomSet/*Test'); + if (msg.startsWith('cube:')) add('**/CubeSimpleTest'); // If no task prefix, run all tests core.setOutput('pattern', patterns.length ? patterns.join(',') : ''); From 13c318495bdb223d8bfd6fc5376c46fe6bb4d5e4 Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 7 Feb 2026 18:33:08 +0300 Subject: [PATCH 11/13] fix ci --- .github/workflows/pr-tests.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/pr-tests.yml b/.github/workflows/pr-tests.yml index aa378cae..da9457f0 100644 --- a/.github/workflows/pr-tests.yml +++ b/.github/workflows/pr-tests.yml @@ -45,7 +45,7 @@ jobs: find src/test/java src/test/resources -type f | sort | while read f; do echo " $f"; done rm -rf hidden-tests - - name: Select test pattern from PR labels + - name: Select test pattern from commit message id: select_tests uses: actions/github-script@v7 with: @@ -70,7 +70,6 @@ jobs: if (msg.startsWith('randomset:')) add('**/randomSet/*Test'); if (msg.startsWith('cube:')) add('**/CubeSimpleTest'); - // If no task prefix, run all tests core.setOutput('pattern', patterns.length ? patterns.join(',') : ''); - name: Run honors no-collections test @@ -93,7 +92,7 @@ jobs: 'Поздравляем! 🎉', '', 'Вы решили сложную версию: решение прошло проверку «без коллекций».' - ].join('\\n'); + ].join('\n'); await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, @@ -107,7 +106,8 @@ jobs: echo "Running selected tests: ${{ steps.select_tests.outputs.pattern }}" mvn -B -Dtest='${{ steps.select_tests.outputs.pattern }}' test else - echo "No task prefix found. Skipping tests." + echo "No task prefix found. Failing." + exit 1 fi - name: Comment on PR when no task prefix @@ -124,8 +124,8 @@ jobs: 'Тесты не запускались.', '', 'Укажите задачу в начале сообщения коммита:', - '`atm: ...`, `html: ...`, `randomset: ...`' - ].join('\\n'); + 'atm: ..., html: ..., randomset: ...' + ].join('\n'); await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, From 729d33c39d50fd90329be61bc63092f51060e6fd Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 7 Feb 2026 18:37:15 +0300 Subject: [PATCH 12/13] fix CI --- .github/workflows/pr-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-tests.yml b/.github/workflows/pr-tests.yml index da9457f0..d9a5bdfc 100644 --- a/.github/workflows/pr-tests.yml +++ b/.github/workflows/pr-tests.yml @@ -104,7 +104,7 @@ jobs: run: | if [ -n "${{ steps.select_tests.outputs.pattern }}" ]; then echo "Running selected tests: ${{ steps.select_tests.outputs.pattern }}" - mvn -B -Dtest='${{ steps.select_tests.outputs.pattern }}' test + mvn -B -Dtest='${{ steps.select_tests.outputs.pattern }},!**/RandomSetBytecodeTest' test else echo "No task prefix found. Failing." exit 1 From 00c613435ea1ff430d3d324d58829f197ff92581 Mon Sep 17 00:00:00 2001 From: marr97 Date: Sat, 7 Feb 2026 21:30:48 +0300 Subject: [PATCH 13/13] cube: once again --- src/main/java/hse/java/practice/task1/RubiksCube.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/main/java/hse/java/practice/task1/RubiksCube.java b/src/main/java/hse/java/practice/task1/RubiksCube.java index a57b2e7e..160a2406 100644 --- a/src/main/java/hse/java/practice/task1/RubiksCube.java +++ b/src/main/java/hse/java/practice/task1/RubiksCube.java @@ -2,23 +2,12 @@ import java.util.Arrays; -/** - * Необходимо реализовать интерфейс Cube - * При повороте передней грани, меняются верх низ право и лево - */ public class RubiksCube implements Cube{ private static final int EDGES_COUNT = 6; private final Edge[] edges = new Edge[EDGES_COUNT]; - /** - * Создать валидный собранный кубик - * грани разместить по ордеру в енуме цветов - * грань 0 -> цвет 0 - * грань 1 -> цвет 1 - * ... - */ public RubiksCube() { CubeColor[] colors = CubeColor.values(); for (int i = 0; i < 6; i++) {