Co-authored-by: sigonasr2 <sigonasr2@gmail.com>
This commit is contained in:
sigonasr2, Sig, Sigo 2022-08-01 18:34:07 +00:00
parent 581d26b018
commit 580310f429
6 changed files with 316 additions and 59 deletions

BIN
archives/33/current Executable file

Binary file not shown.

54
archives/33/src/main.c Normal file
View File

@ -0,0 +1,54 @@
#include <stdio.h>
#include "utils.h"
/*
The fraction 49/98 is a curious fraction, as an inexperienced mathematician in attempting to simplify it may incorrectly believe that 49/98 = 4/8, which is correct, is obtained by cancelling the 9s.
We shall consider fractions like, 30/50 = 3/5, to be trivial examples.
There are exactly four non-trivial examples of this type of fraction, less than one in value, and containing two digits in the numerator and denominator.
If the product of these four fractions is given in its lowest common terms, find the value of the denominator.
https://projecteuler.net/problem=33
*/
void getDigits(int numb,int*digits) {
int counter=0;
while (numb>0) {
int digit=numb%10;
numb/=10;
digits[counter++]=digit;
}
}
int main(int argc,char**argv) {
for (int numerator=10;numerator<=99;numerator++) {
for (int denominator=10;denominator<=99;denominator++) {
if (numerator%10==0&&denominator%10==0||numerator>=denominator) {
continue; //Skip trivials.
}
//There are 4 cases.
int numeratorDigits[2];
int denominatorDigits[2];
getDigits(numerator,numeratorDigits);
getDigits(denominator,denominatorDigits);
boolean works=false;
for (int i=0;i<=1;i++) {
for (int j=0;j<=1;j++) {
if (numeratorDigits[i]==denominatorDigits[j]) {
//Try new numbers with those digits removed.
int newNumb1 = numeratorDigits[!i];
int newNumb2 = denominatorDigits[!j];
if ((double)newNumb1/newNumb2==(double)numerator/denominator) {
printf("Curious Fraction: %d/%d -> %d/%d\n",numerator,denominator,newNumb1,newNumb2);
}
}
}
}
}
}
return 0;
}

207
archives/33/src/utils.c Normal file
View File

