diff --git a/pom.xml b/pom.xml index 7fced37..092333f 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,6 @@ 21 17 17 - --enable-preview diff --git a/src/main/java/algorithms/sprint0/AB.java b/src/main/java/algorithms/sprint0/AB.java new file mode 100644 index 0000000..5258660 --- /dev/null +++ b/src/main/java/algorithms/sprint0/AB.java @@ -0,0 +1,74 @@ +package algorithms.sprint0; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; +import java.util.InputMismatchException; +import java.util.Scanner; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class AB { + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + int a = sc.nextInt(); + int b = sc.nextInt(); + long sum = sum(a, b); + System.out.println(sum); + } + + public static long sum(int a, int b) { + return (long) a + b; + } + + @Test + public void test() { + assertEquals(5, sum(2, 3)); + assertEquals(-1, sum(-2, 1)); + } + + @ParameterizedTest + @CsvSource({ + "0,0,0", + "2,3,5", + "-1,4,3", + "2147483647,1,2147483648", + "2000000000,2000000000,4000000000" + }) + void sum_works(int a, int b, long expected) { + assertEquals(expected, AB.sum(a, b)); + } + + @Test + void main_prints_sum_basic() { + String in = "2 3\n"; + InputStream oldIn = System.in; + PrintStream oldOut = System.out; + try { + System.setIn(new ByteArrayInputStream(in.getBytes(StandardCharsets.UTF_8))); + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + System.setOut(new PrintStream(buf, true, StandardCharsets.UTF_8)); + + AB.main(new String[0]); + + String nl = System.lineSeparator(); + assertEquals("5" + nl, buf.toString(StandardCharsets.UTF_8)); + } finally { + System.setIn(oldIn); + System.setOut(oldOut); + } + } + + @Test + void main_bad_input_throws() { + System.setIn(new ByteArrayInputStream("x y\n".getBytes(StandardCharsets.UTF_8))); + assertThrows(InputMismatchException.class, () -> AB.main(new String[0])); + } +} diff --git a/src/main/java/algorithms/sprint0/SlidingAverage.java b/src/main/java/algorithms/sprint0/SlidingAverage.java new file mode 100644 index 0000000..e5775bd --- /dev/null +++ b/src/main/java/algorithms/sprint0/SlidingAverage.java @@ -0,0 +1,100 @@ +package algorithms.sprint0; + +import org.junit.jupiter.api.Test; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; + +import static algorithms.sprint0.Utils.readInt; +import static algorithms.sprint0.Utils.readList; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class SlidingAverage { + + private static List movingAverage(int n, List arr, int windowSize) { + int minSize = Math.min(arr.size(), n); + int count = minSize - windowSize + 1; + if (windowSize <= 0 || count <= 0) return java.util.Collections.emptyList(); + List result = new ArrayList<>(count); + long sum = 0; + for (int i = 0; i < windowSize; i++) sum += arr.get(i); + result.add(sum / (double) windowSize); + for (int i = windowSize; i < minSize; i++) { + sum += arr.get(i) - arr.get(i - windowSize); + result.add(sum / (double) windowSize); + } + return result; + } + + public static void main(String[] args) throws IOException { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out))) { + int n = readInt(reader); + List arr = readList(reader); + int windowSize = readInt(reader); + List result = movingAverage(n, arr, windowSize); + for (double elem : result) { + writer.write(elem + " "); + } + } + } + + private static void assertListDoubles(List actual, double... expected) { + assertEquals(expected.length, actual.size(), "size"); + for (int i = 0; i < expected.length; i++) { + assertEquals(expected[i], actual.get(i), 1e-9, "idx=" + i); + } + } + + @Test + void test1() { + List actual = movingAverage(7, List.of(1, 2, 3, 4, 5, 6, 7), 4); + assertListDoubles(actual, 2.5, 3.5, 4.5, 5.5); + } + + @Test + void w1_returnsOriginalValues() { + List actual = movingAverage(7, List.of(1, 2, 3, 4, 5, 6, 7), 1); + assertListDoubles(actual, 1, 2, 3, 4, 5, 6, 7); + } + + @Test + void wEqMin_singleAverage() { + List actual = movingAverage(7, List.of(1, 2, 3, 4, 5, 6, 7), 7); + assertListDoubles(actual, 4.0); + } + + @Test + void wGreaterThanMin_empty() { + List actual = movingAverage(5, List.of(1, 2, 3, 4, 5, 6, 7), 6); + assertEquals(List.of(), actual); + } + + @Test + void wZeroOrNegative_empty() { + assertEquals(List.of(), movingAverage(5, List.of(1, 2, 3, 4, 5), 0)); + assertEquals(List.of(), movingAverage(5, List.of(1, 2, 3, 4, 5), -3)); + } + + @Test + void cutByN_truncatesAndAverages() { + List actual = movingAverage(5, List.of(1, 2, 3, 4, 5, 6, 7), 3); + // окна по первым 5 элементам: [1,2,3],[2,3,4],[3,4,5] + assertListDoubles(actual, 2.0, 3.0, 4.0); + } + + @Test + void emptyArray_empty() { + List actual = movingAverage(10, List.of(), 3); + assertEquals(List.of(), actual); + } + + @Test + void largeValues_noOverflowInSum() { + int M = Integer.MAX_VALUE; + List actual = movingAverage(4, List.of(M, M, M, M), 2); + // три окна: [M,M],[M,M],[M,M] → среднее = M + assertListDoubles(actual, M, M, M); + } +} diff --git a/src/main/java/algorithms/sprint0/Utils.java b/src/main/java/algorithms/sprint0/Utils.java new file mode 100644 index 0000000..37b903b --- /dev/null +++ b/src/main/java/algorithms/sprint0/Utils.java @@ -0,0 +1,150 @@ +package algorithms.sprint0; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.junit.jupiter.api.Test; + +import java.io.*; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.*; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class Utils { + + public static List readList(BufferedReader reader) throws IOException { + String line = reader.readLine(); + if (line == null) throw new NumberFormatException("EOF"); + return Arrays.stream(line.trim().split("\\s+")) + .map(Integer::parseInt) + .collect(Collectors.toList()); + } + + public static void printList(List list, Writer writer) { + for (T elem : list) { + try { + writer.write(String.valueOf(elem)); + writer.write(" "); + } catch (IOException ignored) { + } + } + } + + public static int readInt(BufferedReader reader) throws IOException { + String line = reader.readLine(); + if (line == null) throw new NumberFormatException("EOF"); + return Integer.parseInt(line); + } + + @Test + public void readListbasic() throws Exception { + BufferedReader br = new BufferedReader(new StringReader("1 2 3")); + List got = readList(br); + assertEquals(Arrays.asList(1, 2, 3), got); + } + + @Test + void readList_mixedWhitespace_and_signs() throws Exception { + BufferedReader br = new BufferedReader(new StringReader(" -1\t0 5 ")); + List got = readList(br); + assertEquals(Arrays.asList(-1, 0, 5), got); + } + + @Test + void readList_emptyLine_throwsNumberFormat() { + BufferedReader br = new BufferedReader(new StringReader("\\n")); + assertThrows(NumberFormatException.class, () -> readList(br)); + } + + @Test + void readList_EOF_throwsNumberFormat() { + BufferedReader br = new BufferedReader(new StringReader("")); + assertThrows(NumberFormatException.class, () -> readList(br)); + } + + @Test + void readList_nonIntegerToken_throwsNumberFormat() { + BufferedReader br = new BufferedReader(new StringReader("1 a 3")); + assertThrows(NumberFormatException.class, () -> readList(br)); + } + + @Test + void readList_overflow_throwsNumberFormat() { + BufferedReader br = new BufferedReader(new StringReader("2147483648")); + assertThrows(NumberFormatException.class, () -> readList(br)); + } + + // --- readInt --- + + @Test + void readInt_basic() throws Exception { + BufferedReader br = new BufferedReader(new StringReader("42")); + assertEquals(42, readInt(br)); + } + + @Test + void readInt_negative() throws Exception { + BufferedReader br = new BufferedReader(new StringReader("-7")); + assertEquals(-7, readInt(br)); + } + + @Test + void readInt_withSpaces_throwsNumberFormat() { + BufferedReader br = new BufferedReader(new StringReader(" 42 ")); + assertThrows(NumberFormatException.class, () -> readInt(br)); + } + + // --- printList --- + + @Test + void printList_integers_trailingSpace_noNewline() throws Exception { + StringWriter sw = new StringWriter(); + printList(Arrays.asList(1, 2, 3), sw); + assertEquals("1 2 3 ", sw.toString()); + } + + @Test + void printList_strings_usesToString() throws Exception { + StringWriter sw = new StringWriter(); + printList(Arrays.asList("a", "b"), sw); + assertEquals("a b ", sw.toString()); + } + + @Test + void printList_empty_writesNothing() throws Exception { + StringWriter sw = new StringWriter(); + printList(List.of(), sw); + assertEquals("", sw.toString()); + } + + @Test + void printList_ioExceptions_areSwallowed() { + Writer throwing = new Writer() { + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + throw new IOException("boom"); + } + + @Override + public void flush() { + } + + @Override + public void close() { + } + + @Override + public void write(String str) throws IOException { + throw new IOException("boom"); + } + + @Override + public void write(int c) throws IOException { + throw new IOException("boom"); + } + }; + assertDoesNotThrow(() -> printList(Arrays.asList(1, 2, 3), throwing)); + } +} diff --git a/src/main/java/algorithms/sprint0/Zip.java b/src/main/java/algorithms/sprint0/Zip.java new file mode 100644 index 0000000..257ef4a --- /dev/null +++ b/src/main/java/algorithms/sprint0/Zip.java @@ -0,0 +1,97 @@ +package algorithms.sprint0; + +import org.junit.jupiter.api.Test; + +import java.io.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static algorithms.sprint0.Utils.printList; +import static algorithms.sprint0.Utils.readList; +import static org.junit.jupiter.api.Assertions.*; + +public class Zip { + + private static List zip(List a, List b, int n) { + if (n < 0) throw new IllegalArgumentException("n >= 0 required"); + int min = Math.min(n, Math.min(a.size(), b.size())); + ArrayList integers = new ArrayList<>(min * 2); + + for (int i = 0; i < min; i++) { + integers.add(a.get(i)); + integers.add(b.get(i)); + } + return integers; + } + + public static void main(String[] args) throws IOException { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out))) { + int n = Integer.parseInt(reader.readLine().trim()); + List a = readList(reader); + List b = readList(reader); + printList(zip(a, b, n), writer); + } + } + + @Test + void equalLength_nEqualsSize() { + List a = Arrays.asList(1, 3, 5); + List b = Arrays.asList(2, 4, 6); + assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6), zip(a, b, 3)); + } + + @Test + void nSmallerThanSizes() { + List a = Arrays.asList(10, 30, 50); + List b = Arrays.asList(20, 40, 60); + assertEquals(Arrays.asList(10, 20, 30, 40), zip(a, b, 2)); + } + + @Test + void nZero_returnsEmpty() { + List a = Arrays.asList(1, 3, 5); + List b = Arrays.asList(2, 4, 6); + assertTrue(zip(a, b, 0).isEmpty()); + } + + @Test + void nGreaterThanSizes_clampedToMin() { + List a = Arrays.asList(1, 3, 5); + List b = Arrays.asList(2, 4, 6); + assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6), zip(a, b, 10)); + } + + @Test + void oneListShorter_minByShorter() { + List a = List.of(1); + List b = Arrays.asList(2, 4, 6); + assertEquals(Arrays.asList(1, 2), zip(a, b, 3)); + } + + @Test + void emptyLists_anyN_returnsEmpty() { + List a = List.of(); + List b = List.of(); + assertTrue(zip(a, b, 5).isEmpty()); + } + + @Test + void negativeN_throwsIAE_withMessage() { + IllegalArgumentException ex = + assertThrows(IllegalArgumentException.class, + () -> zip(List.of(1), List.of(2), -1)); + assertTrue(ex.getMessage().contains("n >= 0")); + } + + @Test + void nullA_throwsNPE() { + assertThrows(NullPointerException.class, () -> zip(null, List.of(2), 1)); + } + + @Test + void nullB_throwsNPE() { + assertThrows(NullPointerException.class, () -> zip(List.of(1), null, 1)); + } +} diff --git a/src/main/java/algorithms/sprint1/Distances.java b/src/main/java/algorithms/sprint1/Distances.java new file mode 100644 index 0000000..5392669 --- /dev/null +++ b/src/main/java/algorithms/sprint1/Distances.java @@ -0,0 +1,160 @@ +import java.io.*; +import java.util.Arrays; + +// https://contest.yandex.ru/contest/22450/run-report/157289807/ +public class Distances { + + // -------------------- SOLUTION -------------------- + static int[] solve(int[] a) { + int n = a.length; + int[] dist = new int[n]; + + int lastZero = -n; + for (int i = 0; i < n; i++) { + if (a[i] == 0) { + lastZero = i; + } + dist[i] = i - lastZero; + } + + int nextZero = lastZero; + for (int i = lastZero; i >= 0; i--) { + if (a[i] == 0) nextZero = i; + dist[i] = Math.min(dist[i], nextZero - i); + } + return dist; + } + + + // -------------------- FAST INPUT -------------------- + static final class FastIn { + private final InputStream in; + private final byte[] buf = new byte[1 << 16]; + private int ptr = 0, len = 0; + + FastIn(InputStream in) { + this.in = in; + } + + private int read() throws IOException { + if (ptr >= len) { + len = in.read(buf); + ptr = 0; + if (len <= 0) return -1; + } + return buf[ptr++]; + } + + int nextInt() throws IOException { + int c; + do { + c = read(); + if (c == -1) throw new EOFException("Unexpected EOF"); + } while (c <= ' '); + + int sign = 1; + if (c == '-') { + sign = -1; + c = read(); + } + + int val = 0; + while (c > ' ') { + val = val * 10 + (c - '0'); + c = read(); + } + return val * sign; + } + } + + // -------------------- FAST OUTPUT -------------------- + static final class FastOut { + private final OutputStream out; + private final byte[] buf = new byte[1 << 16]; + private int p = 0; + private final byte[] tmp = new byte[12]; + + FastOut(OutputStream out) { + this.out = out; + } + + void writeByte(int b) throws IOException { + if (p == buf.length) flush(); + buf[p++] = (byte) b; + } + + void writeInt(int x) throws IOException { + if (x == 0) { + writeByte('0'); + return; + } + if (x < 0) { + writeByte('-'); + x = -x; + } + + int k = 0; + while (x > 0) { + tmp[k++] = (byte) ('0' + (x % 10)); + x /= 10; + } + for (int i = k - 1; i >= 0; i--) writeByte(tmp[i]); + } + + void flush() throws IOException { + out.write(buf, 0, p); + p = 0; + } + } + + // -------------------- INPUT / OUTPUT -------------------- + static void run() { + + try (InputStream input = new BufferedInputStream(new FileInputStream("input.txt")); OutputStream output = new BufferedOutputStream(new FileOutputStream("output.txt"))) { + + + FastIn in = new FastIn(input); + FastOut out = new FastOut(output); + + int n = in.nextInt(); + int[] a = new int[n]; + for (int i = 0; i < n; i++) a[i] = in.nextInt(); + + int[] dist = solve(a); + + for (int i = 0; i < n; i++) { + if (i > 0) out.writeByte(' '); + out.writeInt(dist[i]); + } + out.writeByte('\n'); + out.flush(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + // -------------------- TESTS -------------------- + static void assertEq(int[] exp, int[] act, String name) { + if (!Arrays.equals(exp, act)) { + throw new AssertionError(name + "\nexp=" + Arrays.toString(exp) + "\nact=" + Arrays.toString(act)); + } + } + + static void test() { + assertEq(new int[]{0, 1, 2, 1, 0}, solve(new int[]{0, 1, 4, 9, 0}), "sample1"); + assertEq(new int[]{0, 1, 2, 3, 4, 5}, solve(new int[]{0, 7, 9, 4, 8, 20}), "sample2"); + assertEq(new int[]{0}, solve(new int[]{0}), "n=1"); + assertEq(new int[]{0, 0, 0}, solve(new int[]{0, 0, 0}), "all zeros"); + assertEq(new int[]{2, 1, 0, 1, 2}, solve(new int[]{5, 6, 0, 7, 8}), "zero in middle"); + System.out.println("OK"); + } + + // -------------------- MAIN -------------------- + public static void main(String[] args) throws Exception { + if (System.getProperty("os.name").startsWith("Windows")) { + test(); + } else { + run(); + } + } +} diff --git a/src/main/java/algorithms/sprint1/SleightOfHand.java b/src/main/java/algorithms/sprint1/SleightOfHand.java new file mode 100644 index 0000000..087bdb4 --- /dev/null +++ b/src/main/java/algorithms/sprint1/SleightOfHand.java @@ -0,0 +1,237 @@ +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +// https://contest.yandex.ru/contest/22450/run-report/157017632/ +public class SleightOfHand { + // -------------------- FAST INPUT -------------------- + static final class FastIn { + private final InputStream in; + private final byte[] buf = new byte[1 << 16]; + private int ptr = 0, len = 0; + + FastIn(InputStream in) { + this.in = in; + } + + private int read() throws IOException { + if (ptr >= len) { + len = in.read(buf); + ptr = 0; + if (len <= 0) return -1; + } + return buf[ptr++]; + } + + int nextInt() throws IOException { + int c; + do { + c = read(); + if (c == -1) throw new EOFException("Unexpected EOF"); + } while (c <= ' '); + + int sign = 1; + if (c == '-') { + sign = -1; + c = read(); + } + + int val = 0; + while (c > ' ') { + val = val * 10 + (c - '0'); + c = read(); + } + return val * sign; + } + + String next() throws IOException { + int c; + do { + c = read(); + if (c == -1) throw new EOFException("Unexpected EOF"); + } while (c <= ' '); + + byte[] tmp = new byte[32]; + int n = 0; + while (c > ' ') { + if (n == tmp.length) { + byte[] t2 = new byte[tmp.length * 2]; + System.arraycopy(tmp, 0, t2, 0, tmp.length); + tmp = t2; + } + tmp[n++] = (byte) c; + c = read(); + if (c == -1) break; + } + return new String(tmp, 0, n); + } + } + + // -------------------- FAST OUTPUT -------------------- + static final class FastOut { + private final OutputStream out; + private final byte[] buf = new byte[1 << 16]; + private int p = 0; + private final byte[] tmp = new byte[12]; + + FastOut(OutputStream out) { + this.out = out; + } + + void writeByte(int b) throws IOException { + if (p == buf.length) flush(); + buf[p++] = (byte) b; + } + + void writeInt(int x) throws IOException { + if (x == 0) { + writeByte('0'); + return; + } + if (x < 0) { + writeByte('-'); + x = -x; + } + + int k = 0; + while (x > 0) { + tmp[k++] = (byte) ('0' + (x % 10)); + x /= 10; + } + for (int i = k - 1; i >= 0; i--) writeByte(tmp[i]); + } + + void flush() throws IOException { + out.write(buf, 0, p); + p = 0; + } + } + + public static void main(String[] args) throws Exception { + if (System.getProperty("os.name").startsWith("Windows")) { + test(); + } else { + run(); + } + } + + private static void run() throws Exception { + FastIn in = new FastIn(System.in); + FastOut out = new FastOut(System.out); + + int k = in.nextInt(); + int limit = 2 * k; + int[] count = new int[10]; + + for (int r = 0; r < 4; r++) { + String s = in.next(); + // На всякий случай, если токенайзер разделит строку (обычно не будет) + while (s.length() < 4) { + s += in.next(); + } + for (int c = 0; c < 4; c++) { + char ch = s.charAt(c); + if (ch != '.') { + count[ch - '0']++; + } + } + } + + int points = 0; + for (int d = 1; d <= 9; d++) { + int cnt = count[d]; + if (cnt != 0 && cnt <= limit) { + points++; + } + } + + out.writeInt(points); + out.writeByte('\n'); + out.flush(); + } + + private static void test() { + // Примеры из условия + assertEq(2, solve(3, new int[][]{ + {1, 2, 3, 1}, + {2, 0, 0, 2}, + {2, 0, 0, 2}, + {2, 0, 0, 2} + })); + + assertEq(1, solve(4, new int[][]{ + {1, 1, 1, 1}, + {9, 9, 9, 9}, + {1, 1, 1, 1}, + {9, 9, 1, 1} + })); + + assertEq(0, solve(1, new int[][]{ + {1, 1, 1, 1}, + {1, 1, 1, 1}, + {1, 1, 1, 1}, + {1, 1, 1, 1} + })); + + // Критичный тест: ровно 2*k нажатий — очко должно засчитаться + assertEq(1, solve(2, new int[][]{ + {5, 5, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {5, 5, 0, 0} + })); + + // Чуть больше лимита — очко не должно засчитаться + assertEq(0, solve(2, new int[][]{ + {6, 6, 6, 0}, + {6, 6, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} + })); // 6 встречается 5 раз, limit=4 + + // Пустое поле + assertEq(0, solve(5, new int[][]{ + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} + })); + + // Несколько цифр в пределах лимита + assertEq(2, solve(1, new int[][]{ + {1, 1, 2, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} + })); // limit=2, cnt(1)=2, cnt(2)=1 + + System.out.println("Test OK"); + } + + static int solve(int k, int[][] a) { + int points = 0; + final int limit = 2 * k; + final int[] count = new int[10]; + + for (int[] row : a) { + for (int v : row) { + if (v != 0) count[v]++; + } + } + + for (int d = 1; d <= 9; d++) { + int cnt = count[d]; + if (cnt != 0 && cnt <= limit) { + points++; + } + } + return points; + } + + static void assertEq(int exp, int act) { + if (exp != act) { + throw new AssertionError("Expected=" + exp + ", actual=" + act); + } + } +} diff --git a/src/main/java/algorithms/sprint1/Solution2.java b/src/main/java/algorithms/sprint1/Solution2.java new file mode 100644 index 0000000..dcf5542 --- /dev/null +++ b/src/main/java/algorithms/sprint1/Solution2.java @@ -0,0 +1,55 @@ +package algorithms.sprint1; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.StringTokenizer; + +//