Fully implement generatePositionBetween, Add javadoc & source

This commit is contained in:
MrLetsplay 2023-11-22 11:18:31 +01:00
parent 93845890c1
commit da2cd43ebf
Signed by: mr
SSH Key Fingerprint: SHA256:92jBH80vpXyaZHjaIl47pjRq+Yt7XGTArqQg1V7hSqg
3 changed files with 151 additions and 22 deletions

39
pom.xml
View File

@ -9,11 +9,48 @@
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<version>3.11.0</version>
<configuration>
<release>17</release>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.6.2</version>
<configuration>
<source>17</source>
<encoding>UTF-8</encoding>
<sourcepath>src/main/java</sourcepath>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

View File

@ -5,6 +5,8 @@ import java.util.List;
public class Util {
// Source for a lot of the code: https://digitalfreepen.com/2017/10/06/simple-real-time-collaborative-text-editor.html
public static final int BASE = 10;
public static int comparePositions(Identifier[] a, Identifier[] b) {
@ -17,14 +19,17 @@ public class Util {
}
public static Identifier[] generatePositionBetween(Identifier[] before, Identifier[] after, int site) {
if(comparePositions(before, after) != -1) throw new IllegalArgumentException("before must be strictly less than after");
List<Identifier> newPosition = new ArrayList<>();
for(int i = 0; i < Math.min(before.length, after.length) + 1; i++) {
Identifier c1 = i >= before.length ? new Identifier(0, site) : before[i];
Identifier c2 = i >= after.length ? new Identifier(BASE, site) : after[i];
Identifier c2 = i >= after.length ? new Identifier(BASE - 1, site) : after[i];
if(c1.digit() != c2.digit()) {
// TODO: generate delta, then pick a value between
int[] incremented = getIncremented(before, after, i);
return constructPosition(incremented, before, after, site);
}
if(c1.site() == c2.site()) {
@ -34,7 +39,8 @@ public class Util {
if(c1.site() < c2.site()) {
// Anything starting with before will be sorted before after
newPosition.add(new Identifier(BASE, site));
newPosition.add(c1);
newPosition.add(new Identifier(1, site));
return newPosition.toArray(Identifier[]::new);
}
@ -44,9 +50,9 @@ public class Util {
return null;
}
public static int[] getIncremented(Identifier[] i1, Identifier[] i2, int offset) {
public static int[] getIncremented(Identifier[] before, Identifier[] after, int offset) {
// TODO: can potentially be optimized by just calculating the index of the first non-zero digit (e.g. don't return array and discard it -> just return the index)
int[] delta = subtract(i2, i1, offset);
int[] delta = subtract(after, before, offset);
int firstNonZero = 0;
for(int i = 0; i < delta.length; i++) {
if(delta[i] != 0) {
@ -57,16 +63,38 @@ public class Util {
// Because of math, (firstNonZero + 1) >= i1.length (I think)
// then make the array 1 longer so we have space for the increment (which is one order of magnitude smaller)
int[] incremented = new int[firstNonZero + 2];
int[] incremented = new int[offset + firstNonZero + 2];
for(int i = 0; i < incremented.length; i++) {
incremented[i] = i <= i1.length ? i1[i].digit() : 0;
incremented[i] = i < before.length ? before[i].digit() : 0;
}
add1AtIndex(incremented, firstNonZero + 1); // last digit might be zero, which is ambigious, inc again
if(incremented[incremented.length - 1] == 0) add1AtIndex(incremented, firstNonZero + 1);
add1AtIndex(incremented, offset + firstNonZero + 1); // last digit might be zero, which is ambigious, inc again
if(incremented[incremented.length - 1] == 0) add1AtIndex(incremented, offset + firstNonZero + 1);
return incremented;
}
public static Identifier[] constructPosition(int[] num, Identifier[] before, Identifier[] after, int site) {
// Implements rules according to constructPosition from https://inria.hal.science/inria-00432368/document
Identifier[] ident = new Identifier[num.length];
for(int i = 0; i < num.length; i++) {
int digit = num[i];
if(i == num.length - 1) {
ident[i] = new Identifier(digit, site);
}else if(i < before.length && digit == before[i].digit()) {
ident[i] = before[i];
}else if(i < after.length && digit == after[i].digit()) {
ident[i] = after[i];
}else {
ident[i] = new Identifier(digit, site);
}
}
return ident;
}
/**
* Subtract b from a, where a > b
*/

View File

@ -12,58 +12,122 @@ public class DecimalTest {
@Test
public void testSimpleSubtraction() {
Identifier[] a = new Identifier[] { new Identifier(1, 0), new Identifier(2, 0), new Identifier(3, 0) };
Identifier[] b = new Identifier[] { new Identifier(1, 0), new Identifier(1, 0), new Identifier(3, 0) };
Identifier[] a = { new Identifier(1, 0), new Identifier(2, 0), new Identifier(3, 0) };
Identifier[] b = { new Identifier(1, 0), new Identifier(1, 0), new Identifier(3, 0) };
assertArrayEquals(new int[] { 0, 1, 0 }, Util.subtract(a, b, 0));
}
@Test
public void testCarrySubtraction() {
Identifier[] a = new Identifier[] { new Identifier(2, 0), new Identifier(0, 0), new Identifier(4, 0) };
Identifier[] b = new Identifier[] { new Identifier(1, 0), new Identifier(0, 0), new Identifier(5, 0) };
Identifier[] a = { new Identifier(2, 0), new Identifier(0, 0), new Identifier(4, 0) };
Identifier[] b = { new Identifier(1, 0), new Identifier(0, 0), new Identifier(5, 0) };
assertArrayEquals(new int[] { 0, Util.BASE - 1, Util.BASE - 1 }, Util.subtract(a, b, 0));
}
@Test
public void testOffsetSubtraction() {
Identifier[] a = new Identifier[] { new Identifier(1, 0), new Identifier(0, 0), new Identifier(5, 0) };
Identifier[] b = new Identifier[] { new Identifier(1, 0), new Identifier(0, 0), new Identifier(4, 0) };
Identifier[] a = { new Identifier(1, 0), new Identifier(0, 0), new Identifier(5, 0) };
Identifier[] b = { new Identifier(1, 0), new Identifier(0, 0), new Identifier(4, 0) };
assertArrayEquals(new int[] { 0, 1 }, Util.subtract(a, b, 1));
}
@Test
public void testReversedInputFails() {
Identifier[] a = new Identifier[] { new Identifier(1, 0), new Identifier(1, 0), new Identifier(3, 0) };
Identifier[] b = new Identifier[] { new Identifier(1, 0), new Identifier(2, 0), new Identifier(3, 0) };
Identifier[] a = { new Identifier(1, 0), new Identifier(1, 0), new Identifier(3, 0) };
Identifier[] b = { new Identifier(1, 0), new Identifier(2, 0), new Identifier(3, 0) };
assertThrows(RuntimeException.class, () -> Util.subtract(a, b, 0));
}
@Test
public void testSimpleAdd1() {
int[] a = new int[] { 0, 0 };
int[] a = { 0, 0 };
Util.add1AtIndex(a, 1);
assertArrayEquals(new int[] { 0, 1 }, a);
}
@Test
public void testCarryAdd1() {
int[] a = new int[] { 0, Util.BASE - 1 };
int[] a = { 0, Util.BASE - 1 };
Util.add1AtIndex(a, 1);
assertArrayEquals(new int[] { 1, 0 }, a);
}
@Test
public void testCarryAdd1_2() {
int[] a = new int[] { 0, Util.BASE - 1, Util.BASE - 1 };
int[] a = { 0, Util.BASE - 1, Util.BASE - 1 };
Util.add1AtIndex(a, 2);
assertArrayEquals(new int[] { 1, 0, 0 }, a);
}
@Test
public void testCarryAdd1_3() {
int[] a = new int[] { 0, Util.BASE - 1, Util.BASE - 1 };
int[] a = { 0, Util.BASE - 1, Util.BASE - 1 };
Util.add1AtIndex(a, 1);
assertArrayEquals(new int[] { 1, 0, Util.BASE - 1 }, a);
}
@Test
public void testIncrement_1() {
Identifier[] a = { new Identifier(1, 0), new Identifier(2, 0) };
Identifier[] b = { new Identifier(1, 0), new Identifier(3, 0) };
assertArrayEquals(new int[] { 1, 2, 1 }, Util.getIncremented(a, b, 1));
}
@Test
public void testIncrement_2() {
Identifier[] a = { new Identifier(1, 0), new Identifier(2, 0) };
Identifier[] b = { new Identifier(1, 0), new Identifier(2, 0), new Identifier(Util.BASE - 1, 0) };
assertArrayEquals(new int[] { 1, 2, 0, 1 }, Util.getIncremented(a, b, 1));
}
@Test
public void testCarryIncrement() {
Identifier[] a = { new Identifier(1, 0), new Identifier(2, 0), new Identifier(Util.BASE - 1, 0) };
Identifier[] b = { new Identifier(1, 0), new Identifier(4, 0) };
assertArrayEquals(new int[] { 1, 3, 1 }, Util.getIncremented(a, b, 1));
}
@Test
public void testConstructPosition_1() {
Identifier[] a = { new Identifier(1, 0), new Identifier(2, 0), new Identifier(Util.BASE - 1, 0) };
Identifier[] b = { new Identifier(1, 0), new Identifier(4, 0) };
int[] newIdent = Util.getIncremented(a, b, 1);
Identifier[] expected = { new Identifier(1, 0), new Identifier(3, 1), new Identifier(1, 1) };
assertArrayEquals(expected, Util.constructPosition(newIdent, a, b, 1));
}
@Test
public void testConstructPosition_2() {
Identifier[] a = { new Identifier(1, 0), new Identifier(2, 2), new Identifier(2, 2) };
Identifier[] b = { new Identifier(1, 0), new Identifier(4, 1), new Identifier(3, 1) };
int[] newIdent = Util.getIncremented(a, b, 1);
Identifier[] expected = { new Identifier(1, 0), new Identifier(2, 2), new Identifier(3, 3) };
assertArrayEquals(expected, Util.constructPosition(newIdent, a, b, 3));
}
@Test
public void testGeneratePosition_1() {
Identifier[] a = { new Identifier(1, 0), new Identifier(2, 1) };
Identifier[] b = { new Identifier(1, 0), new Identifier(3, 2) };
Identifier[] newIdent = Util.generatePositionBetween(a, b, 3);
Identifier[] expected = { new Identifier(1, 0), new Identifier(2, 1), new Identifier(1, 3) };
assertArrayEquals(expected, newIdent);
}
@Test
public void testGeneratePosition_2() {
Identifier[] a = { new Identifier(1, 0), new Identifier(2, 1) };
Identifier[] b = { new Identifier(1, 0), new Identifier(2, 2) };
Identifier[] newIdent = Util.generatePositionBetween(a, b, 3);
Identifier[] expected = { new Identifier(1, 0), new Identifier(2, 1), new Identifier(1, 3) };
assertArrayEquals(expected, newIdent);
}
@Test
public void testGeneratePositionInvalidInputFails() {
Identifier[] a = { new Identifier(1, 0), new Identifier(2, 2) };
Identifier[] b = { new Identifier(1, 0), new Identifier(2, 1) };
assertThrows(IllegalArgumentException.class, () -> Util.generatePositionBetween(a, b, 3));
}
}