Skip to content

Instantly share code, notes, and snippets.

@everettcaleb
Last active August 29, 2015 14:02
Show Gist options
  • Save everettcaleb/b3259a774c786f9e4db0 to your computer and use it in GitHub Desktop.
Save everettcaleb/b3259a774c786f9e4db0 to your computer and use it in GitHub Desktop.
Dumb Assignment program with a custom Mersenne-twister implementation (in C)
// characters.c
// Author: Caleb Everett
// Assignment: #3
// Created on 6/8/2014
// Purpose: Generate two random characters using one of four functions and user input, includes
// Mersenne-twister implementation based on the pseudocode from the Wikipedia article
// (http://en.wikipedia.org/wiki/Mersenne_twister#Pseudocode)
#include <stdio.h>
#include <time.h>
//Mersenne-twister declaration stuff
#define DWORD unsigned int
#define MTSIZE 624
#define NULL 0
static DWORD MT[MTSIZE];
static int MTIndex = 0;
static void MTInit(const DWORD seed);
static const DWORD MTGetNumber(void);
static void MTGenerateNumbers(void);
//Functions for assignment
static const char firstFunction(void);
static const char secondFunction(void);
static const char thirdFunction(void);
static const char fourthFunction(void);
//Constants for assignment
#define ALPHABET_LENGTH 26
static const char * const UPPER_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static const char * const LOWER_ALPHABET = "abcdefghijklmnopqrstuvwxyz";
#define NUMBER_OF_NUMBER_WORDS 2
static const char * const NUMBER_WORDS[] = { "first", "second" };
//Entry-point
int main(int argc, char *argv[]) {
int i = 0;
int n[NUMBER_OF_NUMBER_WORDS];
const char(*f[NUMBER_OF_NUMBER_WORDS])(void);
MTInit(time(NULL) & 0xffffffffu);
printf("Please enter %d numbers from 1-4 to choose the random functions to pick two characters for you.\r\n", NUMBER_OF_NUMBER_WORDS);
while (i < NUMBER_OF_NUMBER_WORDS) {
do {
printf("Enter the %s one now (must be between 1 and 4, inclusive): ", NUMBER_WORDS[i]);
scanf("%d", &n[i]);
} while (n[i] < 1 || n[i] > 4);
switch (n[i]) {
case 1:
f[i] = firstFunction;
break;
case 2:
f[i] = secondFunction;
break;
case 3:
f[i] = thirdFunction;
break;
case 4:
f[i] = fourthFunction;
break;
}
++i;
}
printf("\r\nYour characters are: ");
for (i = 0; i < NUMBER_OF_NUMBER_WORDS; ++i) {
printf("%c", f[i]());
}
printf("\r\n");
//Prevent it from closing immediately (if you double-clicked it in Windows)
getchar();
return 0;
}
//Function implementations
const char firstFunction(void) {
register const DWORD n = MTGetNumber();
return LOWER_ALPHABET[n % ALPHABET_LENGTH]; //A random lower-case letter
}
const char secondFunction(void) {
register const DWORD n = MTGetNumber();
return UPPER_ALPHABET[(n % (ALPHABET_LENGTH / 2)) + (ALPHABET_LENGTH / 2)]; //A random capital letter from N-Z
}
const char thirdFunction(void) {
register const DWORD n = MTGetNumber();
return UPPER_ALPHABET[n % ALPHABET_LENGTH]; //A random capital letter
}
const char fourthFunction(void) {
register const DWORD n = MTGetNumber();
return UPPER_ALPHABET[n % (ALPHABET_LENGTH/2)]; //A random capital letter from A-M
}
//Mersenne-twister implementation stuff
void MTInit(const DWORD seed) {
register int i = 1;
MTIndex = 0;
*MT = seed;
for (; i < MTSIZE; ++i) {
MT[i] = 0xffffffffu & ((0x6C078965u * (MT[i - 1] ^ (MT[i - 1] >> 30))) + i);
}
}
const DWORD MTGetNumber(void) {
register DWORD n;
if (MTIndex == 0) {
MTGenerateNumbers();
}
n = MT[MTIndex];
n ^= n >> 11;
n ^= (n << 7) & 0x9d2c5680u;
n ^= (n << 15) & 0xefc60000u;
n ^= n >> 18;
MTIndex = (MTIndex + 1) % MTSIZE;
return n;
}
void MTGenerateNumbers(void) {
register int i = 0;
register DWORD n;
for (; i < MTSIZE; ++i) {
n = (MT[i] & 0x80000000u) + (MT[(i + 1) % MTSIZE] & 0x7fffffffu);
MT[i] = MT[(i + 397) % MTSIZE] ^ (n >> 1);
if (n % 2) {
MT[i] ^= 0x9908b0dfu;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment