NX01: Added adult size lehmer codes test case
All checks were successful
Run test asserts / Test-Asserts (push) Successful in 1m2s
All checks were successful
Run test asserts / Test-Asserts (push) Successful in 1m2s
This commit is contained in:
parent
6d3133be55
commit
878bf524da
1 changed files with 128 additions and 18 deletions
|
|
@ -72,17 +72,23 @@ public class NumberMatrixFactoryTest {
|
||||||
// size: 9 result: 362880 (T512) (larger than max of 18 bit nether slug path)
|
// size: 9 result: 362880 (T512) (larger than max of 18 bit nether slug path)
|
||||||
// size: 10 result: 3628800
|
// size: 10 result: 3628800
|
||||||
// size: 11 result: 39916800
|
// size: 11 result: 39916800
|
||||||
// java.lang.OutOfMemoryError: Java heap space
|
// size: 12 result: 479001600
|
||||||
// for (int i = 5; i < 10; i++) {
|
// size: 13 result: 6227020800
|
||||||
// int n = i;
|
// size: 14 result: 87178291200
|
||||||
// int[] initial = new int[n];
|
// size: 15 result: 1307674368000
|
||||||
// for (int ni = 0; ni < n; ni++) {
|
// size: 16 result: 20922789888000
|
||||||
// initial[ni] = ni;
|
// size: 17 result: 355687428096000
|
||||||
// }
|
// size: 18 result: 6402373705728000
|
||||||
// List<int[]> allPermutations = new ArrayList<>();
|
// size: 19 result: 121645100408832000
|
||||||
// generatePermutations(initial, 0, allPermutations);
|
// size: 20 result: 2432902008176640000
|
||||||
// System.out.println("size: " + i + " result: " + allPermutations.size());
|
// size: 21 result: -4249290049419214848 TODO: use BigInteger or limit to 18 bit
|
||||||
// }
|
for (int i = 5; i < 20; i++) {
|
||||||
|
int[] rankFirst = calculateLehmerFromRank(0, i);
|
||||||
|
long amount = calculateTotalPermutations(rankFirst);
|
||||||
|
String IDLE = Arrays.toString(decodeLehmerCode(rankFirst));
|
||||||
|
String IDBE = Arrays.toString(decodeLehmerCode(calculateLehmerFromRank(amount - 1, i)));
|
||||||
|
System.out.println("size: " + i + " result: " + amount + " IDLE: " + IDLE + " IDBE: " + IDBE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: redo matrix with lehmer dial tones from jpp-nether-dial-lehmer
|
// TODO: redo matrix with lehmer dial tones from jpp-nether-dial-lehmer
|
||||||
|
|
@ -260,4 +266,108 @@ public class NumberMatrixFactoryTest {
|
||||||
|
|
||||||
Assertions.assertArrayEquals(originalLehmer, reconstructedLehmer, "The inverse operation should perfectly reconstruct the Lehmer code.");
|
Assertions.assertArrayEquals(originalLehmer, reconstructedLehmer, "The inverse operation should perfectly reconstruct the Lehmer code.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the total number of permutations (n!) for a set of size n. The size n is equivalent to the length of the Lehmer code.
|
||||||
|
*/
|
||||||
|
public long calculateTotalPermutations(int[] lehmerCode) {
|
||||||
|
int n = lehmerCode.length;
|
||||||
|
long factorial = 1;
|
||||||
|
for (int i = 1; i <= n; i++) {
|
||||||
|
factorial *= i;
|
||||||
|
}
|
||||||
|
return factorial;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPermutationCountFromLehmerCode() {
|
||||||
|
// Case 1: Lehmer code for [1, 2, 3] is [0, 0, 0]. Length = 3.
|
||||||
|
// Total permutations = 3! = 6.
|
||||||
|
int[] code1 = { 0, 0, 0 };
|
||||||
|
Assertions.assertEquals(6, calculateTotalPermutations(code1), "3-element set should have 6 permutations");
|
||||||
|
|
||||||
|
// Case 2: Lehmer code for [3, 1, 2] is [2, 0, 0]. Length = 3.
|
||||||
|
// Total permutations = 3! = 6.
|
||||||
|
int[] code2 = { 2, 0, 0 };
|
||||||
|
Assertions.assertEquals(6, calculateTotalPermutations(code2), "Lehmer code [2, 0, 0] represents 6 total permutations");
|
||||||
|
|
||||||
|
// Case 3: Lehmer code for [4, 3, 2, 1] is [3, 2, 1, 0]. Length = 4.
|
||||||
|
// Total permutations = 4! = 24.
|
||||||
|
int[] code3 = { 3, 2, 1, 0 };
|
||||||
|
Assertions.assertEquals(24, calculateTotalPermutations(code3), "4-element set should have 24 permutations");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the lexicographical rank (0-based) from a Lehmer code. Logic: sum(lehmer[i] * (n - 1 - i)!)
|
||||||
|
*/
|
||||||
|
public long calculateRank(int[] lehmerCode) {
|
||||||
|
int n = lehmerCode.length;
|
||||||
|
long rank = 0;
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
rank += (long) lehmerCode[i] * factorial(n - 1 - i);
|
||||||
|
}
|
||||||
|
return rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long factorial(int n) {
|
||||||
|
if (n <= 1) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
long fact = 1;
|
||||||
|
for (int i = 2; i <= n; i++) {
|
||||||
|
fact *= i;
|
||||||
|
}
|
||||||
|
return fact;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRankAndTotalPermutations() {
|
||||||
|
// Example: Permutation {1, 0, 2} has Lehmer code {1, 0, 0}
|
||||||
|
// Rank = 1 * 2! + 0 * 1! + 0 * 0! = 2
|
||||||
|
int[] lehmer1 = { 1, 0, 0 };
|
||||||
|
Assertions.assertEquals(2, calculateRank(lehmer1), "Rank of {1, 0, 0} should be 2");
|
||||||
|
|
||||||
|
// Example: Permutation {2, 1, 0} (Last permutation) has Lehmer code {2, 1, 0}
|
||||||
|
// Rank = 2 * 2! + 1 * 1! + 0 * 0! = 4 + 1 + 0 = 5
|
||||||
|
int[] lehmer2 = { 2, 1, 0 };
|
||||||
|
Assertions.assertEquals(5, calculateRank(lehmer2), "Rank of {2, 1, 0} should be 5");
|
||||||
|
|
||||||
|
// Example: Identity {0, 1, 2, 3} has Lehmer code {0, 0, 0, 0}
|
||||||
|
// Rank = 0
|
||||||
|
int[] lehmer3 = { 0, 0, 0, 0 };
|
||||||
|
Assertions.assertEquals(0, calculateRank(lehmer3), "Identity permutation always has rank 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a lexicographical rank (0-based) into a Lehmer code. Logic: Repeatedly divide rank by (n-1-i)! and keep the quotient as the digit.
|
||||||
|
*/
|
||||||
|
public int[] calculateLehmerFromRank(long rank, int n) {
|
||||||
|
int[] lehmer = new int[n];
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
long fact = factorial(n - 1 - i);
|
||||||
|
lehmer[i] = (int) (rank / fact);
|
||||||
|
rank %= fact;
|
||||||
|
}
|
||||||
|
return lehmer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLehmerFromRank() {
|
||||||
|
// Rank 0 should always return all zeros (Identity)
|
||||||
|
Assertions.assertArrayEquals(new int[] { 0, 0, 0 }, calculateLehmerFromRank(0, 3));
|
||||||
|
|
||||||
|
// For n=3, rank 2:
|
||||||
|
// Digit 1: 2 / 2! = 1 (rem 0)
|
||||||
|
// Digit 2: 0 / 1! = 0 (rem 0)
|
||||||
|
// Digit 3: 0 / 0! = 0
|
||||||
|
// Result: {1, 0, 0}
|
||||||
|
Assertions.assertArrayEquals(new int[] { 1, 0, 0 }, calculateLehmerFromRank(2, 3));
|
||||||
|
|
||||||
|
// For n=3, rank 5 (the very last permutation):
|
||||||
|
// Digit 1: 5 / 2! = 2 (rem 1)
|
||||||
|
// Digit 2: 1 / 1! = 1 (rem 0)
|
||||||
|
// Digit 3: 0 / 0! = 0
|
||||||
|
// Result: {2, 1, 0}
|
||||||
|
Assertions.assertArrayEquals(new int[] { 2, 1, 0 }, calculateLehmerFromRank(5, 3));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue