Co-authored-by: sigonasr2 <sigonasr2@gmail.com>
main
sigonasr2, Sig, Sigo 2 years ago
parent 581d26b018
commit 580310f429
  1. BIN
      archives/33/current
  2. 54
      archives/33/src/main.c
  3. 207
      archives/33/src/utils.c
  4. 18
      archives/33/src/utils.h
  5. BIN
      current
  6. 96
      src/main.c

Binary file not shown.

@ -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;
}

@ -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;
}

@ -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);

Binary file not shown.

@ -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;
}
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;
}
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.
}
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;
}
}
Loading…
Cancel
Save