#include #include #include #include #include // These values are used to print the progress mpz_t poss; mpz_t curr; // Checks a string to see if it's valid brainfuck // Note: All you really need to do is check if ['s and ]'s cancel one another out // and that no ] appears before a matching [ int valid_bf(int *bf) { int loop = 0; while (*bf != -1) { if (*bf == 6) loop++; else if (*bf == 7) { if (loop == 0) return 0; loop--; } bf++; } return !loop; } // Converts an array of ints to a string (actual brainfuck) // Note: not used. char *createbf(int len, int *nums) { static const char bfchars[] = { ',', '.', '+', '-', '<', '>', '[', ']' }; char *ret = calloc(len+1, sizeof(char)); int i; for (i = 0; nums[i] != -1; i++) { ret[i] = bfchars[nums[i]]; } return ret; } // Increases the number. Basically, we're using a base 8 number to represent brainfuck. void incr(int *nums) { if (*nums == -1) { return; } else { *nums += 1; if (*nums == 8) { *nums = 0; incr(nums+1); } } } // Actually generate and test every possible brainfuck program (brute-force) mpz_t *howmany(int num) { int *bla = calloc(num+1, sizeof(int)); int *bla2 = calloc(num+1, sizeof(int)); bla[num] = -1; bla2[num] = -1; mpz_t *retval = malloc(sizeof(mpz_t)); mpz_init(*retval); int i; for (i = 0; i < num; i++) { bla2[i] = 7; } while (1) { mpz_add_ui(curr, curr, 1); if (valid_bf(bla)) mpz_add_ui(*retval, *retval, 1); if (!memcmp(bla,bla2,num*sizeof(int))) { break; } incr(bla); } return retval; } // Signal handler for SIGUSR1 // Prints the progress that has been made thus far void sigusr1(int signal) { printf("\n"); mpz_out_str(NULL, 10, curr); printf("/"); mpz_out_str(NULL, 10, poss); printf("--->"); mpz_t bla; mpz_init(bla); mpz_mul_ui(bla, curr, 100); mpz_tdiv_q(bla, bla, poss); mpz_out_str(NULL, 10, bla); mpz_clear(bla); printf("%%"); printf("\n"); } int main(int argc, char **argv) { mpz_init(poss); mpz_init(curr); signal(SIGUSR1, sigusr1); int i; if (argc != 2) { return 0; } sscanf(argv[1], "%d", &i); mpz_ui_pow_ui(poss, 8, i); mpz_t *bla = howmany(i); printf("Possible brainfuck programs with a length of %d: ", i); mpz_out_str(stdout, 10, *bla); printf("\n"); mpz_clear(*bla); return 0; }