diff --git a/archives/24/current b/archives/24/current new file mode 100755 index 0000000..dcd9474 Binary files /dev/null and b/archives/24/current differ diff --git a/archives/24/src/main.c b/archives/24/src/main.c new file mode 100644 index 0000000..d4ed085 --- /dev/null +++ b/archives/24/src/main.c @@ -0,0 +1,79 @@ +#include +#include "utils.h" + +/* + A permutation is an ordered arrangement of objects. For example, 3124 is one possible permutation of the digits 1, 2, 3 and 4. If all of the permutations are listed numerically or alphabetically, we call it lexicographic order. The lexicographic permutations of 0, 1 and 2 are: + + 012 021 102 120 201 210 + + What is the millionth lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9? + + https://projecteuler.net/problem=24 +*/ + +void carryover(int*arr,int digit) { + arr[digit]=0; + if (arr[digit-1]==9) { + carryover(arr,digit-1); + } else { + arr[digit-1]++; + } +} + +void incrementDigit(int*arr) { + int val = arr[9]; + if (arr[9]==9) { + carryover(arr,9); + } else { + arr[9]++; + } +} + +boolean allUniqueDigits(int*arr) { + boolean digits[10] = {}; + for (int i=0;i<10;i++) { + if (!digits[arr[i]]) { + digits[arr[i]]=true; + } else { + return false; + } + } + return true; +} + +int factorial(int numb) { + int final=1; + for (int i=numb;i>=1;i--) { + final*=i; + } + return final; +} + +int main(int argc,char**argv) { + + //For permutations, we know that there are a total of N! permutations. + // Which means each individual set starts at N!/N. So we can skip ahead some permutations. + // For 10 numbers, we get 362,880 values per permutation set. So 1000000/362880 = 2. So we'll start at permutation two. + int setPermutationCount=factorial(10)/10; + int permutationCount=(1000000/setPermutationCount)*setPermutationCount; + int digits[10]={2,0,1,3,4,5,6,7,8,9}; + while ((digits[0]!=9||digits[1]!=8||digits[2]!=7||digits[3]!=6||digits[4]!=5||digits[5]!=4||digits[6]!=3||digits[7]!=2||digits[8]!=1||digits[9]!=0)&&permutationCount!=999999) { + incrementDigit(digits); + if (allUniqueDigits(digits)) { + permutationCount++; + printf("%d:",permutationCount); + for (int i=0;i<10;i++) { + printf(" %d ",digits[i]); + } + printf("\n"); + } + } + + printf("\n\nThe one millionth lexicographic permutation is: \n\t"); + for (int i=0;i<10;i++) { + printf("%d",digits[i]); + } + + + return 0; +} \ No newline at end of file diff --git a/archives/24/src/utils.c b/archives/24/src/utils.c new file mode 100644 index 0000000..715c599 --- /dev/null +++ b/archives/24/src/utils.c @@ -0,0 +1,140 @@ +#include "utils.h" +#include +#include + +struct String mult(struct String numb1, struct String numb2) { + struct String n1 = numb1; + struct String n2 = numb2; + byte carryover = 0; + if (numb2.length>numb1.length) { + n1=numb2; + n2=numb1; + } + int addends[n2.length][n1.length+1]; + for (int i=0;i=0;i--) { + carryover=0; + for (int j=n1.length-1;j>=0;j--) { + int mult = (n1.str[j]-'0')*(n2.str[i]-'0')+((carryover!=0)?carryover:0); + //printf(" %d/%d\n",mult,carryover); + carryover=0; + if (mult>=10) { + carryover=mult/10; + mult=mult%10; + } + addends[(n2.length-1)-i][j+1]=mult; + } + if (carryover>0) { + addends[(n2.length-1)-i][0]=carryover; + } + } + //printIntDoubleArr(n2.length,n1.length+1,addends); + struct String sum = {1,"0"}; + for (int i=0;i=numb2.length) { + for (int offset=0;offsetoffset) { + //printf("%c %c\n",numb1.str[numb1.length-offset-1],numb2.str[numb2.length-offset-1]); + int sum=((numb1.str[numb1.length-offset-1]-'0')+(numb2.str[numb2.length-offset-1]-'0'))+((carryover>0)?carryover--:0); + if (sum>=10) { + carryover=1; + sum-=10; + } + str[offset]=sum+'0'; + } else { + str[offset]=numb1.str[numb1.length-offset-1]+((carryover>0)?carryover--:0); + } + //str[offset+1]='\0'; + } + } else { + for (int offset=0;offsetoffset) { + //printf("%c %c\n",numb1.str[numb1.length-offset-1],numb2.str[numb2.length-offset-1]); + int sum=((numb1.str[numb1.length-offset-1]-'0')+(numb2.str[numb2.length-offset-1]-'0'))+((carryover>0)?carryover--:0); + if (sum>=10) { + carryover=1; + sum-=10; + } + str[offset]=sum+'0'; + } else { + str[offset]=numb2.str[numb2.length-offset-1]+((carryover>0)?carryover--:0); + } + //str[offset+1]='\0'; + } + } + if (carryover>0) { + str = realloc(str,++digitCount); + str[digitCount-1]='1'; + //str[digitCount]='\0'; + } + for (int i=0;i=1;i--) { + final*=i; } + return final; } int main(int argc,char**argv) { - //X * (2^(X-2)) - //0 - //01 - //02 - //03 - //04 - //05 - //06 - //07 - //08 - //09 - //10 - //123 - //124 - //20 - //21 - //3 - //4 - //5 - //6 - //7 - //8 - //9 - - boolean useNextHighest=true; //If this is true, use the next consecutive digit, otherwise skip one. - int*numbs=malloc(sizeof(int)*0); - generate(numbs,count,true); + + //For permutations, we know that there are a total of N! permutations. + // Which means each individual set starts at N!/N. So we can skip ahead some permutations. + // For 10 numbers, we get 362,880 values per permutation set. So 1000000/362880 = 2. So we'll start at permutation two. + int setPermutationCount=factorial(10)/10; + int permutationCount=(1000000/setPermutationCount)*setPermutationCount; + int digits[10]={2,0,1,3,4,5,6,7,8,9}; + while ((digits[0]!=9||digits[1]!=8||digits[2]!=7||digits[3]!=6||digits[4]!=5||digits[5]!=4||digits[6]!=3||digits[7]!=2||digits[8]!=1||digits[9]!=0)&&permutationCount!=999999) { + incrementDigit(digits); + if (allUniqueDigits(digits)) { + permutationCount++; + printf("%d:",permutationCount); + for (int i=0;i<10;i++) { + printf(" %d ",digits[i]); + } + printf("\n"); + } + } + + printf("\n\nThe one millionth lexicographic permutation is: \n\t"); + for (int i=0;i<10;i++) { + printf("%d",digits[i]); + } return 0;