diff --git a/README.md b/README.md index 9fd4d09f..a782d5b7 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ $ git checkout -b part1 Решение каждой задачи - отдельный Java-класс. Можно воспользоваться классом `company.vk.polis.ads.SolveTemplate`, в котором остается реализовать лишь метод `solve`. * informatics-msk: добавлять ничего не нужно, статус решения отображается в общих результатах. -* E-olymp: В самом PR либо в его описании, либо в комментариях к каждому классу-решению нужно добавить ссылку на submission в e-olymp, где видно, что все решение прошло все тесты. +* E-olymp: В самом PR в его описании нужно добавить ссылку на submission в e-olymp, где видно, что решение прошло все тесты. Эти ссылки имеют вид "https://www.e-olymp.com/ru/submissions/5707028". Все обсуждения решения происходят в рамках комментариев к PR @@ -82,9 +82,9 @@ $ git checkout -b 6af9b4bc15fa61806ba537dea3d63f785a774a12 * https://www.e-olymp.com/ru/problems/4074 - Найти медиану 2 * https://www.e-olymp.com/ru/problems/3738 - Простая сортирока - реализовать HeapSort -* Реализовать методы `hasNext()` и `next()` в классе `company.vk.polis.ads.MergeIterator` так, чтобы успешно выполнялись тесты в `company.vk.polis.ads.MergeIteratorTest`. Время работы должно быть O(n logk), где n - суммарное количество всех элементов в k подаваемых на вход итераторах. +* Реализовать методы `hasNext()` и `next()` в классе `company.vk.polis.ads.heap.MergeIterator` так, чтобы успешно выполнялись тесты в `company.vk.polis.ads.heap.MergeIteratorTest`. Время работы должно быть O(n logk), где n - суммарное количество всех элементов в k подаваемых на вход итераторах. -* Реализовать метод `company.vk.polis.ads.TopK#topK`, который должен возвращать список из k максимальных элементов, отсортированных по убыванию, так, чтобы выполнялись тесты в `company.vk.polis.ads.TopKTest`. +* Реализовать метод `company.vk.polis.ads.heap.TopK#topK`, который должен возвращать список из k максимальных элементов, отсортированных по убыванию, так, чтобы выполнялись тесты в `company.vk.polis.ads.heap.TopKTest`. Локально тесты можно запустить с помощью `./gradlew test`. diff --git a/build.gradle.kts b/build.gradle.kts index b96458bd..4ebddb1f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,7 @@ +import org.gradle.api.tasks.testing.logging.TestLogEvent.FAILED +import org.gradle.api.tasks.testing.logging.TestLogEvent.PASSED +import org.gradle.api.tasks.testing.logging.TestLogEvent.SKIPPED + plugins { id("java") } @@ -23,5 +27,9 @@ dependencies { tasks.getByName("test") { useJUnitPlatform() - this.maxHeapSize = "1g" + maxHeapSize = "384m" + + testLogging { + events(PASSED, SKIPPED, FAILED) + } } diff --git a/src/main/java/company/vk/polis/ads/TopK.java b/src/main/java/company/vk/polis/ads/TopK.java deleted file mode 100644 index 3431511e..00000000 --- a/src/main/java/company/vk/polis/ads/TopK.java +++ /dev/null @@ -1,19 +0,0 @@ -package company.vk.polis.ads; - -import java.util.List; - -/** - * Class that allows us to get k max elements ordered descending in source list. - */ -public final class TopK { - /** - * Top-K with O(n logk) complexity. - * @param list input list - * @param k amount of max values to carry out - * @return list with k max elements ordered descending - * @param type of elements - */ - public > List topK(List list, int k) { - throw new UnsupportedOperationException("Implement me"); - } -} diff --git a/src/main/java/company/vk/polis/ads/MergeIterator.java b/src/main/java/company/vk/polis/ads/heap/MergeIterator.java similarity index 84% rename from src/main/java/company/vk/polis/ads/MergeIterator.java rename to src/main/java/company/vk/polis/ads/heap/MergeIterator.java index 03095d83..92f8ebec 100644 --- a/src/main/java/company/vk/polis/ads/MergeIterator.java +++ b/src/main/java/company/vk/polis/ads/heap/MergeIterator.java @@ -1,4 +1,4 @@ -package company.vk.polis.ads; +package company.vk.polis.ads.heap; import java.util.Iterator; import java.util.List; @@ -6,7 +6,7 @@ /** * Iterator that merges k input iterators ordered ascending. * Each value returned by #next() is greater than or equal to previous one. - * Total cost of iteration is O(n logk). + * Total cost of iteration is O(n log(k)). * * @param type of elements */ @@ -28,7 +28,7 @@ public boolean hasNext() { } /** - * Returns next element in ascending order with O(log k) complexity + * Returns next element in ascending order with O(log(k)) complexity * * @return next */ diff --git a/src/main/java/company/vk/polis/ads/heap/TopK.java b/src/main/java/company/vk/polis/ads/heap/TopK.java new file mode 100644 index 00000000..adfbe569 --- /dev/null +++ b/src/main/java/company/vk/polis/ads/heap/TopK.java @@ -0,0 +1,21 @@ +package company.vk.polis.ads.heap; + +import java.util.Iterator; +import java.util.List; + +/** + * Class that allows us to get k max elements ordered descending in source list. + */ +public final class TopK { + /** + * Top-K with O(n log(k)) complexity. + * + * @param elems input elements iterator + * @param k amount of max values to carry out + * @param type of elements + * @return list with k max elements ordered descending + */ + public > List topK(Iterator elems, int k) { + throw new UnsupportedOperationException("Implement me"); + } +} diff --git a/src/test/java/company.vk.polis.ads/TopKTest.java b/src/test/java/company.vk.polis.ads/TopKTest.java deleted file mode 100644 index 558373e2..00000000 --- a/src/test/java/company.vk.polis.ads/TopKTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package company.vk.polis.ads; - -import it.unimi.dsi.fastutil.ints.IntArrayList; -import it.unimi.dsi.fastutil.ints.IntComparators; -import it.unimi.dsi.fastutil.ints.IntList; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import java.util.concurrent.ThreadLocalRandom; -import java.util.stream.IntStream; - -import static org.junit.jupiter.api.Assertions.*; - -@Disabled("Disabled since 4th homework released") -class TopKTest { - private static final int SEQUENCE_SIZE = 100_000_000; - private static final int TOP_K = 1_000_000; - - @Test - void testTopK() { - var input = IntStream.generate(() -> ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE)) - .limit(SEQUENCE_SIZE) - .collect(() -> new IntArrayList(SEQUENCE_SIZE), IntList::add, IntList::addAll); - var expected = dummyTopK(input, TOP_K); - var actual = new TopK().topK(input, TOP_K); - assertEquals(expected, actual); - } - - private static IntList dummyTopK(IntList list, int k) { - list.sort(IntComparators.OPPOSITE_COMPARATOR); - return list.subList(0, k); - } -} diff --git a/src/test/java/company.vk.polis.ads/MergeIteratorTest.java b/src/test/java/company/vk/polis/ads/heap/MergeIteratorTest.java similarity index 94% rename from src/test/java/company.vk.polis.ads/MergeIteratorTest.java rename to src/test/java/company/vk/polis/ads/heap/MergeIteratorTest.java index 3048d1e7..7f5264f4 100644 --- a/src/test/java/company.vk.polis.ads/MergeIteratorTest.java +++ b/src/test/java/company/vk/polis/ads/heap/MergeIteratorTest.java @@ -1,7 +1,6 @@ -package company.vk.polis.ads; +package company.vk.polis.ads.heap; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import java.util.ArrayList; @@ -13,7 +12,6 @@ import static org.junit.jupiter.api.Assertions.*; -@Disabled("Disabled since 4th homework released") class MergeIteratorTest { private static List> iterators; diff --git a/src/test/java/company/vk/polis/ads/heap/TopKTest.java b/src/test/java/company/vk/polis/ads/heap/TopKTest.java new file mode 100644 index 00000000..3b42f039 --- /dev/null +++ b/src/test/java/company/vk/polis/ads/heap/TopKTest.java @@ -0,0 +1,37 @@ +package company.vk.polis.ads.heap; + +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntComparators; +import org.junit.jupiter.api.Test; + +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.IntStream; + +import static org.junit.jupiter.api.Assertions.*; + +class TopKTest { + private static final int SEQUENCE_SIZE = nextInt(150_000_000, 200_000_000); + private static final int TOP_K = nextInt(7_500_000, 10_000_000); + private static final int TOP_K_MIN_VALUE_BOUND = nextInt(Integer.MAX_VALUE / 2 - 1000, Integer.MAX_VALUE / 2); + + @Test + void testTopK() { + var expected = new IntArrayList(TOP_K); + var sequence = IntStream.concat( + IntStream.generate(() -> nextInt(0, TOP_K_MIN_VALUE_BOUND)) + .limit(SEQUENCE_SIZE - TOP_K), + IntStream.generate(() -> { + int i = nextInt(TOP_K_MIN_VALUE_BOUND, Integer.MAX_VALUE); + expected.add(i); + return i; + }).limit(TOP_K) + ).iterator(); + var actual = new TopK().topK(sequence, TOP_K); + expected.sort(IntComparators.OPPOSITE_COMPARATOR); + assertEquals(expected, actual); + } + + private static int nextInt(int from, int to) { + return ThreadLocalRandom.current().nextInt(to - from) + from; + } +}