jweinst1
6/4/2019 - 6:48 AM

using cellular automata to generate random numbers

using cellular automata to generate random numbers

#include <stdio.h>
#include <stdlib.h>

typedef struct {
	unsigned char cells[sizeof(unsigned long)];
} rand_t;

#define UNSIGNED_LONG_TWO_SLOTS (sizeof(unsigned long) / 2)

#define RAND_T_LOAD(rd, seed) do { \
	unsigned char* reader = (unsigned char*)(&(seed)); \
	unsigned ir; \
	for(ir = 0; ir < sizeof(unsigned long); ir++) rd->cells[ir] = reader[ir]; \
} while (0)


typedef struct {
	unsigned char match[2];
	unsigned char result;
} rule_t;

/**
 * Rule matching table
 */
 static const rule_t RULE_MATCH[] = {
	{{0, 0}, 1},
	{{0, 1}, 0},
	{{1, 1}, 2},
	{{0, 2}, 1},
	{{1, 2}, 2},
	{{2, 0}, 0},
	{{2, 1}, 1},
	{{2, 2}, 0},
};

static const size_t RULE_MATCH_COUNT = sizeof(RULE_MATCH) / sizeof(rule_t);
static const unsigned char RULE_DEFAULT = 0;

static void rand_clean(rand_t* cells)
{
	cells->cells[0] = 0;
	cells->cells[1] = 0;
	cells->cells[2] = 0;
	cells->cells[3] = 0;
	cells->cells[4] = 0;
	cells->cells[5] = 0;
	cells->cells[6] = 0;
	cells->cells[7] = 0;
}

static rand_t rand_generation(const rand_t* cells)
{
	rand_t next_gen;
	rand_clean(&next_gen);
	unsigned i;
	for(i=0; i < sizeof(unsigned long) - 1; i++)
	{
		unsigned j;
		for(j=0; j < RULE_MATCH_COUNT;j++)
		{
			if(cells->cells[i] == RULE_MATCH[j].match[0] && cells->cells[i + 1] == RULE_MATCH[j].match[1])
			{
				next_gen.cells[i] = RULE_MATCH[j].result;
				break;
			}
		}
	}
	return next_gen;
}

void rand_print(const rand_t* cells)
{
	unsigned i;
	for(i=0; i < sizeof(unsigned long) ; i++)
	{
		printf("(%u) ", cells->cells[i]);
	}
	printf(" as u64: %lu", *(unsigned long*)(cells->cells));
	putc('\n', stdout);
}


int main(int argc, char const *argv[])
{
	rand_t foo = {{2, 1, 0, 0, 2, 0, 1, 2}};
	rand_print(&foo);
	unsigned i;
	for(i = 0; i < 50; i++)
	{
	foo = rand_generation(&foo);
	rand_print(&foo);
	}
	return 0;
}

// example results

/**
(2) (1) (0) (0) (2) (0) (1) (2)  as u64: 144396671642501378
(1) (0) (1) (1) (0) (0) (2) (0)  as u64: 562949970264065
(0) (0) (2) (0) (1) (1) (0) (0)  as u64: 1103806726144
(1) (1) (0) (0) (2) (0) (1) (0)  as u64: 281483566645505
(2) (0) (1) (1) (0) (0) (0) (0)  as u64: 16842754
(0) (0) (2) (0) (1) (1) (1) (0)  as u64: 282578783436800
(1) (1) (0) (0) (2) (2) (0) (0)  as u64: 2207613190401
(2) (0) (1) (1) (0) (0) (1) (0)  as u64: 281474993553410
(0) (0) (2) (0) (1) (0) (0) (0)  as u64: 4295098368
(1) (1) (0) (0) (0) (1) (1) (0)  as u64: 282574488338689
(2) (0) (1) (1) (0) (2) (0) (0)  as u64: 2199040098306
(0) (0) (2) (0) (1) (0) (1) (0)  as u64: 281479271809024
(1) (1) (0) (0) (0) (0) (0) (0)  as u64: 257
(2) (0) (1) (1) (1) (1) (1) (0)  as u64: 282578800148482
(0) (0) (2) (2) (2) (2) (0) (0)  as u64: 2207646875648
(1) (1) (0) (0) (0) (0) (1) (0)  as u64: 281474976710913
(2) (0) (1) (1) (1) (0) (0) (0)  as u64: 4311810050
(0) (0) (2) (2) (0) (1) (1) (0)  as u64: 282574522023936
(1) (1) (0) (0) (0) (2) (0) (0)  as u64: 2199023255809
(2) (0) (1) (1) (1) (0) (1) (0)  as u64: 281479288520706
(0) (0) (2) (2) (0) (0) (0) (0)  as u64: 33685504
(1) (1) (0) (0) (1) (1) (1) (0)  as u64: 282578783305985
(2) (0) (1) (0) (2) (2) (0) (0)  as u64: 2207613255682
(0) (0) (0) (1) (0) (0) (1) (0)  as u64: 281474993487872
(1) (1) (0) (0) (1) (0) (0) (0)  as u64: 4294967553
(2) (0) (1) (0) (0) (1) (1) (0)  as u64: 282574488403970
(0) (0) (0) (1) (0) (2) (0) (0)  as u64: 2199040032768
(1) (1) (0) (0) (1) (0) (1) (0)  as u64: 281479271678209
(2) (0) (1) (0) (0) (0) (0) (0)  as u64: 65538
(0) (0) (0) (1) (1) (1) (1) (0)  as u64: 282578800082944
(1) (1) (0) (2) (2) (2) (0) (0)  as u64: 2207646744833
(2) (0) (1) (0) (0) (0) (1) (0)  as u64: 281474976776194
(0) (0) (0) (1) (1) (0) (0) (0)  as u64: 4311744512
(1) (1) (0) (2) (0) (1) (1) (0)  as u64: 282574521893121
(2) (0) (1) (0) (0) (2) (0) (0)  as u64: 2199023321090
(0) (0) (0) (1) (1) (0) (1) (0)  as u64: 281479288455168
(1) (1) (0) (2) (0) (0) (0) (0)  as u64: 33554689
(2) (0) (1) (0) (1) (1) (1) (0)  as u64: 282578783371266
(0) (0) (0) (0) (2) (2) (0) (0)  as u64: 2207613190144
(1) (1) (1) (1) (0) (0) (1) (0)  as u64: 281474993553665
(2) (2) (2) (0) (1) (0) (0) (0)  as u64: 4295098882
(0) (0) (0) (0) (0) (1) (1) (0)  as u64: 282574488338432
(1) (1) (1) (1) (0) (2) (0) (0)  as u64: 2199040098561
(2) (2) (2) (0) (1) (0) (1) (0)  as u64: 281479271809538
(0) (0) (0) (0) (0) (0) (0) (0)  as u64: 0
(1) (1) (1) (1) (1) (1) (1) (0)  as u64: 282578800148737
(2) (2) (2) (2) (2) (2) (0) (0)  as u64: 2207646876162
(0) (0) (0) (0) (0) (0) (1) (0)  as u64: 281474976710656
(1) (1) (1) (1) (1) (0) (0) (0)  as u64: 4311810305
(2) (2) (2) (2) (0) (1) (1) (0)  as u64: 282574522024450
(0) (0) (0) (0) (0) (2) (0) (0)  as u64: 2199023255552
*/