Add more solutions
Added solutions for problems 76, 77, 78, 79 and 80 in C and python.
This commit is contained in:
50
C/keylog.txt
Normal file
50
C/keylog.txt
Normal file
@ -0,0 +1,50 @@
|
||||
319
|
||||
680
|
||||
180
|
||||
690
|
||||
129
|
||||
620
|
||||
762
|
||||
689
|
||||
762
|
||||
318
|
||||
368
|
||||
710
|
||||
720
|
||||
710
|
||||
629
|
||||
168
|
||||
160
|
||||
689
|
||||
716
|
||||
731
|
||||
736
|
||||
729
|
||||
316
|
||||
729
|
||||
729
|
||||
710
|
||||
769
|
||||
290
|
||||
719
|
||||
680
|
||||
318
|
||||
389
|
||||
162
|
||||
289
|
||||
162
|
||||
718
|
||||
729
|
||||
319
|
||||
790
|
||||
680
|
||||
890
|
||||
362
|
||||
319
|
||||
760
|
||||
316
|
||||
729
|
||||
380
|
||||
319
|
||||
728
|
||||
716
|
6
C/p076.c
6
C/p076.c
@ -6,8 +6,8 @@
|
||||
* 2 + 2 + 1
|
||||
* 2 + 1 + 1 + 1
|
||||
* 1 + 1 + 1 + 1 + 1
|
||||
|
||||
How many different ways can one hundred be written as a sum of at least two positive integers?*/
|
||||
*
|
||||
* How many different ways can one hundred be written as a sum of at least two positive integers?*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -32,7 +32,7 @@ int main(int argc, char **argv)
|
||||
/* The number of ways a number can be written as a sum is given by the partition function
|
||||
* (-1 because the partition function includes also the number itself).
|
||||
* The function is implemented in projecteuler.c*/
|
||||
n = partition_fn(100, partitions) - 1;
|
||||
n = partition_fn(100, partitions, -1) - 1;
|
||||
|
||||
free(partitions);
|
||||
|
||||
|
83
C/p077.c
Normal file
83
C/p077.c
Normal file
@ -0,0 +1,83 @@
|
||||
/* It is possible to write ten as the sum of primes in exactly five different ways:
|
||||
*
|
||||
* 7 + 3
|
||||
* 5 + 5
|
||||
* 5 + 3 + 2
|
||||
* 3 + 3 + 2 + 2
|
||||
* 2 + 2 + 2 + 2 + 2
|
||||
*
|
||||
* What is the first value which can be written as the sum of primes in over five thousand different ways?*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include "projecteuler.h"
|
||||
|
||||
int count(int value, int n, int i, int target);
|
||||
|
||||
int primes[100];
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i, j, n;
|
||||
double elapsed;
|
||||
struct timespec start, end;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||
|
||||
/* Generate a list of the first 100 primes.*/
|
||||
for(i = 0, j = 0; j < 100; i++)
|
||||
{
|
||||
if(is_prime(i))
|
||||
{
|
||||
primes[j++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
i = 1;
|
||||
|
||||
/* Use a function to count the number of prime partitions for
|
||||
* each number >= 2 until the one that can be written in over
|
||||
* 5000 ways is found.*/
|
||||
while((n = count(0, 0, 0, ++i)) <= 5000);
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &end);
|
||||
|
||||
elapsed = (end.tv_sec - start.tv_sec) + (double)(end.tv_nsec - start.tv_nsec) / 1000000000;
|
||||
|
||||
printf("Project Euler, Problem 77\n");
|
||||
printf("Answer: %d\n", i);
|
||||
|
||||
printf("Elapsed time: %.9lf seconds\n", elapsed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Function using a simple recursive brute force approach
|
||||
* to find all the partitions.*/
|
||||
int count(int value, int n, int i, int target)
|
||||
{
|
||||
int j;
|
||||
|
||||
for(j = i; j < 100; j++)
|
||||
{
|
||||
value += primes[j];
|
||||
|
||||
if(value == target)
|
||||
{
|
||||
return n + 1;
|
||||
}
|
||||
else if(value > target)
|
||||
{
|
||||
return n;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = count(value, n, j, target);
|
||||
value -= primes[j];
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
44
C/p078.c
Normal file
44
C/p078.c
Normal file
@ -0,0 +1,44 @@
|
||||
/* Let p(n) represent the number of different ways in which n coins can be separated into piles.
|
||||
* For example, five coins can be separated into piles in exactly seven different ways, so p(5)=7.
|
||||
*
|
||||
* OOOOO
|
||||
* OOOO O
|
||||
* OOO OO
|
||||
* OOO O O
|
||||
* OO OO O
|
||||
* OO O O O
|
||||
* O O O O O
|
||||
*
|
||||
* Find the least value of n for which p(n) is divisible by one million.*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "projecteuler.h"
|
||||
|
||||
#define N 1000000
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i = -1;
|
||||
long int partitions[N] = {0};
|
||||
double elapsed;
|
||||
struct timespec start, end;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||
|
||||
/* Using the partition function to calculate the number of partitions,
|
||||
* giving the result modulo N.*/
|
||||
while(partition_fn(++i, partitions, N) != 0);
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &end);
|
||||
|
||||
elapsed = (end.tv_sec - start.tv_sec) + (double)(end.tv_nsec - start.tv_nsec) / 1000000000;
|
||||
|
||||
printf("Project Euler, Problem 78\n");
|
||||
printf("Answer: %d\n", i);
|
||||
|
||||
printf("Elapsed time: %.9lf seconds\n", elapsed);
|
||||
|
||||
return 0;
|
||||
}
|
189
C/p079.c
Normal file
189
C/p079.c
Normal file
@ -0,0 +1,189 @@
|
||||
/* A common security method used for online banking is to ask the user for three random characters from a passcode.
|
||||
* For example, if the passcode was 531278, they may ask for the 2nd, 3rd, and 5th characters; the expected reply would be: 317.
|
||||
*
|
||||
* The text file, keylog.txt, contains fifty successful login attempts.
|
||||
*
|
||||
* Given that the three characters are always asked for in order, analyse the file so as to determine the shortest possible
|
||||
* secret passcode of unknown length.*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "projecteuler.h"
|
||||
|
||||
int compare(void *a, void *b);
|
||||
int check_passcode(int **passcode, int len, int **logins, int n);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i, j, keylog, len = 4, found = 0, digits[10] = {0}, passcode_digits[10] = {0}, **passcode, **logins;
|
||||
char line[5];
|
||||
FILE *fp;
|
||||
double elapsed;
|
||||
struct timespec start, end;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||
|
||||
if((fp = fopen("keylog.txt", "r")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error while opening file %s\n", "keylog.txt");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if((logins = (int **)malloc(50*sizeof(int*))) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error while allocating memory\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for(i = 0; i < 50; i++)
|
||||
{
|
||||
if((logins[i] = (int *)malloc(3*sizeof(int))) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error while allocating memory\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
while(fscanf(fp, "%s", line) != EOF)
|
||||
{
|
||||
j = 2;
|
||||
keylog = atoi(line);
|
||||
|
||||
while(keylog > 0)
|
||||
{
|
||||
logins[i][j--] = keylog % 10;
|
||||
/* Check which digits are present in the login attempts.*/
|
||||
digits[keylog%10]++;
|
||||
keylog /= 10;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
j = 0;
|
||||
for(i = 0; i < 10; i++)
|
||||
{
|
||||
/* To generate the passcode, only use the digits present in the
|
||||
* login attempts.*/
|
||||
if(digits[i] > 0)
|
||||
{
|
||||
passcode_digits[j++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
while(!found)
|
||||
{
|
||||
if((passcode = (int **)malloc(len*sizeof(int *))) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error while allocating memory\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
if((passcode[i] = (int *)malloc(sizeof(int))) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error while allocating memory\n");
|
||||
return 1;
|
||||
}
|
||||
/* For the current length, generate the first passcode with the
|
||||
* digits in order.*/
|
||||
*passcode[i] = passcode_digits[i];
|
||||
}
|
||||
|
||||
/* Check if the passcode is compatible with the login attempts.*/
|
||||
if(check_passcode(passcode, len, logins, 50))
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* For the given length, check every permutation until the correct
|
||||
* passcode has been found, or all the permutations have been tried.*/
|
||||
while(next_permutation((void **)passcode, len, compare) != -1)
|
||||
{
|
||||
if(check_passcode(passcode, len, logins, 50))
|
||||
{
|
||||
printf("Project Euler, Problem 79\n");
|
||||
printf("Answer: ");
|
||||
for(i = 0; i < len; i++)
|
||||
printf("%d", *passcode[i]);
|
||||
printf("\n");
|
||||
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
free(passcode[i]);
|
||||
}
|
||||
free(passcode);
|
||||
|
||||
/* If the passcode has not yet been found, try a longer passcode.*/
|
||||
len++;
|
||||
}
|
||||
|
||||
for(i = 0; i < 50; i++)
|
||||
{
|
||||
free(logins[i]);
|
||||
}
|
||||
|
||||
free(logins);
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &end);
|
||||
|
||||
elapsed = (end.tv_sec - start.tv_sec) + (double)(end.tv_nsec - start.tv_nsec) / 1000000000;
|
||||
|
||||
printf("Elapsed time: %.9lf seconds\n", elapsed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int compare(void *a, void *b)
|
||||
{
|
||||
int *n1, *n2;
|
||||
|
||||
n1 = (int *)a;
|
||||
n2 = (int *)b;
|
||||
|
||||
return *n1 - *n2;
|
||||
}
|
||||
|
||||
int check_passcode(int **passcode, int len, int **logins, int n)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
/* For every login attempt, check if all the digits appear in the
|
||||
* passcode in the correct order. Return 0 if a login attempt
|
||||
* incompatible with the current passcode is found.*/
|
||||
for(i = 0; i < n; i++)
|
||||
{
|
||||
k = 0;
|
||||
for(j = 0; j < len; j++)
|
||||
{
|
||||
if(*passcode[j] == logins[i][k])
|
||||
{
|
||||
k++;
|
||||
|
||||
if(k == 3)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(k < 3)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
80
C/p080.c
Normal file
80
C/p080.c
Normal file
@ -0,0 +1,80 @@
|
||||
/* It is well known that if the square root of a natural number is not an integer, then it is irrational.
|
||||
* The decimal expansion of such square roots is infinite without any repeating pattern at all.
|
||||
*
|
||||
* The square root of two is 1.41421356237309504880..., and the digital sum of the first one hundred decimal digits is 475.
|
||||
*
|
||||
* For the first one hundred natural numbers, find the total of the digital sums of the first one hundred decimal digits
|
||||
* for all the irrational square roots*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <gmp.h>
|
||||
|
||||
int is_square(int n);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i, j, sum = 0;
|
||||
char sqrt_digits[104];
|
||||
double elapsed;
|
||||
struct timespec start, end;
|
||||
mpf_t sqrt;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||
|
||||
/* Set the precision to 333 bits (should be enough for 100 decimal digits.*/
|
||||
mpf_set_default_prec(333);
|
||||
mpf_init(sqrt);
|
||||
|
||||
for(i = 2; i < 100; i++)
|
||||
{
|
||||
if(is_square(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Calculate the square root of the current number with the given precision
|
||||
* and sum the digits to the total.*/
|
||||
mpf_sqrt_ui(sqrt, i);
|
||||
gmp_sprintf(sqrt_digits, "%.101Ff\n", sqrt);
|
||||
sum += (sqrt_digits[0] - '0');
|
||||
|
||||
for(j = 2; j < 101; j++)
|
||||
{
|
||||
sum += (sqrt_digits[j] - '0');
|
||||
}
|
||||
}
|
||||
|
||||
mpf_clear(sqrt);
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &end);
|
||||
|
||||
elapsed = (end.tv_sec - start.tv_sec) + (double)(end.tv_nsec - start.tv_nsec) / 1000000000;
|
||||
|
||||
printf("Project Euler, Problem 80\n");
|
||||
printf("Answer: %d\n", sum);
|
||||
|
||||
printf("Elapsed time: %.9lf seconds\n", elapsed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_square(int n)
|
||||
{
|
||||
int m;
|
||||
double p;
|
||||
|
||||
p = sqrt(n);
|
||||
m = p;
|
||||
|
||||
if(p == m)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -785,7 +785,7 @@ int phi(int n, int *primes)
|
||||
}
|
||||
|
||||
/* Function implementing the partition function.*/
|
||||
long int partition_fn(int n, long int *partitions)
|
||||
long int partition_fn(int n, long int *partitions, int mod)
|
||||
{
|
||||
int k, limit;
|
||||
long int res = 0;
|
||||
@ -800,6 +800,7 @@ long int partition_fn(int n, long int *partitions)
|
||||
if(n == 0)
|
||||
{
|
||||
partitions[n] = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -816,12 +817,22 @@ long int partition_fn(int n, long int *partitions)
|
||||
{
|
||||
if(k != 0)
|
||||
{
|
||||
res += pow(-1, k+1) * partition_fn(n-k*(3*k-1)/2, partitions);
|
||||
res += pow(-1, k+1) * partition_fn(n-k*(3*k-1)/2, partitions, mod);
|
||||
}
|
||||
k++;
|
||||
}
|
||||
|
||||
partitions[n] = res;
|
||||
/* Give the result modulo mod, if mod=!-1, otherwise give the full result.*/
|
||||
if(mod != -1)
|
||||
{
|
||||
partitions[n] = res % mod;
|
||||
|
||||
return res;
|
||||
return res % mod;
|
||||
}
|
||||
else
|
||||
{
|
||||
partitions[n] = res;
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ int pell_eq(int i, mpz_t x);
|
||||
int is_semiprime(int n, int *p, int *q, int *primes);
|
||||
int phi_semiprime(int n, int p, int q);
|
||||
int phi(int n, int *primes);
|
||||
long int partition_fn(int n, long int *partitions);
|
||||
long int partition_fn(int n, long int *partitions, int mod);
|
||||
int partition_fn_mpz(int n, mpz_t res, mpz_t *partitions);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user