How can we generate random numbers in Scrypto if floating point libraries are not allowed be used? I want to be able to generate unique IDs for NFTs.
There are 2 ways to solve this:
Self managed - if the data structure is a Vec, we can use vec.len() + 1 as the generated ID, making things more trivial.
Generated Uuid - Scrypto provides Runtime::generate_uuid which is a generated number format in Uuid which should guarantee uniqueness
We can also generate values given a max range:
fn get_random(end: usize) -> usize {
let num = Runtime::generate_uuid();
(num % end as u128) as usize
}
// prints number between 0 - 5
info!("{}", get_random(5));
You can generate a pseudo random NFT id using the built-in NonFungibleId::random() method.
let new_nft_id: NonFungibleId = NonFungibleId::random();
Reference: https://radixdlt.github.io/radixdlt-scrypto/scrypto/resource/struct.NonFungibleId.html
Related
I have a list of nine numbers (1-9), that I need to shuffle based on a seed, and guarantee that each permutation of that shuffle is unique. I'd like to do that like this:
list.shuffle(Random(seed))
There are 9! (362,880) possible permutations of this list, and I know that if I pass it the same Random seed twice, those two permutations will be identical, but I need a way to guarantee that for any given seed between 0 and 362,880, the list order will be unique from any other seed in that range.
Is this possible in Kotlin?
This isn't really a question about Kotlin, but algorithms in general.
There could be much better solution, but you can represent your seed as a number with variable base. First digit has base of 9, second has base of 8 and so on. When dealing with numbers of base 10, we need to repeatedly divide it by 10 and note the remainder to split it into digits. In our case we need to divide it by 9, 8, 7 and so on. This way we will convert the seed to a list of 9 digits like this: 0-8, 0-7, 0-6, ... . What is important: each seed has a unique list of such digits.
Now, if we create another list of numbers 1-9, then we can use the list of digits from the previous paragraph to pick numbers from it, removing them at the same time. Initially, we have 9 items in our list, so valid indexes are 0-8 and this is exactly the range of our first digit. Then we have only 8 remaining items, so they have indexes 0-7 and this is exactly what the second digit is. And so on.
This is not that easy to explain in words, code could be better:
fun shuffled1to9(seed: Int): List<Int> {
require(seed in 0 until 362880)
val remaining = (1..9).toMutableList()
val result = mutableListOf<Int>()
var curr = seed
(9 downTo 2).forEach {
val (next, pick) = curr divmod it
result += remaining.removeAt(pick)
curr = next
}
result += remaining.single()
return result
}
infix fun Int.divmod(divisor: Int): Pair<Int, Int> {
val quotient = this / divisor
return quotient to (this - quotient * divisor)
}
shuffled1to9(0) returns original order of 1..9. shuffled1to9(362879) returns the order inverted: 9..1. Any number in between should generate a unique ordering.
Of course, it can be very easily generalized to different lists of numbers and to different sizes.
I have recently sat a computing exam in university in which we were never taught beforehand about the modulus function or any other check for odd/even function and we have no access to external documentation except our previous lecture notes. Is it possible to do this without these and how?
Bitwise AND (&)
Extract the last bit of the number using the bitwise AND operator. If the last bit is 1, then it's odd, else it's even. This is the simplest and most efficient way of testing it. Examples in some languages:
C / C++ / C#
bool is_even(int value) {
return (value & 1) == 0;
}
Java
public static boolean is_even(int value) {
return (value & 1) == 0;
}
Python
def is_even(value):
return (value & 1) == 0
I assume this is only for integer numbers as the concept of odd/even eludes me for floating point values.
For these integer numbers, the check of the Least Significant Bit (LSB) as proposed by Rotem is the most straightforward method, but there are many other ways to accomplish that.
For example, you could use the integer division operation as a test. This is one of the most basic operation which is implemented in virtually every platform. The result of an integer division is always another integer. For example:
>> x = int64( 13 ) ;
>> x / 2
ans =
7
Here I cast the value 13 as a int64 to make sure MATLAB treats the number as an integer instead of double data type.
Also here the result is actually rounded towards infinity to the next integral value. This is MATLAB specific implementation, other platform might round down but it does not matter for us as the only behavior we look for is the rounding, whichever way it goes. The rounding allow us to define the following behavior:
If a number is even: Dividing it by 2 will produce an exact result, such that if we multiply this result by 2, we obtain the original number.
If a number is odd: Dividing it by 2 will result in a rounded result, such that multiplying it by 2 will yield a different number than the original input.
Now you have the logic worked out, the code is pretty straightforward:
%% sample input
x = int64(42) ;
y = int64(43) ;
%% define the checking function
% uses only multiplication and division operator, no high level function
is_even = #(x) int64(x) == (int64(x)/2)*2 ;
And obvisouly, this will yield:
>> is_even(x)
ans =
1
>> is_even(y)
ans =
0
I found out from a fellow student how to solve this simplistically with maths instead of functions.
Using (-1)^n :
If n is odd then the outcome is -1
If n is even then the outcome is 1
This is some pretty out-of-the-box thinking, but it would be the only way to solve this without previous knowledge of complex functions including mod.
DISCLAIMER: Rather theoretical question here, not looking for a correct answere, just asking for some inspiration!
Consider this:
A function is called repetitively and returns integers based on seeds (the same seed returns the same integer). Your task is to find out which integer is returned most often. Easy enough, right?
But: You are not allowed to use arrays or fields to store return values of said function!
Example:
int mostFrequentNumber = 0;
int occurencesOfMostFrequentNumber = 0;
int iterations = 10000000;
for(int i = 0; i < iterations; i++)
{
int result = getNumberFromSeed(i);
int occurencesOfResult = magic();
if(occurencesOfResult > occurencesOfMostFrequentNumber)
{
mostFrequentNumber = result;
occurencesOfMostFrequentNumber = occurencesOfResult;
}
}
If getNumberFromSeed() returns 2,1,5,18,5,6 and 5 then mostFrequentNumber should be 5 and occurencesOfMostFrequentNumber should be 3 because 5 is returned 3 times.
I know this could easily be solved using a two-dimentional list to store results and occurences. But imagine for a minute that you can not use any kind of arrays, lists, dictionaries etc. (Maybe because the system that is running the code has such a limited memory, that you cannot store enough integers at once or because your prehistoric programming language has no concept of collections).
How would you find mostFrequentNumber and occurencesOfMostFrequentNumber? What does magic() do?? (Of cause you do not have to stick to the example code. Any ideas are welcome!)
EDIT: I should add that the integers returned by getNumber() should be calculated using a seed, so the same seed returns the same integer (i.e. int result = getNumber(5); this would always assign the same value to result)
Make an hypothesis: Assume that the distribution of integers is, e.g., Normal.
Start simple. Have two variables
. N the number of elements read so far
. M1 the average of said elements.
Initialize both variables to 0.
Every time you read a new value x update N to be N + 1 and M1 to be M1 + (x - M1)/N.
At the end M1 will equal the average of all values. If the distribution was Normal this value will have a high frequency.
Now improve the above. Add a third variable:
M2 the average of all (x - M1)^2 for all values of xread so far.
Initialize M2 to 0. Now get a small memory of say 10 elements or so. For every new value x that you read update N and M1 as above and M2 as:
M2 := M2 + (x - M1)^2 * (N - 1) / N
At every step M2 is the variance of the distribution and sqrt(M2) its standard deviation.
As you proceed remember the frequencies of only the values read so far whose distances to M1 are less than sqrt(M2). This requires the use of some additional array, however, the array will be very short compared to the high number of iterations you will run. This modification will allow you to guess better the most frequent value instead of simply answering the mean (or average) as above.
UPDATE
Given that this is about insights for inspiration there is plenty of room for considering and adapting the approach I've proposed to any particular situation. Here are some thoughts
When I say assume that the distribution is Normal you should think of it as: Given that the problem has no solution, let's see if there is some qualitative information I can use to decide what kind of distribution would the data have. Given that the algorithm is intended to find the most frequent number, it should be fine to assume that the distribution is not uniform. Let's try with Normal, LogNormal, etc. to see what can be found out (more on this below.)
If the game completely disallows the use of any array, then fine, keep track of only, say 10 numbers. This would allow you to count the occurrences of the 10 best candidates, which will give more confidence to your answer. In doing this choose your candidates around the theoretical most likely value according to the distribution of your hypothesis.
You cannot use arrays but perhaps you can read the sequence of numbers two or three times, not just once. In that case you can read it once to check whether you hypothesis about its distribution is good nor bad. For instance, if you compute not just the variance but the skewness and the kurtosis you will have more elements to check your hypothesis. For instance, if the first reading indicates that there is some bias, you could use a LogNormal distribution instead, etc.
Finally, in addition to providing the approximate answer you would be able to use the information collected during the reading to estimate an interval of confidence around your answer.
Alright, I found a decent solution myself:
int mostFrequentNumber = 0;
int occurencesOfMostFrequentNumber = 0;
int iterations = 10000000;
int maxNumber = -2147483647;
int minNumber = 2147483647;
//Step 1: Find the largest and smallest number that _can_ occur
for(int i = 0; i < iterations; i++)
{
int result = getNumberFromSeed(i);
if(result > maxNumber)
{
maxNumber = result;
}
if(result < minNumber)
{
minNumber = result;
}
}
//Step 2: for each possible number between minNumber and maxNumber, count occurences
for(int thisNumber = minNumber; thisNumber <= maxNumber; thisNumber++)
{
int occurenceOfThisNumber = 0;
for(int i = 0; i < iterations; i++)
{
int result = getNumberFromSeed(i);
if(result == thisNumber)
{
occurenceOfThisNumber++;
}
}
if(occurenceOfThisNumber > occurencesOfMostFrequentNumber)
{
occurencesOfMostFrequentNumber = occurenceOfThisNumber;
mostFrequentNumber = thisNumber;
}
}
I must admit, this may take a long time, depending on the smallest and largest possible. But it will work without using arrays.
I have defined the following:
typdef enum {
none = 0,
alpha = 1,
beta = 2,
delta = 4
gamma = 8
omega = 16,
} Greek;
Greek t = beta | delta | gammax
I would like to be able to pick one of the flags set in t randomly. The value of t can vary (it could be, anything from the enum).
One thought I had was something like this:
r = 0;
while ( !t & ( 2 << r ) { r = rand(0,4); }
Anyone got any more elegant ideas?
If it helps, I want to do this in ObjC...
Assuming I've correctly understood your intent, if your definition of "elegant" includes table lookups the following should do the trick pretty efficiently. I've written enough to show how it works, but didn't fill out the entire table. Also, for Objective-C I recommend arc4random over using rand.
First, construct an array whose indices are the possible t values and whose elements are arrays of t's underlying Greek values. I ignored none, but that's a trivial addition to make if you want it. I also found it easiest to specify the lengths of the subarrays. Alternatively, you could do this with NSArrays and have them self-report their lengths:
int myArray[8][4] = {
{0},
{1},
{2},
{1,2},
{4},
{4,1},
{4,2},
{4,2,1}
};
int length[] = {1,1,1,2,1,2,2,3};
Then, for any given t you can randomly select one of its elements using:
int r = myArray[t][arc4random_uniform(length[t])];
Once you get past the setup, the actual random selection is efficient, with no acceptance/rejection looping involved.
I want to get all combination of numbers to sum.
My input is X that is variable and X is the number of numbers,
For example:
X=4 means we have 1,2,3,4
x=100 means 1,2,3,4,5,,98,99,100
Now I want to get {(1,2)(1,3)(1,4)(2,3)(2,4)(3,4),(1,2,3)(1,3,4)…}
We can’t have repetitive sequence like (1,2)(2,1)(1,2,3)(1,3,2)
I want to get all combinations that these numbers can be sum without repetitive sequence.
Can anyone help me to find it’s algorithm? I must code it in VBA of Excel using for loops
the "algorithm" is solved from Maths and given by the combinations of X by 2:
X!/((X-2)!*2!)=X!/((X-2)!*2)
(note: Just in case... "!" is the factorial...)
now if you want to use for-loop to calculate factorial (written in c):
int main()
{
int num,factorial=1;
cout<<" Enter Number To Find Its Factorial: ";
cin>>num;
for(int a=1;a<=num;a++)
{
factorial=factorial*a;
}