Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
MT19937 visualization
/* $ cc -O3 mtvisualize.c
* $ ./a.out | x264 -o video.mp4 /dev/stdin
* http://nullprogram.com/video/?v=mt19937-shuffle
*/
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#define CON 0x444444
#define COFF 0xffffff
#define ROWS 125
#define COLS 5
#define WIDTH (COLS * 33 - 1)
#define HEIGHT (ROWS)
#define SCALE 6
static unsigned char image[SCALE * WIDTH * 3 * SCALE * HEIGHT];
static void
set(int x, int y, unsigned long c)
{
for (int sy = 0; sy < SCALE; sy++) {
int yy = y * SCALE + sy;
for (int sx = 0; sx < SCALE; sx++) {
unsigned char *p;
int xx = x * SCALE + sx;
p = image + yy * WIDTH * SCALE * 3 + xx * 3;
p[0] = c >> 0;
p[1] = c >> 8;
p[2] = c >> 16;
}
}
}
static void
draw_int(int x, int y, uint32_t v, unsigned long on, unsigned long off)
{
for (int i = 0; i < 32; i++)
set(x + (31 - i), y, (v >> i) & 1 ? on : off);
}
#define MT_W 32
#define MT_N 624
#define MT_M 397
#define MT_R 31
#define MT_A UINT32_C(0x9908b0df)
#define MT_U 11
#define MT_D UINT32_C(0xffffffff)
#define MT_S 7
#define MT_B UINT32_C(0x9d2c5680)
#define MT_T 15
#define MT_C UINT32_C(0xefc60000)
#define MT_L 18
#define MT_F UINT32_C(1812433253)
#define MT_LM ((UINT32_C(1) << MT_R) - 1)
#define MT_UM (~MT_LM)
struct mt {
uint32_t v[MT_N];
int i;
};
static void
draw(struct mt *mt, int m, int n, int o)
{
draw_int(0, 0, mt->i, CON, COFF);
for (int i = 0; i < 624; i++) {
int x = (i + 1) / ROWS;
int y = (i + 1) % ROWS;
unsigned long con = CON;
unsigned long coff = COFF;
if (i == m) {
con |= 0xff0000;
coff |= 0xffaaaa;
} else if (i == n) {
con |= 0x00ff00;
coff |= 0xaaffaa;
} else if (i == o) {
con |= 0x0000ff;
coff |= 0xaaaaff;
}
draw_int(x * 33, y, mt->v[i], con, coff);
}
printf("P6\n%d %d\n255\n", WIDTH * SCALE, HEIGHT * SCALE);
fwrite(image, 1, sizeof(image), stdout);
}
static void
mt_init(struct mt *mt, uint32_t seed) {
mt->i = MT_N;
mt->v[0] = seed;
for (int i = 1; i < MT_N; i++)
mt->v[i] = MT_F * (mt->v[i - 1] ^ (mt->v[i - 1] >> (MT_W - 2))) + i;
}
static uint32_t
mt_rand(struct mt *mt)
{
if (mt->i >= MT_N) {
/* Draw BEGIN */
draw(mt, -1, -1, -1);
/* Draw END */
for (int i = 0; i < MT_N; i++) {
uint32_t x = (mt->v[i] & MT_UM) + (mt->v[(i + 1) % MT_N] & MT_LM);
uint32_t xa = (x >> 1) ^ ((x & 1) * MT_A);
mt->v[i] = mt->v[(i + MT_M) % MT_N] ^ xa;
/* Draw BEGIN */
mt->i = i;
draw(mt, i, (i + 1) % MT_N, (i + MT_M) % MT_N);
/* Draw END */
}
mt->i = 0;
/* Draw BEGIN */
draw(mt, -1, -1, -1);
/* Draw END */
}
uint32_t y = mt->v[mt->i++];
y = y ^ ((y >> MT_U) & MT_D);
y = y ^ ((y << MT_S) & MT_B);
y = y ^ ((y << MT_T) & MT_C);
y = y ^ (y >> MT_L);
return y;
}
int
main(void)
{
memset(image, 0xff, sizeof(image));
struct mt mt[1] = {{{0}, 0}};
mt_init(mt, 1131464071);
mt_rand(mt);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.