package aud.exam.prep.array; import aud.exam.prep.Pair; import aud.exam.prep.SequenceProcessor; import java.util.Comparator; import java.util.Iterator; import java.util.Objects; @SuppressWarnings("ManualArrayCopy") public class FullyUsedArrayProcessor implements SequenceProcessor> { @Override public boolean find(FullyUsedArray array, T t) { for (int i = 0; i < array.theArray.length; i++) { if (Objects.equals(array.theArray[i], t)) { return true; } } return false; } @Override public boolean findBinary(FullyUsedArray array, T t, Comparator cmp) { if (array.theArray.length == 0) { return false; } var low = 0; var high = array.theArray.length-1; while (low <= high) { var index = (low + high) / 2; var c = cmp.compare(t, array.theArray[index]); if (c == 0) { return true; } else if (c < 0) { high = index-1; } else { low = index+1; } } return false; } @Override public boolean override(FullyUsedArray array, T from, T to) { for (int i = 0; i < array.theArray.length; i++) { if (Objects.equals(array.theArray[i], from)) { array.theArray[i] = to; return true; } } return false; } @Override public boolean overrideAll(FullyUsedArray array, T from, T to) { var modified = false; for (int i = 0; i < array.theArray.length; i++) { if (Objects.equals(array.theArray[i], from)) { array.theArray[i] = to; modified = true; } } return modified; } @Override public boolean overrideAt(FullyUsedArray array, T to, int index) { if (index < 0 || index >= array.theArray.length) { return false; } array.theArray[index] = to; return true; } @Override public void insertInOrder(FullyUsedArray array, T t, Comparator cmp) { T[] newArray = Arrays.newArray(array.theArray.length+1); var index = 0; while (index < array.theArray.length && cmp.compare(array.theArray[index], t) < 0) { newArray[index] = array.theArray[index]; index++; } newArray[index] = t; while (index < array.theArray.length) { newArray[index+1] = array.theArray[index]; index++; } array.theArray = newArray; } @Override public boolean remove(FullyUsedArray array, T t) { if (!find(array, t)) { return false; } T[] newArray = Arrays.newArray(array.theArray.length-1); var index = 0; while (!Objects.equals(array.theArray[index], t)) { newArray[index] = array.theArray[index]; index++; } index++; while (index < array.theArray.length) { newArray[index-1] = array.theArray[index]; index++; } array.theArray = newArray; return true; } @Override public boolean removeAll(FullyUsedArray array, T t) { int size = 0; for (int i = 0; i < array.theArray.length; i++) { if (!Objects.equals(array.theArray[i], t)) { size++; } } if (size == array.theArray.length) { return false; } T[] newArray = Arrays.newArray(size); int index = 0; for (int i = 0; i < array.theArray.length; i++) { if (!Objects.equals(array.theArray[i], t)) { newArray[index++] = array.theArray[i]; } } array.theArray = newArray; return true; } @Override public boolean isAscending(FullyUsedArray array, Comparator cmp) { for (int i = 0; i < array.theArray.length-1; i++) { if (cmp.compare(array.theArray[i], array.theArray[i+1]) > 0) { return false; } } return true; } @Override public T max(FullyUsedArray array, Comparator cmp) { if (array.theArray.length == 0) { throw new IllegalArgumentException("The sequence may not be empty"); } var max = array.theArray[0]; for (int i = 1; i < array.theArray.length; i++) { if (cmp.compare(max, array.theArray[i]) < 0) { max = array.theArray[i]; } } return max; } @Override public T secondMax(FullyUsedArray array, Comparator cmp) { if (array.theArray.length < 2) { throw new IllegalArgumentException("The sequence must contains at least 2 elements"); } T secondMax, max; if (cmp.compare(array.theArray[0], array.theArray[1]) < 0) { secondMax = array.theArray[0]; max = array.theArray[1]; } else { secondMax = array.theArray[1]; max = array.theArray[0]; } for (int i = 2; i < array.theArray.length; i++) { if (cmp.compare(max, array.theArray[i]) < 0) { secondMax = max; max = array.theArray[i]; } else if (cmp.compare(secondMax, array.theArray[i]) < 0) { secondMax = array.theArray[i]; } } return secondMax; } @Override public boolean check(FullyUsedArray array) { return true; } @Override public boolean isItemWiseLessOrEqual(FullyUsedArray a, FullyUsedArray b, Comparator cmp) { if (b.theArray.length < a.theArray.length) { return false; } for (int i = 0; i < a.theArray.length; i++) { if (cmp.compare(a.theArray[i], b.theArray[i]) > 0) { return false; } } return true; } @Override public boolean isItemWiseLess(FullyUsedArray a, FullyUsedArray b, Comparator cmp) { if (b.theArray.length < a.theArray.length) { return false; } var actualLessElement = false; for (int i = 0; i < a.theArray.length; i++) { var c = cmp.compare(a.theArray[i], b.theArray[i]); if (c > 0) { return false; } else if (c < 0) { actualLessElement = true; } } return a.theArray.length < b.theArray.length || actualLessElement; } @Override public boolean isLexSmaller(FullyUsedArray a, FullyUsedArray b, Comparator cmp) { var end = Integer.min(a.theArray.length, b.theArray.length); for (int i = 0; i < end; i++) { var c = cmp.compare(a.theArray[i], b.theArray[i]); if (c < 0) { return true; } if (c > 0) { return false; } } return a.theArray.length < b.theArray.length; } @Override public void exchangePairs(FullyUsedArray array) { } @Override public void rotateTriples(FullyUsedArray array) { } @Override public void removeEverySecond(FullyUsedArray array) { throw new UnsupportedOperationException(); } @Override public void doubleAllKeys(FullyUsedArray array) { T[] newArray = Arrays.newArray(array.theArray.length*2); for (int i = 0; i < array.theArray.length; i++) { newArray[2*i] = newArray[2*i + 1] = array.theArray[i]; } array.theArray = newArray; } @Override public FullyUsedArray rotateRight(FullyUsedArray array) { if (array.theArray.length < 2) { return array; } var right = array.theArray[array.theArray.length-1]; for (int i = array.theArray.length-2; i >= 0; i--) { array.theArray[i+1] = array.theArray[i]; } array.theArray[0] = right; return array; } @Override public FullyUsedArray rotateLeft(FullyUsedArray array) { if (array.theArray.length < 2) { return array; } var left = array.theArray[0]; for (int i = 0; i < array.theArray.length-1; i++) { array.theArray[i] = array.theArray[i+1]; } array.theArray[array.theArray.length-1] = left; return array; } @Override public void removeDuplicates(FullyUsedArray array) { if (array.theArray.length < 2) { return; } var distinctRuns = 1; for (int i = 0; i < array.theArray.length-1; i++) { if (array.theArray[i] != array.theArray[i+1]) { distinctRuns++; } } if (distinctRuns == array.theArray.length) { return; } T[] newArray = Arrays.newArray(distinctRuns); var index = 0; for (int i = 0; i < array.theArray.length; i++) { if (index == 0 || !Objects.equals(newArray[index-1], array.theArray[i])) { newArray[index++] = array.theArray[i]; } } array.theArray = newArray; } @Override public FullyUsedArray invert(FullyUsedArray array) { for (int i = 0; i < array.theArray.length/2; i++) { T t = array.theArray[i]; array.theArray[i] = array.theArray[array.theArray.length-i-1]; array.theArray[array.theArray.length-i-1] = t; } return array; } @Override public FullyUsedArray clone(FullyUsedArray array) { var newArray = new FullyUsedArray(); newArray.theArray = Arrays.newArray(array.theArray.length); for (int i = 0; i < array.theArray.length; i++) { newArray.theArray[i] = array.theArray[i]; } return newArray; } @Override public FullyUsedArray alternate(FullyUsedArray a, FullyUsedArray b) { var newArray = new FullyUsedArray(); newArray.theArray = Arrays.newArray(a.theArray.length + b.theArray.length); var index = 0; var indexA = 0; var indexB = 0; while (indexA < a.theArray.length || indexB < b.theArray.length) { if (indexA < a.theArray.length) { newArray.theArray[index++] = a.theArray[indexA++]; } if (indexB < b.theArray.length) { newArray.theArray[index++] = b.theArray[indexB++]; } } return newArray; } @Override public FullyUsedArray merge(FullyUsedArray a, FullyUsedArray b, Comparator cmp) { throw new UnsupportedOperationException(); } @Override public Pair, FullyUsedArray> divideAlternating(FullyUsedArray array) { throw new UnsupportedOperationException(); } @Override public Pair, FullyUsedArray> divideAlternatingByRuns(FullyUsedArray array, Comparator cmp) { throw new UnsupportedOperationException(); } @Override public Pair, FullyUsedArray> divideByPivot(FullyUsedArray array, T pivot, Comparator cmp) { throw new UnsupportedOperationException(); } @Override public FullyUsedArray create(Iterable iterable) { var array = new FullyUsedArray(); var size = 0; for (T ignored : iterable) { size++; } array.theArray = Arrays.newArray(size); var index = 0; for (T t : iterable) { array.theArray[index] = t; index++; } return array; } @Override public Iterable iterate(FullyUsedArray array) { return () -> new Iterator<>() { private int index = 0; @Override public boolean hasNext() { return index < array.theArray.length; } @Override public T next() { return array.theArray[index++]; } }; } }