Advertisement
Guest User

9 digits

a guest
Jan 26th, 2013
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.58 KB | None | 0 0
  1. /* Compile with:
  2.  * gcc -o lofasz -lgmp -O3 lofasz.c
  3.  *
  4.  * Run with:
  5.  * time ./lofasz 40
  6.  */
  7.  
  8. #include<stdio.h>
  9. #include<stdlib.h>
  10. #include<string.h>
  11. #include<gmp.h>
  12.  
  13. #define MAX_BASE 50
  14.  
  15. struct number_s {
  16.     mpz_t number;
  17.     char used[MAX_BASE];
  18.     struct number_s *next;
  19. };
  20. typedef struct number_s number_t;
  21.  
  22.  
  23. inline number_t* new_number () {
  24.     number_t *n = (number_t *) calloc(1, sizeof(number_t));
  25.     if (n) {
  26.         mpz_init(n->number);
  27.     }
  28.    
  29.     return n;
  30. }
  31.  
  32. inline void copy_used (number_t *to, number_t *from) {
  33.     if (from && to) {
  34.         memcpy(to->used, from->used, MAX_BASE);
  35.     }
  36. }
  37.  
  38. inline void destroy_number (number_t *n) {
  39.     if (n) {
  40.         mpz_clear(n->number);
  41.         free(n);
  42.     }
  43.     n = NULL;
  44. }
  45.  
  46. int main(int argc, char* argv[]) {
  47.     unsigned long int max_base, base, last, middle, cnt, o, d, l;
  48.     number_t *head, *head2, *cur, *cur2;
  49.     mpz_t new_num, new_num_base;
  50.     unsigned char eligible_digits[MAX_BASE * MAX_BASE];
  51.    
  52.     mpz_init(new_num);
  53.     mpz_init(new_num_base);
  54.    
  55.     printf("#base\ttries\tresults\n");
  56.    
  57.     if (argc > 1) {
  58.         int errno = 0;
  59.         max_base = (unsigned long int) strtol(argv[1], NULL, 10);
  60.         if (errno != 0) {
  61.             max_base = 36;
  62.         }
  63.         if (max_base > MAX_BASE - 1) {
  64.             max_base = MAX_BASE - 1;
  65.         }
  66.     }
  67.     else {
  68.         max_base = 36;
  69.     }
  70.    
  71.     for (base = 2; base <= max_base; base +=2) {
  72.         cnt = 0;
  73.         last = base - 1;
  74.         middle = base / 2;
  75.        
  76.         /* pre-compute table of eligible digits for this base */
  77.         for (l = 1; l <= middle; l++) {
  78.             if (base % l == 0) {
  79.                 for (o = 1; o <= last; o++) {
  80.                     for (d = 1; d <= last; d++) {
  81.                         if (d % l == 0 || o % l == 0) {
  82.                             eligible_digits[o*MAX_BASE + d] = (d % l == 0 && o % l == 0) ? 1 : 0;
  83.                         }
  84.                     }
  85.                 }
  86.             }
  87.         }
  88.        
  89.         /* initial list with the digits */
  90.         head = head2 = NULL;
  91.         for (d = last; d >= 1; d--) {
  92.             if (eligible_digits[1*MAX_BASE + d]) {
  93.                 cur = new_number();
  94.                 mpz_set_ui (cur->number, d);
  95.                 cur->used[d] = 1;
  96.                 cur->next = head;
  97.                 head = cur;
  98.             }
  99.         }
  100.        
  101.         for (o = 2; o <= last; o++) {
  102.             cur = head;
  103.             head2 = cur2 = NULL;
  104.             while (cur) {
  105.                 mpz_mul_ui(new_num_base, cur->number, base);
  106.                 for (d = 1; d <= last; d++) {
  107.                     if (!cur->used[d] && (eligible_digits[o*MAX_BASE + d])) {
  108.                         cnt++;
  109.                         mpz_add_ui(new_num, new_num_base, d);
  110.                        
  111.                         #ifdef DEBUG
  112.                         printf("%ld (%ld) ", cnt, o);
  113.                         mpz_out_str(stdout, base, cur->number);
  114.                         printf(" + %ld = ", d);
  115.                         mpz_out_str(stdout, base, new_num);
  116.                         printf(" [");
  117.                         for (l = 0; l <= last; l++) {
  118.                             printf("%c", cur->used[l] ? '*' : ' ');
  119.                         }
  120.                         printf("] ");
  121.                         #endif
  122.                         if (mpz_divisible_ui_p(new_num, o)) {
  123.                             #ifdef DEBUG
  124.                             printf("+");
  125.                             #endif
  126.                             number_t *temp = new_number();
  127.                             mpz_set(temp->number, new_num);
  128.                             copy_used(temp, cur);
  129.                             temp->used[d] = 1;
  130.                             if (head2) {
  131.                                 cur2->next  = temp;
  132.                                 cur2        = temp;
  133.                             }
  134.                             else {
  135.                                 head2 = cur2 = temp;
  136.                             }
  137.                         }
  138.                         #ifdef DEBUG
  139.                         printf("\n");
  140.                         #endif
  141.                     }
  142.                 }
  143.                 cur = cur->next;
  144.             }
  145.            
  146.             while (head) {
  147.                 number_t *next = head->next;
  148.                 destroy_number(head);
  149.                 head = next;
  150.             }
  151.             head = head2;
  152.         }
  153.        
  154.         printf("%ld\t%ld\t", base, cnt);
  155.         cur = head;
  156.         while (cur) {
  157.             mpz_out_str(stdout, base, cur->number);
  158.             printf(" ");
  159.             cur = cur->next;
  160.         }
  161.         printf("\n");
  162.         while (head) {
  163.             number_t *next = head->next;
  164.             destroy_number(head);
  165.             head = next;
  166.         }
  167.         memset(eligible_digits, 0, MAX_BASE*MAX_BASE);
  168.     }
  169.     mpz_clear(new_num);
  170.     mpz_clear(new_num_base);
  171.     return 0;
  172. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement