JPP: Added todo and tests for nether dial tones for lehmer codes
This commit is contained in:
parent
7b5e3e3522
commit
bfc9e511f6
2 changed files with 188 additions and 8 deletions
|
|
@ -39,9 +39,7 @@ import ᒢᐩᐩ.ᔆʸᔆᐪᓫᔿ.ᒃᣔᒃᓫᒻ.ᑊᐣᓑᖮᐪᔆ.DuytsDocAu
|
||||||
public class BabelTest {
|
public class BabelTest {
|
||||||
// ᒢᐩᐩ.ᒡᒢᑊᒻᒻᓫᔿ.xxx
|
// ᒢᐩᐩ.ᒡᒢᑊᒻᒻᓫᔿ.xxx
|
||||||
// ᒢᐩᐩ.ᣕᓫᐪᑋᓫᣗ.ᐪᐤᣕᓫ(8 times 2^6+2^6+2^6+2^9+2^6+2^6+2^6+2^6+2^6+2^6+2^9 = 12800 interface + mutex + etc)
|
// ᒢᐩᐩ.ᣕᓫᐪᑋᓫᣗ.ᐪᐤᣕᓫ(8 times 2^6+2^6+2^6+2^9+2^6+2^6+2^6+2^6+2^6+2^6+2^9 = 12800 interface + mutex + etc)
|
||||||
// ᒢᐩᐩ.ᣕᓫᐪᑋᓫᣗ.ᒼᑋᐤᣗᑊᐣ (SKIP-JAVA4?: REDO 8 times 3 chords of 2^18 tree slug size + file groupings)
|
// ᒢᐩᐩ.ᣕᓫᐪᑋᓫᣗ.ᐪᐤᣕᓫ.ᒼᑋᐤᣗᑊᐣ // implement as group marker interface to readout relative distance to marker root
|
||||||
// = 8*3*(2^18) = 6_291_456 is above default jvm max class limit
|
|
||||||
// implement as group marker interface to readout relative distance to marker root
|
|
||||||
// ᒢᐩᐩ.ᣕᓫᐪᑋᓫᣗ.ᒄᑊᣔᒻ.ᒻᑊᣕᕐᓑᣔ (#interfaces; ~31K + file groupings)
|
// ᒢᐩᐩ.ᣕᓫᐪᑋᓫᣗ.ᒄᑊᣔᒻ.ᒻᑊᣕᕐᓑᣔ (#interfaces; ~31K + file groupings)
|
||||||
// ᒢᐩᐩ.ᣕᓫᐪᑋᓫᣗ.ᒄᑊᣔᒻ.ᒃᣔᔆᓫᒄ (#interfaces; 2304 + 2_655_360 + file groupings)
|
// ᒢᐩᐩ.ᣕᓫᐪᑋᓫᣗ.ᒄᑊᣔᒻ.ᒃᣔᔆᓫᒄ (#interfaces; 2304 + 2_655_360 + file groupings)
|
||||||
// ᒢᐩᐩ.ᑊᑉᒻᣔᔆᔆ.ᒃᐤᣕᓫ.ᣖᑊᣗᣔᐪᓫ.ᒃᐤᣔᐪs
|
// ᒢᐩᐩ.ᑊᑉᒻᣔᔆᔆ.ᒃᐤᣕᓫ.ᣖᑊᣗᣔᐪᓫ.ᒃᐤᣔᐪs
|
||||||
|
|
@ -58,7 +56,7 @@ public class BabelTest {
|
||||||
// - real enum terminator set is from FC18 (FCFlameNumberGram.java)
|
// - real enum terminator set is from FC18 (FCFlameNumberGram.java)
|
||||||
// - bone based terminators up to PIG size 2304 (after 99% of JPP code comes from nether generate on use)
|
// - bone based terminators up to PIG size 2304 (after 99% of JPP code comes from nether generate on use)
|
||||||
// - virtual terminator from nether chord group selector slug path is 2^18 bit pie part values
|
// - virtual terminator from nether chord group selector slug path is 2^18 bit pie part values
|
||||||
// - extended virtual pie slice terminators of nether is thus 8 times 2^18
|
// - extended virtual pie slice terminators of nether is thus 2 times 2^18 (so max gun/etc leaf depth is 6 Q slugs) TODO: zerdinal => upgrade 2 long for 36 bit window size
|
||||||
// ^^ for java3, in java4 100% of runtime+libs is generated per method, so only code which is used.
|
// ^^ for java3, in java4 100% of runtime+libs is generated per method, so only code which is used.
|
||||||
// ᒢᐩᐩ.ᣕᓑᔿᒃᓫᣗ.ᙆᓫᣗᒄᑊᣕᣔᒻ.ᐪᓫᣗᔿᑊᣕᣔᐪᐤᣗ.ᕐᓑᣕᔆ
|
// ᒢᐩᐩ.ᣕᓑᔿᒃᓫᣗ.ᙆᓫᣗᒄᑊᣕᣔᒻ.ᐪᓫᣗᔿᑊᣕᣔᐪᐤᣗ.ᕐᓑᣕᔆ
|
||||||
// ᒢᐩᐩ.ᣕᓑᔿᒃᓫᣗ.ᒻᓫᕐᐤ.ᒢᓫᑊᐣᑊ (+JediTempleBase256InfinityZero redo generics-tree from LegoᐧBrickᐧTapeᐧRecorderᐧχ3 ?)
|
// ᒢᐩᐩ.ᣕᓑᔿᒃᓫᣗ.ᒻᓫᕐᐤ.ᒢᓫᑊᐣᑊ (+JediTempleBase256InfinityZero redo generics-tree from LegoᐧBrickᐧTapeᐧRecorderᐧχ3 ?)
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,12 @@
|
||||||
|
|
||||||
package ᒢᐩᐩ.ᒡᒢᑊᒻᒻᓫᔿ.ᣳᣝᐤᣜᣳ.ᔿᣔᐪᣗᑊᕁ;
|
package ᒢᐩᐩ.ᒡᒢᑊᒻᒻᓫᔿ.ᣳᣝᐤᣜᣳ.ᔿᣔᐪᣗᑊᕁ;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
|
@ -58,4 +64,180 @@ public class NumberMatrixFactoryTest {
|
||||||
Assertions.assertEquals(film.waardes().sizeᴿᵈ(), film.waardes().getᴿᵈ(0).zerdinalSpaceBoundary());
|
Assertions.assertEquals(film.waardes().sizeᴿᵈ(), film.waardes().getᴿᵈ(0).zerdinalSpaceBoundary());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: redo matrix with lehmer dial tones from jpp-nether-dial-lehmer
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the Lehmer code for a given permutation. For each element at index i, count elements to the right (j > i) where permutation[j] <
|
||||||
|
* permutation[i].
|
||||||
|
*/
|
||||||
|
public int[] calculateLehmerCode(int[] permutation) {
|
||||||
|
int n = permutation.length;
|
||||||
|
int[] lehmer = new int[n];
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
int count = 0;
|
||||||
|
for (int j = i + 1; j < n; j++) {
|
||||||
|
if (permutation[j] < permutation[i]) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lehmer[i] = count;
|
||||||
|
}
|
||||||
|
return lehmer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSize3Sequence() {
|
||||||
|
// Expected Lehmer codes for size 3 (Total 3! = 6 permutations)
|
||||||
|
// [0,1,2] -> [0,0,0] (Identity)
|
||||||
|
// [2,1,0] -> [2,1,0] (Reverse)
|
||||||
|
|
||||||
|
Assertions.assertArrayEquals(new int[] { 0, 0, 0 }, calculateLehmerCode(new int[] { 0, 1, 2 }));
|
||||||
|
Assertions.assertArrayEquals(new int[] { 0, 1, 0 }, calculateLehmerCode(new int[] { 0, 2, 1 }));
|
||||||
|
Assertions.assertArrayEquals(new int[] { 1, 0, 0 }, calculateLehmerCode(new int[] { 1, 0, 2 }));
|
||||||
|
Assertions.assertArrayEquals(new int[] { 1, 1, 0 }, calculateLehmerCode(new int[] { 1, 2, 0 }));
|
||||||
|
Assertions.assertArrayEquals(new int[] { 2, 0, 0 }, calculateLehmerCode(new int[] { 2, 0, 1 }));
|
||||||
|
Assertions.assertArrayEquals(new int[] { 2, 1, 0 }, calculateLehmerCode(new int[] { 2, 1, 0 }));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSize4Sequence() {
|
||||||
|
// Testing specific key cases for size 4 (Total 4! = 24 permutations)
|
||||||
|
|
||||||
|
// Example: [0, 1, 2, 3] (Identity)
|
||||||
|
Assertions.assertArrayEquals(new int[] { 0, 0, 0, 0 }, calculateLehmerCode(new int[] { 0, 1, 2, 3 }));
|
||||||
|
|
||||||
|
// Example: [3, 2, 1, 0] (Maximum inversions)
|
||||||
|
Assertions.assertArrayEquals(new int[] { 3, 2, 1, 0 }, calculateLehmerCode(new int[] { 3, 2, 1, 0 }));
|
||||||
|
|
||||||
|
// Example from literature: [1, 3, 0, 2]
|
||||||
|
// 1 > 0 (1 to the right is smaller) -> Lehmer[0] = 1
|
||||||
|
// 3 > 0, 3 > 2 (2 to the right are smaller) -> Lehmer[1] = 2
|
||||||
|
// 0 (none to the right are smaller) -> Lehmer[2] = 0
|
||||||
|
// 2 (none to the right are smaller) -> Lehmer[3] = 0
|
||||||
|
Assertions.assertArrayEquals(new int[] { 1, 2, 0, 0 }, calculateLehmerCode(new int[] { 1, 3, 0, 2 }));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllSize5Permutations() {
|
||||||
|
int n = 5;
|
||||||
|
int[] initial = { 0, 1, 2, 3, 4 };
|
||||||
|
Set<String> uniqueLehmerCodes = new HashSet<>();
|
||||||
|
List<int[]> allPermutations = new ArrayList<>();
|
||||||
|
|
||||||
|
// 1. Generate all 5! = 120 permutations
|
||||||
|
generatePermutations(initial, 0, allPermutations);
|
||||||
|
|
||||||
|
Assertions.assertEquals(120, allPermutations.size(), "Should find exactly 120 permutations for size 5");
|
||||||
|
|
||||||
|
// 2. Calculate and verify Lehmer code for each
|
||||||
|
for (int[] p : allPermutations) {
|
||||||
|
int[] code = calculateLehmerCode(p);
|
||||||
|
|
||||||
|
// Check that each digit is within bounds: code[i] < (n - i)
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
assert (code[i] < (n - i));
|
||||||
|
}
|
||||||
|
|
||||||
|
uniqueLehmerCodes.add(Arrays.toString(code));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Verify that every permutation produced a unique Lehmer code
|
||||||
|
Assertions.assertEquals(120, uniqueLehmerCodes.size(), "Each permutation must have a unique Lehmer code");
|
||||||
|
|
||||||
|
// 4. Check that named math is equal to old math.
|
||||||
|
NumberMatrixSet film = NumberMatrixFactory.INSTANCE.geefFilmSet(5);
|
||||||
|
Assertions.assertEquals(120, film.waardes().sizeᴿᵈ());
|
||||||
|
|
||||||
|
// 4. Check that all permutations are equal
|
||||||
|
Set<String> uniquePermutationCodes = new HashSet<>();
|
||||||
|
for (int[] p : allPermutations) {
|
||||||
|
uniquePermutationCodes.add(Arrays.toString(p));
|
||||||
|
}
|
||||||
|
film.waardes().forEachᴿᵈ(v -> {
|
||||||
|
int[] code = new int[v.rȧñkNummerBlokGroote()];
|
||||||
|
for (int i = 0; i < code.length; i++) {
|
||||||
|
code[i] = v.rȧñkNummerBlokWaarde(code.length - i - 1);
|
||||||
|
}
|
||||||
|
uniquePermutationCodes.remove(Arrays.toString(code));
|
||||||
|
});
|
||||||
|
Assertions.assertEquals(0, uniquePermutationCodes.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generatePermutations(int[] arr, int index, List<int[]> res) {
|
||||||
|
if (index == arr.length) {
|
||||||
|
res.add(arr.clone());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = index; i < arr.length; i++) {
|
||||||
|
swap(arr, index, i);
|
||||||
|
generatePermutations(arr, index + 1, res);
|
||||||
|
swap(arr, index, i); // Backtrack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void swap(int[] arr, int i, int j) {
|
||||||
|
int temp = arr[i];
|
||||||
|
arr[i] = arr[j];
|
||||||
|
arr[j] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Inverse: Converts a Lehmer code back into the original permutation. Logic: The value at lehmer[i] is used as an index into a list of remaining
|
||||||
|
* available numbers.
|
||||||
|
*/
|
||||||
|
public int[] decodeLehmerCode(int[] lehmer) {
|
||||||
|
int n = lehmer.length;
|
||||||
|
int[] permutation = new int[n];
|
||||||
|
|
||||||
|
// Create a list of available numbers {0, 1, 2, ..., n-1}
|
||||||
|
List<Integer> numbers = new ArrayList<>();
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
numbers.add(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For each Lehmer digit, pick the element at that index and remove it
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
int indexInAvailable = lehmer[i];
|
||||||
|
permutation[i] = numbers.remove(indexInAvailable);
|
||||||
|
}
|
||||||
|
|
||||||
|
return permutation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInverseSize3() {
|
||||||
|
// Lehmer [1, 1, 0]
|
||||||
|
// 1. Pick index 1 from {0, 1, 2} -> 1. Remaining {0, 2}
|
||||||
|
// 2. Pick index 1 from {0, 2} -> 2. Remaining {0}
|
||||||
|
// 3. Pick index 0 from {0} -> 0.
|
||||||
|
// Result: [1, 2, 0]
|
||||||
|
Assertions.assertArrayEquals(new int[] { 1, 2, 0 }, decodeLehmerCode(new int[] { 1, 1, 0 }));
|
||||||
|
|
||||||
|
// Lehmer [2, 0, 0] -> [2, 0, 1]
|
||||||
|
Assertions.assertArrayEquals(new int[] { 2, 0, 1 }, decodeLehmerCode(new int[] { 2, 0, 0 }));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInverseSize4() {
|
||||||
|
// Lehmer [1, 2, 0, 0] -> [1, 3, 0, 2]
|
||||||
|
Assertions.assertArrayEquals(new int[] { 1, 3, 0, 2 }, decodeLehmerCode(new int[] { 1, 2, 0, 0 }));
|
||||||
|
|
||||||
|
// Maximum inversion: [3, 2, 1, 0] -> [3, 2, 1, 0]
|
||||||
|
Assertions.assertArrayEquals(new int[] { 3, 2, 1, 0 }, decodeLehmerCode(new int[] { 3, 2, 1, 0 }));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRoundTripSize5() {
|
||||||
|
// Ensure that calculate(decode(x)) returns x for a size 5 permutation
|
||||||
|
int[] originalLehmer = { 4, 0, 2, 1, 0 };
|
||||||
|
|
||||||
|
// 1. Decode to permutation
|
||||||
|
int[] permutation = decodeLehmerCode(originalLehmer);
|
||||||
|
|
||||||
|
// 2. Re-calculate Lehmer from that permutation
|
||||||
|
int[] reconstructedLehmer = calculateLehmerCode(permutation);
|
||||||
|
|
||||||
|
Assertions.assertArrayEquals(originalLehmer, reconstructedLehmer, "The inverse operation should perfectly reconstruct the Lehmer code.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue