Advertisement
m1o2

m1o2 - Permutation - Project Euler 24 projecteuler24

Aug 19th, 2011
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.68 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <conio.h>
  4. #include <string.h>
  5.  
  6. #define WaitForResponse { fprintf(stdout,"\n\n Press any key to continue..."); flushall(); getch(); }
  7. #define ErrorMsg( msg ) { fprintf(stderr,"\n\n Error: %s\n",(msg)); fflush(stdout); }
  8. #define PointerAssert( pointer ) { if( (pointer)==NULL){ ErrorMsg("Insufficient Memory"); WaitForResponse; exit(1); }  }
  9. #define IntAtIndex( arr, index ) *((int*)(arr)+(index) )
  10.  
  11. typedef unsigned long long int Gigantic;
  12. typedef enum { False, True } Bool;
  13. typedef enum { Reverse = -1, Normal = 1 } IteratorMode;
  14.  
  15. typedef struct Arr{
  16.     void* arr;
  17.     Gigantic length;
  18.     Gigantic top;
  19. }Arr,*Array;
  20.  
  21. Array newArray(void* arr, Gigantic length, Gigantic top);
  22. Array permutation_n(Array arr, Gigantic n);
  23. void print_array_int(Array arr);
  24. void print_all_permutations(Array arr);
  25. Gigantic factorial( Gigantic n );
  26. Gigantic next_index( Array arr, Gigantic n, IteratorMode mode );
  27. Array reverse_int( Array arr, Array indexer );
  28. void copy_array_int( void* dest, void* source );
  29.  
  30.  
  31. int main(){
  32.  
  33.  
  34.     int a[] = {0,1,2,3,4,5,6,7,8,9};
  35.     Array arr = newArray(a,10,9);
  36.  
  37.     //Array p = permutation_n(arr, 1000000 );
  38.  
  39.     //print_array_int( p );
  40.    
  41.     //print_all_permutations( arr );
  42.     Array p = permutation_n(arr, 123456 );
  43.     print_array_int( p );
  44.  
  45.     free( p->arr);
  46.     free( p );
  47.  
  48. free( arr );
  49.  
  50. WaitForResponse;
  51. return 0;
  52. }
  53.  
  54.  
  55.  
  56. Array permutation_n(Array arr, Gigantic n){
  57.  
  58.     Array temp = newArray(calloc(arr->top+1,sizeof(int)),arr->top+1,arr->top);
  59.     Array permutation = newArray(calloc(arr->top+1,sizeof(int)),arr->length,arr->top);
  60.     Gigantic index;
  61.  
  62.     PointerAssert( temp->arr );
  63.  
  64.     for( index = 1; n >= 1 ; ++index ){
  65.  
  66.         Gigantic fact = factorial(arr->top-(index-1));
  67.         Gigantic div;
  68.         Gigantic mod;
  69.  
  70.         div = n / fact;
  71.         mod = n % fact;
  72.  
  73.         if( mod == 0 ){
  74.             Gigantic tempIndex = next_index(temp,div,Normal);
  75.             Array reversed;
  76.  
  77.             IntAtIndex(permutation->arr,index-1) = IntAtIndex(arr->arr, tempIndex );
  78.             IntAtIndex(temp->arr,tempIndex) = 1;
  79.  
  80.             reversed = reverse_int(arr,temp);
  81.             copy_array_int((((int*)permutation->arr)+index),reversed->arr,reversed->length);
  82.  
  83.             free( reversed );
  84.  
  85.             return permutation;
  86.         }
  87.         else if( fact == 1 ){
  88.  
  89.             Gigantic nextIndex = next_index(temp, 1, Normal ),test1;
  90.  
  91.             test1 = IntAtIndex(arr->arr,nextIndex);
  92.             IntAtIndex(permutation->arr,index-1) = IntAtIndex(arr->arr,nextIndex);
  93.             IntAtIndex(temp->arr,nextIndex) = 1;
  94.  
  95.             nextIndex = next_index(temp, 1, Normal );
  96.             test1 = IntAtIndex(arr->arr,nextIndex);
  97.             IntAtIndex(permutation->arr, index-1) = IntAtIndex(arr->arr, nextIndex);
  98.             IntAtIndex(temp->arr,nextIndex) = 1;
  99.  
  100.  
  101.  
  102.             return permutation;
  103.         }
  104.         else{
  105.             Gigantic tempIndex = next_index(temp, div+1, Normal );
  106.             n = mod;
  107.  
  108.             IntAtIndex(permutation->arr,index-1) = IntAtIndex(arr->arr, tempIndex);
  109.  
  110.             IntAtIndex(temp->arr, tempIndex) = 1;
  111.  
  112.         }
  113.     }
  114.  
  115.     free( temp->arr );
  116.     free( temp );
  117.  
  118.     return permutation;
  119. }
  120.  
  121. Gigantic next_index( Array arr, Gigantic n, IteratorMode mode ){    ///
  122.     Gigantic index = (( mode == Normal )?(0):(arr->top)),counter = 0;
  123.     Gigantic till = 0;
  124.  
  125.     for( ; till <= arr->top && counter < n; index += mode , ++till )
  126.         if( IntAtIndex( arr->arr, index ) == 0 && ++counter == n )
  127.             return index;
  128.  
  129.     return -1;
  130. }
  131.  
  132. Array reverse_int( Array arr, Array indexer ){ //
  133.  
  134.     Gigantic count, index,temp;
  135.     Array newArr;
  136.  
  137.     for(index = count = 0; index <= arr->top; ++index)
  138.         if( IntAtIndex(indexer->arr, index ) == 0 )
  139.             ++count;
  140.  
  141.     newArr = newArray(malloc(sizeof(count)),count,count-1);
  142.  
  143.     for( index = temp = 0; temp < count; ++index )
  144.         if( IntAtIndex(indexer->arr, arr->top-index) == 0 ){
  145.             IntAtIndex(newArr->arr,temp) = IntAtIndex(arr->arr, arr->top-index);
  146.             ++temp;
  147.         }
  148.    
  149.     return newArr;
  150. }
  151.  
  152. void copy_array_int( void* dest, void* source,  Gigantic length){  //
  153.  
  154.     while( length-- > 0 )
  155.         IntAtIndex( dest,length ) = IntAtIndex( source, length );
  156.        
  157. }
  158.  
  159. Array newArray(void* arr, Gigantic length, Gigantic top){ //
  160.  
  161.     Array newArr = (Array)malloc(sizeof(Arr));
  162.     PointerAssert( newArray );
  163.  
  164.     newArr->arr = (int*)arr;
  165.     newArr->length = length;
  166.     newArr->top = top;
  167.  
  168.     return newArr;
  169. }
  170.  
  171.  
  172. void print_array_int(Array arr){  //
  173.  
  174.     Gigantic index;
  175.  
  176.     for( index = 0; index <= arr->top; ++index)
  177.         fprintf(stdout,"%d",IntAtIndex(arr->arr,index) );
  178.    
  179. }
  180.  
  181. void print_all_permutations(Array arr){
  182.     Gigantic index,fact = factorial(arr->top+1);
  183.  
  184.     for( index = 1; index <= fact; ++index){
  185.         Array temp = permutation_n(arr,index);
  186.         print_array_int( temp );
  187.         putchar('\n');
  188.         free( temp );
  189.     }
  190. }
  191.  
  192. Gigantic factorial( Gigantic n ){  //
  193.     Gigantic result = 1,index=0;
  194.  
  195.     for( ; n > 1; ++index)
  196.         result *= n--;
  197.  
  198.     return result;
  199. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement