diff --git a/dotnet/WhiteRabbit/PhraseSet.cs b/dotnet/WhiteRabbit/PhraseSet.cs index 667bfcf..642f68e 100644 --- a/dotnet/WhiteRabbit/PhraseSet.cs +++ b/dotnet/WhiteRabbit/PhraseSet.cs @@ -7,7 +7,7 @@ { public fixed long Buffer[4 * Constants.PhrasesPerSet]; - public PhraseSet(Word[] words, int[][] permutations, int offset, int numberOfCharacters) + public PhraseSet(Word[] words, long[] permutations, int offset, int numberOfCharacters) { Debug.Assert(numberOfCharacters + words.Length - 1 < 27); @@ -21,7 +21,8 @@ var cumulativeWordOffsetX4 = 0; for (var j = 0; j < numberOfWords; j++) { - var currentWord = words[permutation[j]]; + var currentWord = words[permutation & 15]; + permutation = permutation >> 4; longBuffer[0] |= currentWord.Buffers[cumulativeWordOffsetX4 + 0]; longBuffer[1] |= currentWord.Buffers[cumulativeWordOffsetX4 + 1]; longBuffer[2] ^= currentWord.Buffers[cumulativeWordOffsetX4 + 2]; diff --git a/dotnet/WhiteRabbit/PrecomputedPermutationsGenerator.cs b/dotnet/WhiteRabbit/PrecomputedPermutationsGenerator.cs index b2c9f66..669c732 100644 --- a/dotnet/WhiteRabbit/PrecomputedPermutationsGenerator.cs +++ b/dotnet/WhiteRabbit/PrecomputedPermutationsGenerator.cs @@ -5,25 +5,44 @@ internal static class PrecomputedPermutationsGenerator { - private static int[][][] Permutations { get; } = Enumerable.Range(0, 9).Select(GeneratePermutations).ToArray(); + private static long[][] Permutations { get; } = Enumerable.Range(0, 9).Select(GeneratePermutations).ToArray(); private static long[] PermutationsNumbers { get; } = GeneratePermutationsNumbers().Take(19).ToArray(); - public static int[][] HamiltonianPermutations(int n) => Permutations[n]; + public static long[] HamiltonianPermutations(int n) => Permutations[n]; public static long GetPermutationsNumber(int n) => PermutationsNumbers[n]; - private static int[][] GeneratePermutations(int n) + private static long[] GeneratePermutations(int n) { var result = PermutationsGenerator.HamiltonianPermutations(n) - .Select(permutation => permutation.PermutationData) + .Select(FormatPermutation) .ToArray(); - if (result.Length % Constants.PhrasesPerSet == 0) + + return PadToWholeChunks(result, Constants.PhrasesPerSet); + } + + private static T[] PadToWholeChunks(T[] original, int chunkSize) + { + if (original.Length % chunkSize == 0) + { + return original; + } + + return original.Concat(Enumerable.Repeat(original[0], chunkSize - (original.Length % chunkSize))).ToArray(); + } + + private static long FormatPermutation(PermutationsGenerator.Permutation permutation) + { + System.Diagnostics.Debug.Assert(permutation.PermutationData.Length <= 16); + + long result = 0; + for (var i = 0; i < permutation.PermutationData.Length; i++) { - return result; + result |= (long)(permutation.PermutationData[i]) << (4 * i); } - return result.Concat(Enumerable.Repeat(result[0], Constants.PhrasesPerSet - (result.Length % Constants.PhrasesPerSet))).ToArray(); + return result; } private static IEnumerable GeneratePermutationsNumbers()