Implement MappedShuffle for tracking the permutation of an array
This commit is contained in:
@@ -17,6 +17,7 @@ zcash_gtest_SOURCES = \
|
|||||||
gtest/test_noteencryption.cpp \
|
gtest/test_noteencryption.cpp \
|
||||||
gtest/test_merkletree.cpp \
|
gtest/test_merkletree.cpp \
|
||||||
gtest/test_pow.cpp \
|
gtest/test_pow.cpp \
|
||||||
|
gtest/test_random.cpp \
|
||||||
gtest/test_rpc.cpp \
|
gtest/test_rpc.cpp \
|
||||||
gtest/test_circuit.cpp \
|
gtest/test_circuit.cpp \
|
||||||
gtest/test_txid.cpp \
|
gtest/test_txid.cpp \
|
||||||
|
|||||||
34
src/gtest/test_random.cpp
Normal file
34
src/gtest/test_random.cpp
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "random.h"
|
||||||
|
|
||||||
|
int GenZero(int n)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GenMax(int n)
|
||||||
|
{
|
||||||
|
return n-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Random, MappedShuffle) {
|
||||||
|
std::vector<int> a {8, 4, 6, 3, 5};
|
||||||
|
std::vector<int> m {0, 1, 2, 3, 4};
|
||||||
|
|
||||||
|
auto a1 = a;
|
||||||
|
auto m1 = m;
|
||||||
|
MappedShuffle(a1.begin(), m1.begin(), a1.size(), GenZero);
|
||||||
|
std::vector<int> ea1 {4, 6, 3, 5, 8};
|
||||||
|
std::vector<int> em1 {1, 2, 3, 4, 0};
|
||||||
|
EXPECT_EQ(ea1, a1);
|
||||||
|
EXPECT_EQ(em1, m1);
|
||||||
|
|
||||||
|
auto a2 = a;
|
||||||
|
auto m2 = m;
|
||||||
|
MappedShuffle(a2.begin(), m2.begin(), a2.size(), GenMax);
|
||||||
|
std::vector<int> ea2 {8, 4, 6, 3, 5};
|
||||||
|
std::vector<int> em2 {0, 1, 2, 3, 4};
|
||||||
|
EXPECT_EQ(ea2, a2);
|
||||||
|
EXPECT_EQ(em2, m2);
|
||||||
|
}
|
||||||
24
src/random.h
24
src/random.h
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,6 +25,29 @@ uint64_t GetRand(uint64_t nMax);
|
|||||||
int GetRandInt(int nMax);
|
int GetRandInt(int nMax);
|
||||||
uint256 GetRandHash();
|
uint256 GetRandHash();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rearranges the elements in the range [first,first+len) randomly, assuming
|
||||||
|
* that gen is a uniform random number generator. Follows the same algorithm as
|
||||||
|
* std::shuffle in C++11 (a Durstenfeld shuffle).
|
||||||
|
*
|
||||||
|
* The elements in the range [mapFirst,mapFirst+len) are rearranged according to
|
||||||
|
* the same permutation, enabling the permutation to be tracked by the caller.
|
||||||
|
*
|
||||||
|
* gen takes an integer n and produces a uniform random output in [0,n).
|
||||||
|
*/
|
||||||
|
template <typename RandomAccessIterator, typename MapRandomAccessIterator>
|
||||||
|
void MappedShuffle(RandomAccessIterator first,
|
||||||
|
MapRandomAccessIterator mapFirst,
|
||||||
|
size_t len,
|
||||||
|
std::function<int(int)> gen)
|
||||||
|
{
|
||||||
|
for (size_t i = len-1; i > 0; --i) {
|
||||||
|
auto r = gen(i+1);
|
||||||
|
std::swap(first[i], first[r]);
|
||||||
|
std::swap(mapFirst[i], mapFirst[r]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Seed insecure_rand using the random pool.
|
* Seed insecure_rand using the random pool.
|
||||||
* @param Deterministic Use a deterministic seed
|
* @param Deterministic Use a deterministic seed
|
||||||
|
|||||||
Reference in New Issue
Block a user