@ -0,0 +1,207 @@
#include "utils.h"
#include <stdio.h>
#include <stdlib.h>
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<n2.length;i++) {
for (int j=0;j<n1.length+1;j++) {
addends[i][j]=0;
}
}
for (int i=n2.length-1;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<n2.length;i++) {
char val[n1.length+1+i];
for (int j=0;j<n1.length+1+i;j++) {
val[j]='0';
}
for (int j=0;j<n1.length+1;j++) {
val[j]=addends[i][j]+'0';
}
sum=add((struct String){n1.length+1+i,val},sum);
//printf("\nAA:%s",sum.str);
}
if (sum.str[0]=='0') {
char*newStr=malloc(sum.length);
for (int i=1;i<sum.length+1;i++) {
newStr[i-1]=sum.str[i];
}
free(sum.str);
sum=(struct String){sum.length-1,newStr};
}
//printf("\nA:%s",sum.str);
return sum;
}
struct String add(struct String numb1, struct String numb2){
//printf("%s %s\n",numb1.str,numb2.str);
byte carryover=0;
int digitCount=0;
char*str = malloc(1);
//str[0]='\0';
if (numb1.length>=numb2.length) {
for (int offset=0;offset<numb1.length;offset++) {
str = realloc(str,++digitCount);
//printf("Digit count is now %d\n",digitCount);
if (numb2.length>offset) {
//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;offset<numb2.length;offset++) {
str = realloc(str,++digitCount);
//printf("Digit count is now %d\n",digitCount);
if (numb1.length>offset) {
//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<digitCount/2;i++) {
char c = str[i];
char c2 = str[digitCount-i-1];
str[digitCount-i-1]=c;
str[i]=c2;
}
str = realloc(str,digitCount+1);
str[digitCount]='\0';
struct String newStr = {digitCount,str};
return newStr;
}
void printLongDoubleArr(int a,int b,long doubleArr[a][b]) {
for (int i=0;i<a;i++) {
for (int j=0;j<b;j++) {
printf("%ld\t",doubleArr[i][j]);
}
printf("\n");
}
}
void printIntDoubleArr(int a,int b,int doubleArr[a][b]) {
for (int i=0;i<a;i++) {
for (int j=0;j<b;j++) {
printf("%d\t",doubleArr[i][j]);
}
printf("\n");
}
}
struct String createBigNumber(char*numb) {
int marker=0;
while (numb[marker++]!='\0');
return (struct String){marker-1,numb};
}
int*getFactors(int numb) {
int*factorList=malloc(sizeof(int)*1);
int factorListSize=2;
factorList[0]=1;
factorList[1]=numb;
int max=numb;
for (int i=2;i<max;i++) {
if (numb%i==0) {
factorList=realloc(factorList,sizeof(int)*++factorListSize);
factorList[factorListSize-1]=i;
if (numb/i!=i) {
factorList=realloc(factorList,sizeof(int)*++factorListSize);
factorList[factorListSize-1]=numb/i;
max=numb/i;
}
}
}
factorList=realloc(factorList,sizeof(int)*++factorListSize);
factorList[factorListSize-1]=0;
return factorList;
}
boolean isFactor(int*factorList,int numb) {
int counter=0;
while (factorList[counter]!=0) {
if (numb==factorList[counter]) {
return true;
}
counter++;
}
return false;
}
struct String BigPow(int numb1, int numb2) {
struct String sum = BigNumber(1);
char*newStr = malloc(0);
int strLength=0;
while (numb1>0) {
newStr=realloc(newStr,++strLength);
newStr[strLength-1]=(numb1%10)+'0';
numb1/=10;
}
for (int i=0;i<strLength/2;i++) {
char oldC=newStr[strLength-i-1];
newStr[strLength-i-1]=newStr[i];
newStr[i]=oldC;
}
struct String bigNumb2 = (struct String){strLength,newStr};
for (int i=0;i<numb2;i++) {
sum=mult(sum,bigNumb2);
}
free(newStr);
return sum;
}
boolean equals(struct String str1,struct String str2) {
if (str1.length!=str2.length) {
return false;
}
for (int i=0;i<str1.length;i++) {
if (str1.str[i]!=str2.str[i]) {
return false;
}
}
return true;
}

18
archives/33/src/utils.h Normal file
View File

@ -0,0 +1,18 @@
#define true 1
#define false 0
#define boolean char
#define byte char
struct String{
int length;
char*str;
};
struct String add(struct String numb1, struct String numb2);
struct String mult(struct String numb1, struct String numb2);
struct String BigPow(int numb1,int numb2);
void printLongDoubleArr(int a,int b,long doubleArr[a][b]);
void printIntDoubleArr(int a,int b,int doubleArr[a][b]);
struct String createBigNumber(char*numb);
#define BigNumber(X) createBigNumber(#X)
boolean isFactor(int*factorList,int numb);
int*getFactors(int numb);
boolean equals(struct String str1,struct String str2);

BIN
current

Binary file not shown.

View File

@ -1,76 +1,54 @@
#include <stdio.h>
#include "utils.h"
#include <stdlib.h>
/*
We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once; for example, the 5-digit number, 15234, is 1 through 5 pandigital.
The fraction 49/98 is a curious fraction, as an inexperienced mathematician in attempting to simplify it may incorrectly believe that 49/98 = 4/8, which is correct, is obtained by cancelling the 9s.
The product 7254 is unusual, as the identity, 39 × 186 = 7254, containing multiplicand, multiplier, and product is 1 through 9 pandigital.
We shall consider fractions like, 30/50 = 3/5, to be trivial examples.
Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through 9 pandigital.
There are exactly four non-trivial examples of this type of fraction, less than one in value, and containing two digits in the numerator and denominator.
HINT: Some products can be obtained in more than one way so be sure to only include it once in your sum.
If the product of these four fractions is given in its lowest common terms, find the value of the denominator.
https://projecteuler.net/problem=32
https://projecteuler.net/problem=33
*/
int main(int argc,char**argv) {
int numb1=1;
int numb2=1;
long sumPandigital=0;
boolean*uniqueProducts = malloc(100000000);
for (int i=0;i<100000000;i++) {
uniqueProducts[i]=false;
void getDigits(int numb,int*digits) {
int counter=0;
while (numb>0) {
int digit=numb%10;
numb/=10;
digits[counter++]=digit;
}
for (numb1=1;numb1<10000;numb1++) {
for (numb2=1;numb2<10000;numb2++) {
int prod=numb1*numb2;
int numb=prod;
boolean uniqueDigits[9] = {};
while (numb>0) {
int digit=numb%10-1;
if (digit!=-1&&!uniqueDigits[digit]) {
uniqueDigits[digit]=true;
} else {
goto skip;
}
numb/=10;
}
int main(int argc,char**argv) {
for (int numerator=10;numerator<=99;numerator++) {
for (int denominator=10;denominator<=99;denominator++) {
if (numerator%10==0&&denominator%10==0||numerator>=denominator) {
continue; //Skip trivials.
}
numb=numb1;
while (numb>0) {
int digit=numb%10-1;
if (digit!=-1&&!uniqueDigits[digit]) {
uniqueDigits[digit]=true;
} else {
goto skip;
}
numb/=10;
}
numb=numb2;
while (numb>0) {
int digit=numb%10-1;
if (digit!=-1&&!uniqueDigits[digit]) {
uniqueDigits[digit]=true;
} else {
goto skip;
}
numb/=10;
}
for (int i=0;i<9;i++) {
if (!uniqueDigits[i]) {
goto skip;
//There are 4 cases.
int numeratorDigits[2];
int denominatorDigits[2];
getDigits(numerator,numeratorDigits);
getDigits(denominator,denominatorDigits);
boolean works=false;
for (int i=0;i<=1;i++) {
for (int j=0;j<=1;j++) {
if (numeratorDigits[i]==denominatorDigits[j]) {
//Try new numbers with those digits removed.
int newNumb1 = numeratorDigits[!i];
int newNumb2 = denominatorDigits[!j];
if ((double)newNumb1/newNumb2==(double)numerator/denominator) {
printf("Curious Fraction: %d/%d -> %d/%d\n",numerator,denominator,newNumb1,newNumb2);
}
}
}
}
//If we got here it's a pandigital.
if (!uniqueProducts[prod]) {
uniqueProducts[prod]=true;
sumPandigital+=prod;
printf("\n%d*%d = %d is pandigital!",numb1,numb2,prod);
}
skip:
continue;
}
}
printf("\nSum of pandigitals: %ld",sumPandigital);
return 0;
}
}