Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <stdio.h>
- #include <stdint.h>
- #include <ctype.h>
- #include <omp.h>
- #define BITS (1u << 20)
- #define MAX (BITS * 8)
- #define LEN 14
- static int64_t eval(const char *str, int n)
- {
- const char *end = str + n;
- int64_t res = 0;
- int op= '+';
- while (str < end) {
- int64_t x = 0;
- while (str < end && isdigit(*str)) {
- x = x * 10 + *str++ - '0';
- }
- switch (op) {
- case '+': res += x; break;
- case '-': res -= x; break;
- case '*': res *= x; break;
- case '/': if (x == 0) return -1;
- if (res % x) return -1;
- res /= x; break;
- }
- if (res == 0) return -1;
- op = *str++;
- }
- if (res < 0 || res >= MAX) return -1;
- return res;
- }
- static void swap(char *str, int i, int j)
- {
- char s = str[i]; str[i] = str[j]; str[j] = s;
- }
- static void permute(char *str, int n, uint8_t *set)
- {
- int op = !isdigit(str[n - 1]);
- int i;
- if (!op) {
- int64_t e = eval(str, n);
- if (e >= 0) {
- int m = e / 8;
- int j = e % 8;
- if ((set[m] & (1u << j)) == 0) {
- if (0 && n < 5000000) printf("%ld == %.*s\n", e, n, str);
- set[m] |= (1u << j);
- }
- }
- }
- for (i = n; i < LEN; i++) {
- if (!op || isdigit(str[i])) {
- if (op && str[i] == '0') continue;
- swap(str, i, n);
- permute(str, n + 1, set);
- swap(str, i, n);
- }
- }
- }
- int main(void)
- {
- int mthread = omp_get_max_threads();
- uint8_t *set[mthread];
- int m = 0;
- int i;
- fprintf(stderr, "Maximum number of threads: %d\n", mthread);
- for (i = 0; i < mthread; i++) set[i] = NULL;
- #pragma omp parallel
- {
- int nthread = omp_get_num_threads();
- int ithread = omp_get_thread_num();
- int n;
- set[ithread] = calloc(1, BITS);
- set[ithread][0] = 1;
- #pragma omp for
- for (n = 0; n < 9 * 13; n++) {
- char pool[] = "0123456789+-*/";
- swap(pool, 0, 1 + n / 13);
- swap(pool, 1, 1 + n % 13);
- fprintf(stderr,
- "Exploring %c%c... on thread %d/%d.\n",
- pool[0], pool[1], ithread, nthread);
- permute(pool, 2, set[ithread]);
- }
- }
- {
- int nthread = 0;
- while (nthread < mthread && set[nthread]) nthread++;
- for (i = 0; i < BITS; i++) {
- uint8_t mask = 0u;
- int k;
- for (k = 0; k < nthread; k++) {
- mask |= set[k][i];
- }
- for (k = 0; k < 8; k++) {
- if ((mask & (1u << k)) == 0) {
- printf("%d\n", m);
- }
- m++;
- }
- if (m >= 5000000) break;
- }
- for (i = 0; i < nthread; i++) free(set[i]);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement