Related
I'm currently working on an OpenVibe Session in which I must program a Lua Script. My problem is generating a random table with 2 values: 1s and 2s. If the value in table is 1, then send Stimulus through output 1. And if it's 2, then through output 2.
My question is how I can generate in Lua code a table of 52 1s and 2s (44 1s and 8 2s which correspond to 85% 1s and 15% 2s) in a way that you have at least 3 1s before the next 2s? Somehow like this: 1 1 1 2 1 1 1 1 1 1 2 1 1 1 1 2 1 1 1 2.
I´m not an expert in Lua. So any help would be most appreciated.
local get_table_52
do
local cached_C = {}
local function C(n, k)
local idx = n * 9 + k
local value = cached_C[idx]
if not value then
if k == 0 or k == n then
value = 1
else
value = C(n-1, k-1) + C(n-1, k)
end
cached_C[idx] = value
end
return value
end
function get_table_52()
local result = {}
for j = 1, 52 do
result[j] = 1
end
local r = math.random(C(28, 8))
local p = 29
for k = 8, 1, -1 do
local b = 0
repeat
r = r - b
p = p - 1
b = C(p - 1, k - 1)
until r <= b
result[p + k * 3] = 2
end
return result
end
end
Usage:
local t = get_table_52()
-- t contains 44 ones and 8 twos, there are at least 3 ones before next two
Here is the logic.
You have 8 2s. Before each 2 there is a string of 3 1s. That's 32 of your numbers.
Those 8 groups of 1112 separate 9 spots that the remaining 20 1s can go.
So your problem is to randomly distribute 20 1s to 9 random places. And then take that collection of numbers and write out your list. So in untested code from a non-Lua programmer:
-- Populate buckets
local buckets = {0, 0, 0, 0, 0, 0, 0, 0, 0}
for k = 1, 20 do
local bucket = floor(rand(9))
buckets[bucket] = buckets[bucket] + 1
end
-- Turn that into an array
local result = {}
local i = 0
for bucket = 0, 8 do
-- Put buckets[bucket] 1s in result
if 0 < buckets[bucket] do
for j = 0, buckets[bucket] do
result[i] = 1
i = i + 1
end
end
-- Add our separating 1112?
if bucket < 8 do
result[i] = 1
result[i+1] = 1
result[i+2] = 1
result[i+3] = 2
i = i + 4
end
end
I came across an interesting problem:
How would you count the number of 1 digits in the representation of 11 to the power of N, 0<N<=1000.
Let d be the number of 1 digits
N=2 11^2 = 121 d=2
N=3 11^3 = 1331 d=2
Worst time complexity expected O(N^2)
The simple approach where you compute the number and count the number of 1 digits my getting the last digit and dividing by 10, does not work very well. 11^1000 is not even representable in any standard data type.
Powers of eleven can be stored as a string and calculated quite quickly that way, without a generalised arbitrary precision math package. All you need is multiply by ten and add.
For example, 111 is 11. To get the next power of 11 (112), you multiply by (10 + 1), which is effectively the number with a zero tacked the end, added to the number: 110 + 11 = 121.
Similarly, 113 can then be calculated as: 1210 + 121 = 1331.
And so on:
11^2 11^3 11^4 11^5 11^6
110 1210 13310 146410 1610510
+11 +121 +1331 +14641 +161051
--- ---- ----- ------ -------
121 1331 14641 161051 1771561
So that's how I'd approach, at least initially.
By way of example, here's a Python function to raise 11 to the n'th power, using the method described (I am aware that Python has support for arbitrary precision, keep in mind I'm just using it as a demonstration on how to do this an an algorithm, which is how the question was tagged):
def elevenToPowerOf(n):
# Anything to the zero is 1.
if n == 0: return "1"
# Otherwise, n <- n * 10 + n, once for each level of power.
num = "11"
while n > 1:
n = n - 1
# Make multiply by eleven easy.
ten = num + "0"
num = "0" + num
# Standard primary school algorithm for adding.
newnum = ""
carry = 0
for dgt in range(len(ten)-1,-1,-1):
res = int(ten[dgt]) + int(num[dgt]) + carry
carry = res // 10
res = res % 10
newnum = str(res) + newnum
if carry == 1:
newnum = "1" + newnum
# Prepare for next multiplication.
num = newnum
# There you go, 11^n as a string.
return num
And, for testing, a little program which works out those values for each power that you provide on the command line:
import sys
for idx in range(1,len(sys.argv)):
try:
power = int(sys.argv[idx])
except (e):
print("Invalid number [%s]" % (sys.argv[idx]))
sys.exit(1)
if power < 0:
print("Negative powers not allowed [%d]" % (power))
sys.exit(1)
number = elevenToPowerOf(power)
count = 0
for ch in number:
if ch == '1':
count += 1
print("11^%d is %s, has %d ones" % (power,number,count))
When you run that with:
time python3 prog.py 0 1 2 3 4 5 6 7 8 9 10 11 12 1000
you can see that it's both accurate (checked with bc) and fast (finished in about half a second):
11^0 is 1, has 1 ones
11^1 is 11, has 2 ones
11^2 is 121, has 2 ones
11^3 is 1331, has 2 ones
11^4 is 14641, has 2 ones
11^5 is 161051, has 3 ones
11^6 is 1771561, has 3 ones
11^7 is 19487171, has 3 ones
11^8 is 214358881, has 2 ones
11^9 is 2357947691, has 1 ones
11^10 is 25937424601, has 1 ones
11^11 is 285311670611, has 4 ones
11^12 is 3138428376721, has 2 ones
11^1000 is 2469932918005826334124088385085221477709733385238396234869182951830739390375433175367866116456946191973803561189036523363533798726571008961243792655536655282201820357872673322901148243453211756020067624545609411212063417307681204817377763465511222635167942816318177424600927358163388910854695041070577642045540560963004207926938348086979035423732739933235077042750354729095729602516751896320598857608367865475244863114521391548985943858154775884418927768284663678512441565517194156946312753546771163991252528017732162399536497445066348868438762510366191040118080751580689254476068034620047646422315123643119627205531371694188794408120267120500325775293645416335230014278578281272863450085145349124727476223298887655183167465713337723258182649072572861625150703747030550736347589416285606367521524529665763903537989935510874657420361426804068643262800901916285076966174176854351055183740078763891951775452021781225066361670593917001215032839838911476044840388663443684517735022039957481918726697789827894303408292584258328090724141496484460001, has 105 ones
real 0m0.609s
user 0m0.592s
sys 0m0.012s
That may not necessarily be O(n2) but it should be fast enough for your domain constraints.
Of course, given those constraints, you can make it O(1) by using a method I call pre-generation. Simply write a program to generate an array you can plug into your program which contains a suitable function. The following Python program does exactly that, for the powers of eleven from 1 to 100 inclusive:
def mulBy11(num):
# Same length to ease addition.
ten = num + '0'
num = '0' + num
# Standard primary school algorithm for adding.
result = ''
carry = 0
for idx in range(len(ten)-1, -1, -1):
digit = int(ten[idx]) + int(num[idx]) + carry
carry = digit // 10
digit = digit % 10
result = str(digit) + result
if carry == 1:
result = '1' + result
return result
num = '1'
print('int oneCountInPowerOf11(int n) {')
print(' static int numOnes[] = {-1', end='')
for power in range(1,101):
num = mulBy11(num)
count = sum(1 for ch in num if ch == '1')
print(',%d' % count, end='')
print('};')
print(' if ((n < 0) || (n > sizeof(numOnes) / sizeof(*numOnes)))')
print(' return -1;')
print(' return numOnes[n];')
print('}')
The code output by this script is:
int oneCountInPowerOf11(int n) {
static int numOnes[] = {-1,2,2,2,2,3,3,3,2,1,1,4,2,3,1,4,2,1,4,4,1,5,5,1,5,3,6,6,3,6,3,7,5,7,4,4,2,3,4,4,3,8,4,8,5,5,7,7,7,6,6,9,9,7,12,10,8,6,11,7,6,5,5,7,10,2,8,4,6,8,5,9,13,14,8,10,8,7,11,10,9,8,7,13,8,9,6,8,5,8,7,15,12,9,10,10,12,13,7,11,12};
if ((n < 0) || (n > sizeof(numOnes) / sizeof(*numOnes)))
return -1;
return numOnes[n];
}
which should be blindingly fast when plugged into a C program. On my system, the Python code itself (when you up the range to 1..1000) runs in about 0.6 seconds and the C code, when compiled, finds the number of ones in 111000 in 0.07 seconds.
Here's my concise solution.
def count1s(N):
# When 11^(N-1) = result, 11^(N) = (10+1) * result = 10*result + result
result = 1
for i in range(N):
result += 10*result
# Now count 1's
count = 0
for ch in str(result):
if ch == '1':
count += 1
return count
En c#:
private static void Main(string[] args)
{
var res = Elevento(1000);
var countOf1 = res.Select(x => int.Parse(x.ToString())).Count(s => s == 1);
Console.WriteLine(countOf1);
}
private static string Elevento(int n)
{
if (n == 0) return "1";
//Otherwise, n <- n * 10 + n, once for each level of power.
var num = "11";
while (n > 1)
{
n--;
// Make multiply by eleven easy.
var ten = num + "0";
num = "0" + num;
//Standard primary school algorithm for adding.
var newnum = "";
var carry = 0;
foreach (var dgt in Enumerable.Range(0, ten.Length).Reverse())
{
var res = int.Parse(ten[dgt].ToString()) + int.Parse(num[dgt].ToString()) + carry;
carry = res/10;
res = res%10;
newnum = res + newnum;
}
if (carry == 1)
newnum = "1" + newnum;
// Prepare for next multiplication.
num = newnum;
}
//There you go, 11^n as a string.
return num;
}
I want to write a loop that scans all binary sequences of length n with k 1's and n-k 0's.
Actually, in each iteration an action is performed on the sequence and if a criterion is met the loop will break, otherwise it goes to next sequence. (I am not looking for nchoosek or perms since for large values of n it takes so much time to give the output).
What MATLAB code do you suggest?
You could implement something like an iterator/generator pattern:
classdef Iterator < handle
properties (SetAccess = private)
n % sequence length
counter % keeps track of current iteration
end
methods
function obj = Iterator(n)
% constructor
obj.n = n;
obj.counter = 0;
end
function seq = next(obj)
% get next bit sequence
if (obj.counter > 2^(obj.n) - 1)
error('Iterator:StopIteration', 'Stop iteration')
end
seq = dec2bin(obj.counter, obj.n) - '0';
obj.counter = obj.counter + 1;
end
function tf = hasNext(obj)
% check if sequence still not ended
tf = (obj.counter <= 2^(obj.n) - 1);
end
function reset(obj)
% reset the iterator
obj.counter = 0;
end
end
end
Now you can use it as:
k = 2;
iter = Iterator(4);
while iter.hasNext()
seq = iter.next();
if sum(seq)~=k, continue, end
disp(seq)
end
In the example above, this will iterate through all 0/1 sequences of length 4 with exactly k=2 ones:
0 0 1 1
0 1 0 1
0 1 1 0
1 0 0 1
1 0 1 0
1 1 0 0
If I have a function named rand1() which generates number 0(30% probability) or 1(70% probability), how to write a function rand2() which generates number 0 or 1 equiprobability use rand1() ?
Update:
Finally, I found this is a problem on book Introduction to Algorithms (2nd) (I have bought the Chinese edition of this book ), Excercise 5.1-3, the original problem is :
5.1-3
Suppose that you want to output 0 with probability 1/2 and 1 with probability 1/2.
At your disposal is a procedure BIASED-RANDOM, that outputs either 0 or 1. It
outputs 1 with some probability p and 0 with probability 1− p, where 0 < p < 1,
but you do not know what p is. Give an algorithm that uses BIASED-RANDOM
as a subroutine, and returns an unbiased answer, returning 0 with probability 1/2
and 1 with probability 1/2. What is the expected running time of your algorithm
as a function of p?
the solution is :
(see: http://www.cnblogs.com/meteorgan/archive/2012/05/04/2482317.html)
To get an unbiased random bit, given only calls to BIASED-RANDOM, call
BIASED-RANDOM twice. Repeatedly do so until the two calls return different
values, and when this occurs, return the Þrst of the two bits:
UNBIASED-RANDOM
while TRUE
do
x ← BIASED-RANDOM
y ← BIASED-RANDOM
if x != y
then return x
To see that UNBIASED-RANDOM returns 0 and 1 each with probability 1/2, observe
that the probability that a given iteration returns 0 is
Pr {x = 0 and y = 1} = (1 − p)p ,
and the probability that a given iteration returns 1 is
Pr {x = 1 and y = 0} = p(1 − p) .
(We rely on the bits returned by BIASED-RANDOM being independent.) Thus, the
probability that a given iteration returns 0 equals the probability that it returns 1.
Since there is no other way for UNBIASED-RANDOM to return a value, it returns 0
and 1 each with probability 1/2.
Generate two numbers, a and b.
If a is 0 and b is 1 (21% chance), generate a 0.
If a is 1 and b is 0 (21% chance), generate a 1.
For all other cases (58% chance), just generate a new a and b and try again.
If you call rand1 twice, there is an equal chance of getting [1 0] and [0 1], so if you return the first of each non-matching pair (and discard matching pairs) you will get, on average, 0.5(1 - p2 - (1-p)2) output bits per input bit (where p is the probability of rand1 returning 1; 0.7 in your example) and independently of p, each output bit will be 1 with probability 0.5.
However, we can do better.
Rather than throw away the matching pairs, we can remember them in the hope that they are followed by opposite matching pairs - The sequences [0 0 1 1] and [1 1 0 0] are also equally likely, and again we can return the first bit whenever we see such a sequence (still with output probability 0.5.) We can keep combining them indefinitely, looking for sequences like [0 0 0 0 1 1 1 1] etc.
And we can go even further - consider the input sequences [0 0 0 1] and [0 1 0 0] produce the same output ([0]) as it stands, but these two sequences were also equally likely, so we can extract an extra bit of output from this, returning [0 0] for the first case and [0 1]
for the second. This is where it gets more complicated though, as you would need to start buffering output bits.
Both techniques can be applied recursively, and taken to the limit it becomes lossless (i.e. if rand1 has a probability of 0.5, you get an average of one output bit per input bit.)
Full description (with math) here: http://www.eecs.harvard.edu/~michaelm/coinflipext.pdf
You will need to figure out how close you want to get to 50% 0 50% 1.
If you add results from repeated calls to rand1. if the results is 0 or 2 then the value returned is 0 if it is 1 then return 1. (in code you can use modulo 2)
int val = rand1(); // prob 30% 0, and 70% 1
val=(val+rand1())%2; // prob 58% 0, and 42% 1 (#1 see math bellow)
val=(val+rand1())%2; // prob 46.8% 0, and 53.2% 1 (#2 see math bellow)
val=(val+rand1())%2; // prob 51.28% 0, and 48.72% 1
val=(val+rand1())%2; // prob 49.488% 0, and 50.512% 1
val=(val+rand1())%2; // prob 50.2048% 0, and 49.7952% 1
You get the idea. so it is up to you to figure out how close you want the probabilities. every subsequent call will gets you closer to 50% 50% but it will never be exactly equal.
If you want the math for the probabilities:
1
prob ((val+rand1()%2) = 0) = (prob(val = 0)*prob(rand1() = 0)) + (prob(val = 1)*prob(rand1() = 1)
= (0.3*0.3)+(0.7*0.7)
= 0.09 + 0.49
= 0.58
= 58%
prob ((val+rand1()%2) = 1) = (prob(val = 1)*prob(rand1() = 0)) + (prob(val = 0)*prob(rand1() = 1)
= (0.7*0.3)+(0.3*0.7)
= 0.21 + 0.21
= 0.42
= 42%
2
prob ((val+rand1()%2) = 0) = (prob(val = 0)*prob(rand1() = 0)) + (prob(val = 1)*prob(rand1() = 1)
= (0.58*0.3)+(0.42*0.7)
= 0.174 + 0.294
= 0.468
= 46.8%
prob ((val+rand1()%2) = 1) = (prob(val = 1)*prob(rand1() = 0)) + (prob(val = 0)*prob(rand1() = 1)
= (0.42*0.3)+(0.58*0.7)
= 0.126 + 0.406
= 0.532
= 53.2%
Below rand2 function will provide 50% probability for occurence of zero or one.
#define LIMIT_TO_CALCULATE_PROBABILITY 10 //set any even numbers
int rand2()
{
static int one_occurred = 0;
static int zero_occured = 0;
int rand_value = 0;
int limit = (LIMIT_TO_CALCULATE_PROBABILITY / 2);
if (LIMIT_TO_CALCULATE_PROBABILITY == (one_occured + zero_occured))
{
one_occured = 0;
zero_occured = 0;
}
rand_value = rand1();
if ((1 == rand_value) && (one_occured < limit))
{
one_occured++;
return rand_value;
}
else if ((0 == rand_value) && (zero_occured < limit))
{
zero_occured++;
return rand_value;
}
else if (1 == rand_value)
{
zero_occured++;
return 0;
}
else if (0 == rand_value)
{
one_occured++;
return 1;
}
}
I need to generate repeatable pseudo random numbers based on a set of coordinates, so that with a given seed, I will always generate the same value for a specific coordinate.
I figured I'd use something like this for the seed:
/* 64bit seed value*/
struct seed_cord {
uint16 seed;
uint16 coord_x_int;
uint16 coord_y_int;
uint8 coord_x_frac;
uint8 coord_y_frac;
}
Where coord_x_int is the integer part of the coordinate, and the fraction part is given by coord_x_frac / 0xFF. seed is a randomly pre-determined value.
But I must admit, trying to understand all the intricacies of PRNGs is a little overwhelming. What would be a good generator for what I'm attempting?
I tested out Java's PRNG using using this scheme in a quick groovy script, with the following result:
Obviously, this is hardly decent randomness.
The script I used was:
import java.awt.image.BufferedImage
import javax.imageio.ImageIO
short shortSeed = new Random().next(16) as short
def image = new BufferedImage(512, 512, BufferedImage.TYPE_BYTE_GRAY)
def raster = image.getRaster()
//x
(0..1).each{ x ->
(0..255).each{ xFrac ->
//y
(0..1).each{ y ->
(0..255).each{ yFrac ->
long seed = (shortSeed as long) << 48 |
(x as long) << 32 |
(y as long) << 16 |
(xFrac as long) << 8 |
(yFrac as long)
def value = new Random(seed).next(8)
raster.setSample( (x? xFrac+256 : xFrac), (y? yFrac+256 : yFrac), 0 , value)
}}}}
ImageIO.write(image, "PNG", new File("randomCoord.png"))
If you're really only looking at 512x512, then that's uh... 218 pixels you're interested in.
There's plenty of space for that kind of population with good ole MD5 (128 bit output).
You can just take the lowest 32 bits for an integer if that's the kind of output you need. Really, any sort of hashing algorithm that has an output space at least as large as an int will do.
Now, you can do all sorts of fun stuff if you're paranoid. Start with a hash of your coordinates, then feed the result into a secure random number generator (java.security.SecureRandom). Then hash it 1000 times with a salt that's your birthday concatenated (x+y) times.
Joking aside, random number generators don't necessarily have wildly varying results based on small variations of the seed. They're designed to have a really, super duper long chain of generated numbers before they start repeating, while having those chains pretty evenly distributed among the number space.
On the other hand, the SecureRandom is designed to have the additional feature of being chaotic in regard to the seed.
Most languages have a PRNG package (or two) that lets you initialize the generator with a specific seed. PRNGs can also often be found as part of a larger cryptographic package; they tend to be a bit stronger than those found in general-purpose libraries.
I would take a program like this one I have created and then modify it to pick coordinates:
REM $DYNAMIC
COMMON SHARED n%, rbuf%, sz%, sw%, p1$
DECLARE SUB initialize ()
DECLARE SUB filbuf ()
DECLARE SUB setup ()
DECLARE FUNCTION Drnd# ()
DECLARE SUB core ()
DECLARE SUB modify ()
DIM SHARED pad1(340) AS STRING * 1
DIM SHARED trnsltr(66) AS STRING * 1 ' translates a 0-67 value into a pad character
DIM SHARED trnslt(255) AS INTEGER 'translates a pad value to 0-67 value -1 if error
DIM SHARED moders(26) AS INTEGER 'modding function prim number array
DIM SHARED moders2(26) AS INTEGER 'modding function prim number array
DIM SHARED ranbuf(1 TO 42) AS DOUBLE 'random number buffer if this is full and rbuf %>0
REM then this buffer is used to get new random values
REM rbuf% holds the index of the next random number to be used
REM subroutine setup loads the prime number table
REM from the data statements to be used
REM as modifiers in two different ways (or more)
REM subroutine initialize primes the pad array with initial values
REM transfering the values from a string into an array then
REM makes the first initial scrambling of this array
REM initializing pad user input phase:
CLS
INPUT "full name of file to be encrypted"; nam1$
INPUT "full name of output file"; nam2$
INPUT "enter password"; p2$
rbuf% = 0
n% = 0: sw% = 0
p3$ = STRING$(341, "Y")
p1$ = "Tfwd+-$wiHEbeMN<wjUHEgwBEGwyIEGWYrg3uehrnnqbwurt+>Hdgefrywre"
p1$ = p2$ + p1$ + p3$
PRINT "hit any key to continue any time after a display and after the graphic display"
p1$ = LEFT$(p1$, 341)
sz% = LEN(p1$)
CALL setup
CALL initialize
CLS
ibfr$ = STRING$(512, 32)
postn& = 1
OPEN nam1$ FOR BINARY AS #1
OPEN nam2$ FOR BINARY AS #2
g& = LOF(1)
max& = g&
sbtrct% = 512
WHILE g& > 0
LOCATE 1, 1
PRINT INT(1000 * ((max& - g&) / max&)) / 10; "% done";
IF g& < 512 THEN
ibfr$ = STRING$(g&, 32)
sbtrct% = g&
END IF
GET #1, postn&, ibfr$
FOR ste% = 1 TO LEN(ibfr$)
geh% = INT(Drnd# * 256)
MID$(ibfr$, ste%, 1) = CHR$(geh% XOR ASC(MID$(ibfr$, ste%, 1)))
NEXT ste%
PUT #2, postn&, ibfr$
postn& = postn& + sbtrct%
g& = g& - sbtrct%
WEND
CLOSE #2
CLOSE #1
PRINT "hit any key to exit"
i$ = ""
WHILE i$ = "": i$ = INKEY$: WEND
SYSTEM
END
DATA 3,5,7,9,11,13,17,19
DATA 23,29,33,37,43,47
DATA 53,59,67,71,73,79,83
DATA 89,91,97,101,107,109
DATA 43,45,60,62,36
REM $STATIC
SUB core
REM shuffling algorythinm
FOR a% = 0 TO 339
m% = (a% + 340) MOD 341: bez% = trnslt(ASC(pad1(340)))
IF n% MOD 3 = 0 THEN pad1(340) = trnsltr((2 * trnslt(ASC(pad1(a%))) + 67 - trnslt(ASC(pad1(m%)))) MOD 67)
IF n% MOD 3 = 1 THEN pad1(340) = trnsltr((2 * (67 - trnslt(ASC(pad1(a%)))) + 67 - trnslt(ASC(pad1(m%)))) MOD 67)
IF n% MOD 3 = 2 THEN pad1(340) = trnsltr(((2 * trnslt(ASC(pad1(a%))) + 67 - trnslt(ASC(pad1(m%)))) + moders(n% MOD 27)) MOD 67)
pad1(a% + 1) = pad1(m%): n% = (n% + 1) MOD 32767
pad1(a%) = trnsltr((bez% + trnslt(ASC(pad1(m%)))) MOD 67)
NEXT a%
sw% = (sw% + 1) MOD 32767
END SUB
FUNCTION Drnd#
IF rbuf% = 0 THEN
CALL core
CALL filbuf
IF sw% = 32767 THEN CALL modify
END IF
IF rbuf% > 0 THEN yut# = ranbuf(rbuf%)
rbuf% = rbuf% - 1
Drnd# = yut#
END FUNCTION
SUB filbuf
q% = 42: temp# = 0
WHILE q% > 0
FOR p% = 1 TO 42
k% = (p% - 1) * 8
FOR e% = k% TO k% + 7
temp# = temp# * 67: hug# = ABS(trnslt(ASC(pad1(e%)))): temp# = temp# + hug#
NEXT e%
IF temp# / (67 ^ 8) >= 0 AND q% < 43 THEN
ranbuf(q%) = temp# / (67 ^ 8): q% = q% - 1
END IF
temp# = 0
NEXT p%
WEND
rbuf% = 42
END SUB
SUB initialize
FOR a% = 0 TO 340
pad1(a%) = MID$(p1$, a% + 1, 1)
NEXT a%
FOR a% = 0 TO 340
LOCATE 1, 1
IF a% MOD 26 = 0 THEN PRINT INT((340 - a%) / 26)
sum% = 0
FOR b% = 0 TO 340
qn% = INT(Drnd# * 81)
op% = INT(qn% / 3)
qn% = qn% MOD 3
IF qn% = 0 THEN sum% = sum% + trnslt(ASC(pad1(b%)))
IF qn% = 1 THEN sum% = sum% + (67 + 66 - trnslt(ASC(pad1(b%)))) MOD 67
IF qn% = 2 THEN sum% = sum% + trnslt(ASC(pad1(b%))) + moders(op%)
NEXT b%
pad1(a%) = trnsltr(sum% MOD 67)
NEXT a%
n% = n% + 1
END SUB
SUB modify
REM modifier shuffling routine
q% = 26
temp# = 0
WHILE q% > -1
FOR p% = 1 TO 27
k% = (p% - 1) * 4 + 3
FOR e% = k% TO k% + 3
temp# = temp# * 67
hug# = ABS(trnslt(ASC(pad1(e%))))
temp# = temp# + hug#
NEXT e%
IF (temp# / (67 ^ 4)) >= 0 AND q% > -1 THEN
SWAP moders(q%), moders(INT(27 * (temp# / (67 ^ 4))))
q% = q% - 1
END IF
temp# = 0
NEXT p%
WEND
END SUB
SUB setup
FOR a% = 0 TO 26
READ moders(a%)
moders2(a%) = moders(a%)
NEXT a%
REM setting up tables and modder functions
FOR a% = 0 TO 25
trnsltr(a%) = CHR$(a% + 97)
trnsltr(a% + 26) = CHR$(a% + 65)
NEXT a%
FOR a% = 52 TO 61
trnsltr(a%) = CHR$(a% - 4)
NEXT a%
FOR a% = 62 TO 66
READ b%
trnsltr(a%) = CHR$(b%)
NEXT a%
FOR a% = 0 TO 255
trnslt(a%) = -1
NEXT a%
FOR a% = 0 TO 66
trnslt(ASC(trnsltr(a%))) = a%
NEXT a%
RESTORE
END SUB
the call to drand# gives you random numbers from 0 to 1 simply multiply that by your needed range for each vector needed p2$ is the password that is passed to the password handler which combines it with some other random characters and then caps the size to a certain limit p1$ is where the final modified password is contained
drand# itself calls another sub which is actually a clone of itself with some shuffling of
sorts that works to ensure that the numbers being produced are truly random there is also a table of values that are added in to the values being added all this in total makes the RNG many many more times random with than without.
this RNG has a very high sensitivity to slight differences in password initially set you must however make an intial call to setup and initialize to "bootstrap" the random number generator this RNG will produce Truly random numbers that will pass all tests of randomness
more random even then shuffling a deck of cards by hand , more random than rolling a dice..
hope this helps using the same password will result in the same sequnece of vectors
This program would have to be modified a bit though to pick random vectors rather than
it's current use as a secure encryption random number generator...
You can use encryption for this task, for example AES. Use your seed as the password, struct with coordinates as the data block and encrypt it. The encrypted block will be your random number (you can actually use any part of it). This approach is used in the Fortuna PRNG. The same approach can be used for disk encryption where random access of data is needed (see Random access encryption with AES In Counter mode using Fortuna PRNG:)