diff --git a/src/aud/exam/prep/array/FullyUsedArrayProcessor.java b/src/aud/exam/prep/array/FullyUsedArrayProcessor.java index 06de614..446abba 100644 --- a/src/aud/exam/prep/array/FullyUsedArrayProcessor.java +++ b/src/aud/exam/prep/array/FullyUsedArrayProcessor.java @@ -437,7 +437,43 @@ public class FullyUsedArrayProcessor implements SequenceProcessor, FullyUsedArray> divideAlternatingByRuns(FullyUsedArray array, Comparator cmp) { - throw new UnsupportedOperationException(); + var p = new Pair, FullyUsedArray>(); + p.fst = new FullyUsedArray<>(); + p.snd = new FullyUsedArray<>(); + + var runInFst = true; + var elementsInFst = 0; + + for (int i = 0; i < array.theArray.length; i++) { + if (runInFst) { + elementsInFst++; + } + + if (i < array.theArray.length-1 && cmp.compare(array.theArray[i], array.theArray[i + 1]) > 0) { + runInFst = !runInFst; + } + } + + p.fst.theArray = Arrays.newArray(elementsInFst); + p.snd.theArray = Arrays.newArray(array.theArray.length - elementsInFst); + + runInFst = true; + var indexA = 0; + var indexB = 0; + + for (int i = 0; i < array.theArray.length; i++) { + if (runInFst) { + p.fst.theArray[indexA++] = array.theArray[i]; + } else { + p.snd.theArray[indexB++] = array.theArray[i]; + } + + if (i < array.theArray.length-1 && cmp.compare(array.theArray[i], array.theArray[i + 1]) > 0) { + runInFst = !runInFst; + } + } + + return p; } @Override diff --git a/test/aud/exam/prep/ListOfRunsProvider.java b/test/aud/exam/prep/ListOfRunsProvider.java new file mode 100644 index 0000000..39b266e --- /dev/null +++ b/test/aud/exam/prep/ListOfRunsProvider.java @@ -0,0 +1,46 @@ +package aud.exam.prep; + +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.ArgumentsProvider; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +public class ListOfRunsProvider implements ArgumentsProvider { + + @Override + public Stream provideArguments(ExtensionContext extensionContext) { + return Stream + .generate(this::listOfRuns) + .map(Arguments::of) + .limit(Tests.STEAM_SIZE); + } + + private List> listOfRuns() { + var runs = Tests.RANDOM.nextInt(20); + return Stream + .generate(this::run) + .limit(runs) + .collect(Collectors.toList()); + } + + private List run() { + var size = Tests.RANDOM.nextInt(50); + var run = IntStream + .range(0, size) + .boxed() + .flatMap(i -> { + var n = Tests.RANDOM.nextInt(5); + return Collections.nCopies(n, i).stream(); + }) + .collect(Collectors.toList()); + + run.add(0, -1); + run.add(999); + return run; + } +} diff --git a/test/aud/exam/prep/SequenceProcessorTest.java b/test/aud/exam/prep/SequenceProcessorTest.java index 10a6248..d5a132e 100644 --- a/test/aud/exam/prep/SequenceProcessorTest.java +++ b/test/aud/exam/prep/SequenceProcessorTest.java @@ -506,8 +506,8 @@ public abstract class SequenceProcessorTest { @ArgumentsSource(ListProvider.class) void testThat_divideAlternatingWorks(List list) { S s = processor.create(list); - var div = List.of(new ArrayList(), new ArrayList()); + var div = List.of(new ArrayList(), new ArrayList()); for (int i = 0; i < list.size(); i++) { div.get(i % 2).add(list.get(i)); } @@ -521,6 +521,29 @@ public abstract class SequenceProcessorTest { assertIterableEquals(div.get(1), processor.iterate(p.snd)); } + @ParameterizedTest + @ArgumentsSource(ListOfRunsProvider.class) + void testThat_divideAlternatingByRunsWorks(List> runs) { + var list = runs + .stream() + .flatMap(List::stream) + .collect(Collectors.toList()); + S s = processor.create(list); + + var div = List.of(new ArrayList(), new ArrayList()); + for (int i = 0; i < runs.size(); i++) { + div.get(i % 2).addAll(runs.get(i)); + } + + var p = processor.divideAlternatingByRuns(s, cmp); + + assertTrue(processor.check(p.fst)); + assertIterableEquals(div.get(0), processor.iterate(p.fst)); + + assertTrue(processor.check(p.snd)); + assertIterableEquals(div.get(1), processor.iterate(p.snd)); + } + @ParameterizedTest @ArgumentsSource(ListProvider.class) void testThat_divideByPivotWorks(List list) {