From 7489196be85228eb607885b52fefbef6bbb0f6f4 Mon Sep 17 00:00:00 2001 From: Daniele Fucini Date: Sat, 28 Sep 2019 11:31:06 +0200 Subject: [PATCH] Improve solution for problem 47 --- C/p047.c | 83 +++++++++++++++++++++++--------------------------- Python/p047.py | 71 ++++++++++++++++-------------------------- 2 files changed, 64 insertions(+), 90 deletions(-) diff --git a/C/p047.c b/C/p047.c index 35cc6f9..0e383f2 100644 --- a/C/p047.c +++ b/C/p047.c @@ -15,88 +15,81 @@ #include #include #include -#include "projecteuler.h" #define N 150000 -int count_distinct_factors(int n); - -int *primes; +int *count_factors(int n); int main(int argc, char **argv) { - int i, found = 0; + int i, count, res; + int *factors; double elapsed; struct timespec start, end; clock_gettime(CLOCK_MONOTONIC, &start); - if((primes = sieve(N)) == NULL) + if((factors = count_factors(N)) == NULL) { - fprintf(stderr, "Error! Sieve function returned NULL\n"); + fprintf(stderr, "Error! Count_factors function returned NULL\n"); return 1; } - /* Starting from 647, count the distinct prime factors of n, n+1, n+2 and n+3. - * If they all have 4, the solution is found.*/ - for(i = 647; !found && i < N - 3; i++) - { - if(!primes[i] && !primes[i+1] && !primes[i+2] && !primes[i+3]) - { - if(count_distinct_factors(i) == 4 && count_distinct_factors(i+1) == 4 && - count_distinct_factors(i+2) == 4 && count_distinct_factors(i+3) == 4) - { - found = 1; - } - } - } + count = 0; - free(primes); + for(i = 0; i < N; i++) + { + if(factors[i] == 4) + { + count++; + } + else + { + count = 0; + } + + if(count == 4) + { + res = i - 3; + break; + } + } clock_gettime(CLOCK_MONOTONIC, &end); elapsed = (end.tv_sec - start.tv_sec) + (double)(end.tv_nsec - start.tv_nsec) / 1000000000; printf("Project Euler, Problem 47\n"); - printf("Answer: %d\n", i-1); + printf("Answer: %d\n", res); printf("Elapsed time: %.9lf seconds\n", elapsed); return 0; } -int count_distinct_factors(int n) +/* Function using a modified sieve of Eratosthenes to count + * the distinct prime factors of each number.*/ +int *count_factors(int n) { - int i, count=0; + int i = 2, j; + int *factors; - /* Start checking if 2 is a prime factor of n. Then remove - * all 2s factore.*/ - if(n % 2 == 0) + if((factors = (int *)calloc(n, sizeof(int))) == NULL) { - count++; - - do - { - n /= 2; - }while(n % 2 == 0); + return NULL; } - /* Check all odd numbers i, if they're prime and they're a factor - * of n, count them and then divide n for by i until all factors i - * are eliminated. Stop the loop when n=1, i.e. all factors have - * been found.*/ - for(i = 3; n > 1; i += 2) + while(i < n / 2) { - if(primes[i] && n % i == 0) + if(factors[i] == 0) { - count++; - - do + for(j = i; j < n; j += i) { - n /= i; - }while(n % i == 0); + factors[j]++; + } } + i++; } - return count; + return factors; } diff --git a/Python/p047.py b/Python/p047.py index d03cfed..0940444 100644 --- a/Python/p047.py +++ b/Python/p047.py @@ -14,65 +14,46 @@ # Find the first four consecutive integers to have four distinct prime factors each. What is the first of these numbers? from timeit import default_timer -from projecteuler import sieve -def count_distinct_factors(n): - global primes - count = 0 +# Function using a modified sieve of Eratosthenes to count +# the prime factors of each number. +def count_factors(n): + factors = [0] * n + i = 2 -# Start checking if 2 is a prime factor of n. Then remove -# all 2s factore. - if n % 2 == 0: - count = count + 1 + while i < n // 2: + if factors[i] == 0: + for j in range(i, n, i): + factors[j] = factors[j] + 1 + i = i + 1 - while True: - n = n // 2 - - if n % 2 != 0: - break - - i = 3 - -# Check all odd numbers i, if they're prime and they're a factor -# of n, count them and then divide n for by i until all factors i -# are eliminated. Stop the loop when n=1, i.e. all factors have -# been found. - while n > 1: - if primes[i] == 1 and n % i == 0: - count = count + 1 - - while True: - n = n // i - - if n % i != 0: - break - i = i + 2 - - return count + return factors def main(): start = default_timer() - global primes - N = 150000 - primes = sieve(N) - found = 0 - i = 647 + factors = count_factors(N) -# Starting from 647, count the distinct prime factors of n, n+1, n+2 and n+3. -# If they all have 4, the solution is found. - while not found and i < N - 3: - if primes[i] == 0 and primes[i+1] == 0 and primes[i+2] == 0 and primes[i+3] == 0: - if count_distinct_factors(i) == 4 and count_distinct_factors(i+1) == 4 and count_distinct_factors(i+2) == 4 and count_distinct_factors(i+3) == 4: - found = 1 - i = i + 1 + count = 0 + +# Find the first instance of four consecutive numbers +# having four distinct prime factors. + for i in range(N): + if factors[i] == 4: + count = count + 1 + else: + count = 0 + + if count == 4: + res = i - 3 + break end = default_timer() print('Project Euler, Problem 47') - print('Answer: {}'.format(i-1)) + print('Answer: {}'.format(res)) print('Elapsed time: {:.9f} seconds'.format(end - start))