Co-authored-by: sigonasr2 <sigonasr2@gmail.com>
main
sigonasr2, Sig, Sigo 3 years ago committed by GitHub
parent bc9a7f5137
commit 15b49c4b3c
  1. BIN
      archives/23/current
  2. 63
      archives/23/src/main.c
  3. 140
      archives/23/src/utils.c
  4. 14
      archives/23/src/utils.h
  5. BIN
      current
  6. 134
      src/main.c

Binary file not shown.

@ -0,0 +1,63 @@
#include <stdio.h>
#include "utils.h"
#include <stdlib.h>
/*
A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.
A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.
As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.
Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.
https://projecteuler.net/problem=23
*/
int main(int argc,char**argv) {
//First find all abundant numbers.
//Then iterate through all abundant numbers and determine which numbers are made with them. Numbers not found are to be summed together.
int*abundantNumbers=malloc(sizeof(int)*0);
int abundantNumberCount=0;
for (int i=1;i<=28123;i++) {
int factorSum=1;
//Iterate through divisors.
int max=i/2;
for (int j=2;j<max;j++) {
if (i%j==0) {
factorSum+=j;
if (j!=i/j) {
factorSum+=i/j;
}
max=i/j;
}
}
if (factorSum>i) {
//printf("%d is abundant...\n",i);
abundantNumbers=realloc(abundantNumbers,sizeof(int)*(++abundantNumberCount));
abundantNumbers[abundantNumberCount-1]=i;
}
}
//Next is to sum up all integers up to 28124.
long sum=0;
for (int i=0;i<28124;i++) {
sum+=i;
}
printf("Sum of all numbers is %ld\n",sum);
boolean removed[28124] = {};
for (int i=0;i<abundantNumberCount;i++) {
for (int j=0;j<abundantNumberCount;j++) {
int su=abundantNumbers[i]+abundantNumbers[j];
if (su<28124&&!removed[su]) {
sum-=su;
removed[su]=true;
printf("Removed %d...\n",su);
}
}
}
printf("Sum of only non-summed abundant integers is %ld",sum);
return 0;
}

@ -0,0 +1,140 @@
#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("%s\n",sum.str);
}
if (sum.str[0]=='0') {
char*newStr=malloc(sum.length-1);
for (int i=1;i<sum.length;i++) {
newStr[i-1]=sum.str[i];
}
free(sum.str);
sum=(struct String){sum.length-1,newStr};
}
//printf("%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};
}

@ -0,0 +1,14 @@
#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);
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)

Binary file not shown.

@ -1,103 +1,63 @@
#include <stdio.h>
#include "utils.h"
#include <stdlib.h>
#include <string.h>
/*
Using names.txt (right click and 'Save Link/Target As...'), a 46K text file containing over five-thousand first names, begin by sorting it into alphabetical order. Then working out the alphabetical value for each name, multiply this value by its alphabetical position in the list to obtain a name score.
A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.
For example, when the list is sorted into alphabetical order, COLIN, which is worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name in the list. So, COLIN would obtain a score of 938 × 53 = 49714.
A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.
What is the total of all the name scores in the file?
As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.
https://projecteuler.net/problem=22
*/
Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.
int nameScore(int pos,char*str) {
int myScore=0;
int marker=0;
while (str[marker]!='\0') {
myScore+=str[marker]-'A'+1;
marker++;
}
return myScore*pos;
}
https://projecteuler.net/problem=23
*/
int main(int argc,char**argv) {
FILE*file = fopen("p022_names.txt","r");
int pointer=0;
int nameCount=0;
while (!feof(file)) {
if (fgetc(file)=='"') {
while (fgetc(file)!='"') {
}
nameCount++;
}
}
fseek(file,0,0);
char*names[nameCount];
int currentCount=0;
while (!feof(file)) {
if (fgetc(file)=='"') {
//Start reading the name.
char*newName=malloc(1);
char c=' ';
int length=1;
while ((c=fgetc(file))!='"') {
newName=realloc(newName,++length);
newName[length-2]=c;
newName[length-1]='\0';
}
if (currentCount<2) {
if (currentCount==1) {
if (strcmp(names[0],newName)<0) {
names[1]=newName;
} else {
names[1]=names[0];
names[0]=newName;
}
} else {
names[0]=newName;
}
} else {
int low=0;
int high=currentCount;
int pos=0;
int mid=low+(high-low)/2;
while (low<=high) {
mid=low+(high-low)/2;
if (mid>=currentCount) {
break;
}
int diff=strcmp(names[mid],newName);
if (diff<0) {
low=mid+1;
//printf("%s is after %s... New low:%d\n",newName,names[mid],low);
} else {
high=mid-1;
//printf("%s is before %s... New high:%d\n",newName,names[mid],high);
}
}
pos=low+(high-low)/2;
//printf("Position of %s is %d Count:%d.\n",newName,pos,currentCount);
if (pos==currentCount) {
names[currentCount]=newName;
} else {
for (int j=currentCount;j>=pos;j--) {
names[j]=names[j-1];
}
names[pos]=newName;
}
}
currentCount++;
//First find all abundant numbers.
//Then iterate through all abundant numbers and determine which numbers are made with them. Numbers not found are to be summed together.
int*abundantNumbers=malloc(sizeof(int)*0);
int abundantNumberCount=0;
for (int i=1;i<=28123;i++) {
int factorSum=1;
//Iterate through divisors.
int max=i/2;
for (int j=2;j<max;j++) {
if (i%j==0) {
factorSum+=j;
if (j!=i/j) {
factorSum+=i/j;
}
max=i/j;
}
}
if (factorSum>i) {
//printf("%d is abundant...\n",i);
abundantNumbers=realloc(abundantNumbers,sizeof(int)*(++abundantNumberCount));
abundantNumbers[abundantNumberCount-1]=i;
}
}
//Next is to sum up all integers up to 28124.
long sum=0;
for (int i=0;i<28124;i++) {
sum+=i;
}
printf("Sum of all numbers is %ld\n",sum);
boolean removed[28124] = {};
for (int i=0;i<abundantNumberCount;i++) {
for (int j=0;j<abundantNumberCount;j++) {
int su=abundantNumbers[i]+abundantNumbers[j];
if (su<28124&&!removed[su]) {
sum-=su;
removed[su]=true;
printf("Removed %d...\n",su);
}
}
long nameScores=0;
for (int i=0;i<nameCount;i++) {
//Assign scores.
nameScores+=nameScore(i+1,names[i]);
printf("%d - %s: %d\n",i+1,names[i],nameScore(i+1,names[i]));
}
printf("\nThe total score of all names is: %ld",nameScores);
printf("Sum of only non-summed abundant integers is %ld",sum);
return 0;
}
Loading…
Cancel
Save