Fully implement generatePositionBetween, Add javadoc & source
This commit is contained in:
parent
93845890c1
commit
da2cd43ebf
39
pom.xml
39
pom.xml
@ -9,11 +9,48 @@
|
|||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.8.1</version>
|
<version>3.11.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<release>17</release>
|
<release>17</release>
|
||||||
|
<encoding>UTF-8</encoding>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</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>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@ import java.util.List;
|
|||||||
|
|
||||||
public class Util {
|
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 final int BASE = 10;
|
||||||
|
|
||||||
public static int comparePositions(Identifier[] a, Identifier[] b) {
|
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) {
|
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<>();
|
List<Identifier> newPosition = new ArrayList<>();
|
||||||
|
|
||||||
for(int i = 0; i < Math.min(before.length, after.length) + 1; i++) {
|
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 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()) {
|
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()) {
|
if(c1.site() == c2.site()) {
|
||||||
@ -34,7 +39,8 @@ public class Util {
|
|||||||
|
|
||||||
if(c1.site() < c2.site()) {
|
if(c1.site() < c2.site()) {
|
||||||
// Anything starting with before will be sorted before after
|
// 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);
|
return newPosition.toArray(Identifier[]::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,9 +50,9 @@ public class Util {
|
|||||||
return null;
|
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)
|
// 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;
|
int firstNonZero = 0;
|
||||||
for(int i = 0; i < delta.length; i++) {
|
for(int i = 0; i < delta.length; i++) {
|
||||||
if(delta[i] != 0) {
|
if(delta[i] != 0) {
|
||||||
@ -57,16 +63,38 @@ public class Util {
|
|||||||
|
|
||||||
// Because of math, (firstNonZero + 1) >= i1.length (I think)
|
// 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)
|
// 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++) {
|
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
|
add1AtIndex(incremented, offset + firstNonZero + 1); // last digit might be zero, which is ambigious, inc again
|
||||||
if(incremented[incremented.length - 1] == 0) add1AtIndex(incremented, firstNonZero + 1);
|
if(incremented[incremented.length - 1] == 0) add1AtIndex(incremented, offset + firstNonZero + 1);
|
||||||
return incremented;
|
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
|
* Subtract b from a, where a > b
|
||||||
*/
|
*/
|
||||||
|
@ -12,58 +12,122 @@ public class DecimalTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSimpleSubtraction() {
|
public void testSimpleSubtraction() {
|
||||||
Identifier[] a = new Identifier[] { new Identifier(1, 0), new Identifier(2, 0), new Identifier(3, 0) };
|
Identifier[] a = { 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[] b = { new Identifier(1, 0), new Identifier(1, 0), new Identifier(3, 0) };
|
||||||
assertArrayEquals(new int[] { 0, 1, 0 }, Util.subtract(a, b, 0));
|
assertArrayEquals(new int[] { 0, 1, 0 }, Util.subtract(a, b, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCarrySubtraction() {
|
public void testCarrySubtraction() {
|
||||||
Identifier[] a = new Identifier[] { new Identifier(2, 0), new Identifier(0, 0), new Identifier(4, 0) };
|
Identifier[] a = { 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[] 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));
|
assertArrayEquals(new int[] { 0, Util.BASE - 1, Util.BASE - 1 }, Util.subtract(a, b, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOffsetSubtraction() {
|
public void testOffsetSubtraction() {
|
||||||
Identifier[] a = new Identifier[] { new Identifier(1, 0), new Identifier(0, 0), new Identifier(5, 0) };
|
Identifier[] a = { 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[] b = { new Identifier(1, 0), new Identifier(0, 0), new Identifier(4, 0) };
|
||||||
assertArrayEquals(new int[] { 0, 1 }, Util.subtract(a, b, 1));
|
assertArrayEquals(new int[] { 0, 1 }, Util.subtract(a, b, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReversedInputFails() {
|
public void testReversedInputFails() {
|
||||||
Identifier[] a = new Identifier[] { new Identifier(1, 0), new Identifier(1, 0), new Identifier(3, 0) };
|
Identifier[] a = { 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[] b = { new Identifier(1, 0), new Identifier(2, 0), new Identifier(3, 0) };
|
||||||
assertThrows(RuntimeException.class, () -> Util.subtract(a, b, 0));
|
assertThrows(RuntimeException.class, () -> Util.subtract(a, b, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSimpleAdd1() {
|
public void testSimpleAdd1() {
|
||||||
int[] a = new int[] { 0, 0 };
|
int[] a = { 0, 0 };
|
||||||
Util.add1AtIndex(a, 1);
|
Util.add1AtIndex(a, 1);
|
||||||
assertArrayEquals(new int[] { 0, 1 }, a);
|
assertArrayEquals(new int[] { 0, 1 }, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCarryAdd1() {
|
public void testCarryAdd1() {
|
||||||
int[] a = new int[] { 0, Util.BASE - 1 };
|
int[] a = { 0, Util.BASE - 1 };
|
||||||
Util.add1AtIndex(a, 1);
|
Util.add1AtIndex(a, 1);
|
||||||
assertArrayEquals(new int[] { 1, 0 }, a);
|
assertArrayEquals(new int[] { 1, 0 }, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCarryAdd1_2() {
|
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);
|
Util.add1AtIndex(a, 2);
|
||||||
assertArrayEquals(new int[] { 1, 0, 0 }, a);
|
assertArrayEquals(new int[] { 1, 0, 0 }, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCarryAdd1_3() {
|
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);
|
Util.add1AtIndex(a, 1);
|
||||||
assertArrayEquals(new int[] { 1, 0, Util.BASE - 1 }, a);
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user