summaryrefslogtreecommitdiff
path: root/markov.c
blob: 39dbc928d5d68e48f34c6b74bfadc4eeeb636d35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>
#include <sysexits.h>

static struct {
	int n;
	int *cs;
} patterns[256] = {0};

static uint32_t hash(char *s) {
	unsigned int h = 0x811c9dc5;
	for (size_t i = 0; s[i] != '\0'; i++) {
		h *= 0x01000193;
		h = h ^ s[i];
	}
	return h;
}

int main(int argc, char *argv[]) {
	if (argc > 1) {
		if (argc > 2) {
			fprintf(stderr, "usage: %s [seed]\n", argv[0]);
			return EX_USAGE;
		}
		srand(hash(argv[1]));
	} else srand(time(NULL));

	int c;
	int prev = getchar();
	int p = prev;
	while (prev != EOF) {
		c = getchar();
		prev = (unsigned char) prev;
		patterns[prev].n++;
		patterns[prev].cs =
			realloc(patterns[prev].cs, patterns[prev].n * sizeof(int));
		if (!patterns[prev].cs) perror(argv[0]);
		patterns[prev].cs[patterns[prev].n - 1] = c;
		prev = c;
	} 

	while (p != EOF && patterns[p].n != 0) {
		p = (unsigned char) p;
		putchar(p);
		p = patterns[p].cs[rand() % patterns[p].n];
	}
	return 0;
}