Co-authored-by: sigonasr2 <sigonasr2@gmail.com>
main
sigonasr2, Sig, Sigo 2 years ago
parent 7e113d0340
commit 581d26b018
  1. BIN
      archives/32/current
  2. 76
      archives/32/src/main.c
  3. 207
      archives/32/src/utils.c
  4. 18
      archives/32/src/utils.h
  5. BIN
      current
  6. 145
      src/main.c

Binary file not shown.

@ -0,0 +1,76 @@
#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 product 7254 is unusual, as the identity, 39 × 186 = 7254, containing multiplicand, multiplier, and product is 1 through 9 pandigital.
Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through 9 pandigital.
HINT: Some products can be obtained in more than one way so be sure to only include it once in your sum.
https://projecteuler.net/problem=32
*/
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;
}
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;
}
for (int i=0;i<9;i++) {
if (!uniqueDigits[i]) {
goto skip;
}
}
//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;
}

@ -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,99 +1,76 @@
#include <stdio.h> #include <stdio.h>
#include "utils.h" #include "utils.h"
#include <stdlib.h>
/* /*
In the United Kingdom the currency is made up of pound (£) and pence (p). There are eight coins in general circulation: 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.
1p, 2p, 5p, 10p, 20p, 50p, £1 (100p), and £2 (200p). The product 7254 is unusual, as the identity, 39 × 186 = 7254, containing multiplicand, multiplier, and product is 1 through 9 pandigital.
It is possible to make £2 in the following way: Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through 9 pandigital.
1×£1 + 1×50p + 2×20p + 1×5p + 1×2p + 3×1p HINT: Some products can be obtained in more than one way so be sure to only include it once in your sum.
How many different ways can £2 be made using any number of coins? https://projecteuler.net/problem=32
https://projecteuler.net/problem=31
*/ */
enum Currency{
pence1,
pence2,
pence5,
pence10,
pence20,
pence50,
pound1, //100 pences
pound2, //200 pences
};
int getValue(enum Currency cur) {
switch (cur) {
case pence1:{
return 1;
}break;
case pence2:{
return 2;
}break;
case pence5:{
return 5;
}break;
case pence10:{
return 10;
}break;
case pence20:{
return 20;
}break;
case pence50:{
return 50;
}break;
case pound1:{
return 100;
}break;
case pound2:{
return 200;
}break;
}
}
int total(int*amts) {
return
getValue(pence1)*amts[0]+
getValue(pence2)*amts[1]+
getValue(pence5)*amts[2]+
getValue(pence10)*amts[3]+
getValue(pence20)*amts[4]+
getValue(pence50)*amts[5]+
getValue(pound1)*amts[6]+
getValue(pound2)*amts[7];
}
void carryover(int*amts,int placeVal) {
amts[placeVal]++;
if (placeVal<7&&amts[placeVal]>200/getValue(placeVal)) {
carryover(amts,placeVal+1);
amts[placeVal]=0;
}
}
int main(int argc,char**argv) { int main(int argc,char**argv) {
int currencyAmts[8] = {}; int numb1=1;
int combinationCount=0; int numb2=1;
int maxCurrencyVal=200; long sumPandigital=0;
int currentMarker=0; boolean*uniqueProducts = malloc(100000000);
for (int i=0;i<100000000;i++) {
while (currencyAmts[6]!=2) { uniqueProducts[i]=false;
if (total(currencyAmts)==200) { }
printf("Coin amts: "); for (numb1=1;numb1<10000;numb1++) {
for (int i=0;i<8;i++) { for (numb2=1;numb2<10000;numb2++) {
printf("%d ",currencyAmts[i]); 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;
} }
printf("\n"); numb=numb2;
combinationCount++; 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;
}
}
//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;
} }
carryover(currencyAmts,0);
} }
printf("\n\nCombination count: %d",(combinationCount+2)); printf("\nSum of pandigitals: %ld",sumPandigital);
return 0; return 0;
} }

Loading…
Cancel
Save