I Ching PRNG

L

luserXtrog

Hello all.
I got this little idea that I think is nifty. It's a pseudorandom
number generator based on the sequence of hexagrams in
the I Ching (interpreting each hexagram as a binary-
endcoded number, a la IIRC Leibniz). I've pieced together a
little prototype; but I am having trouble extending its range
and domain.

Thoughts/ideas/condemnations?

/* ich.c */
#include <stdio.h>

/*
Table taken from:
Cleary, Thomas, trans. I CHING: The Book of Change.
Shambala Publications, Inc. Boston: 1992.
Reorganized to follow binary sequence of trigrams,
where yang is 0 and yin is 1,
and trigrams are read from the top downward:
sky 0, lake 1, fire 2, thunder 3,
wind 4, water 5, mountain 6, earth 7
*/
unsigned char iching[]={
/*_*8 + */
/* 0 1 2 3 4 5 6 7 */
/*0*/ 1, 43, 14, 34, 9, 5, 26, 11,
/*1*/ 10, 58, 38, 54, 61, 60, 41, 19,
/*2*/ 13, 49, 30, 55, 37, 63, 22, 36,
/*3*/ 25, 17, 21, 51, 42, 3, 27, 24,
/*4*/ 44, 28, 50, 32, 57, 48, 18, 46,
/*5*/ 6, 47, 64, 40, 59, 29, 4, 7,
/*6*/ 33, 31, 56, 62, 53, 39, 52, 15,
/*7*/ 12, 45, 35, 16, 20, 8, 23, 2
};
/*
Interesting:
iching[0*8+5] == 5, sky/water: waiting
waiting encodes to itself.
*/

unsigned char corr[]={
2, 1, 20, 19, 57, 58, 13, 27, 32,
46, 18, 17, 7, 28, 25, 42, 12, 11, 4, 3, 45,
39, 24, 23, 15, 48, 8, 14, 41, 31, 30, 9, 49,
50, 51, 52, 62, 47, 22, 61, 29, 16, 44, 43, 21,
10, 38, 26, 33, 34, 35, 36, 63, 64, 56,
55, 5, 6, 60, 59, 40, 37, 53, 54
};

unsigned char comp[]={
2, 1, 50, 49, 35, 36, 13, 14, 16,
15, 12, 11, 7, 8, 10, 9, 18, 17, 33, 34, 48,
42, 43, 44, 46, 45, 28, 27, 30, 29, 41, 42, 19,
20, 5, 6, 40, 39, 38, 37, 31, 32, 23, 24, 26,
25, 22, 21, 4, 3, 57, 58, 54, 53, 59,
60, 51, 52, 55, 56, 62, 61, 64, 63
};

unsigned char seed = '\000'; /* sky/sky: the creative */

unsigned char randi() {
unsigned char ret;
ret = iching[seed % 64] - 1; /* cardinal-1=ordinal */
ret = corr[comp[ret] - 1] % 64;
seed++;
return ret;
}

int main() {
int i;
for(i=0;i<65;i++)
printf("using seed: %02d, ", (int)seed),
printf("randi returns: %02d\n", (int) randi());
printf("final seed: %02d\n", (int)seed);
return 0;
}
/*eof*/

gives the following output:
using seed: 00, randi returns: 01
using seed: 01, randi returns: 24
using seed: 02, randi returns: 27
using seed: 03, randi returns: 03
using seed: 04, randi returns: 42
using seed: 05, randi returns: 51
using seed: 06, randi returns: 21
using seed: 07, randi returns: 17
using seed: 08, randi returns: 25
using seed: 09, randi returns: 36
using seed: 10, randi returns: 22
using seed: 11, randi returns: 63
using seed: 12, randi returns: 37
using seed: 13, randi returns: 55
using seed: 14, randi returns: 30
using seed: 15, randi returns: 49
using seed: 16, randi returns: 13
using seed: 17, randi returns: 19
using seed: 18, randi returns: 41
using seed: 19, randi returns: 60
using seed: 20, randi returns: 61
using seed: 21, randi returns: 54
using seed: 22, randi returns: 16
using seed: 23, randi returns: 58
using seed: 24, randi returns: 10
using seed: 25, randi returns: 11
using seed: 26, randi returns: 26
using seed: 27, randi returns: 05
using seed: 28, randi returns: 09
using seed: 29, randi returns: 34
using seed: 30, randi returns: 14
using seed: 31, randi returns: 43
using seed: 32, randi returns: 23
using seed: 33, randi returns: 08
using seed: 34, randi returns: 20
using seed: 35, randi returns: 16
using seed: 36, randi returns: 35
using seed: 37, randi returns: 45
using seed: 38, randi returns: 12
using seed: 39, randi returns: 15
using seed: 40, randi returns: 52
using seed: 41, randi returns: 39
using seed: 42, randi returns: 53
using seed: 43, randi returns: 62
using seed: 44, randi returns: 56
using seed: 45, randi returns: 31
using seed: 46, randi returns: 33
using seed: 47, randi returns: 07
using seed: 48, randi returns: 04
using seed: 49, randi returns: 29
using seed: 50, randi returns: 59
using seed: 51, randi returns: 40
using seed: 52, randi returns: 00
using seed: 53, randi returns: 47
using seed: 54, randi returns: 06
using seed: 55, randi returns: 46
using seed: 56, randi returns: 18
using seed: 57, randi returns: 48
using seed: 58, randi returns: 57
using seed: 59, randi returns: 32
using seed: 60, randi returns: 50
using seed: 61, randi returns: 28
using seed: 62, randi returns: 44
using seed: 63, randi returns: 02
using seed: 64, randi returns: 02
final seed: 65

tia
 
L

luserXtrog

I know just enough about PRNG's
to know that I'm not qualified
to comment on how good or how bad it is.

When I was more ignorant,
I would  have formed an opinion about it.

It is precisely due to my own ignorance that I was led to
this idea, hypothesizing that a mystical ordering of values
would be inherently non-mathematical. I asked for help
because whenever I try to think of extending it, I end
up confusing myself.

It seems straightforward to break a longer integer seed
into a string a 6bit numbers, each of which would govern
it's respective 6bit portion of value to be returned. But
the epiphany eludes me. It seems that each 6bit piece
should somehow be modified by the result of the adjacent
transformation, so I can start with a seed of 1 and all
the zero bits will be interpreted differently.

Thus, the thought of extending either the range or domain
separately leads back to the total problem.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top