Skip to content

Commit

Permalink
feat: Project Euler Problem 5 - #162 (#599)
Browse files Browse the repository at this point in the history
* rename existing code as sol3

* Added naive implementation for Problem 5

* Added a solution for Euler Problem 5 with easy improvements

* rename new files

* code formatting

* update documentations

* fix docs

* updating DIRECTORY.md

Co-authored-by: buffet <[email protected]>
Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
  • Loading branch information
3 people authored Sep 3, 2020
1 parent 23b2a29 commit bb6c62a
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 3 deletions.
4 changes: 3 additions & 1 deletion DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,9 @@
* Problem 401
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_401/sol1.c)
* Problem 5
* [Sol](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_5/sol.c)
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_5/sol1.c)
* [Sol2](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_5/sol2.c)
* [Sol3](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_5/sol3.c)
* Problem 6
* [Sol](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_6/sol.c)
* Problem 7
Expand Down
48 changes: 48 additions & 0 deletions project_euler/problem_5/sol1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* \file
* \brief [Problem 5](https://projecteuler.net/problem=5) solution - Naive
* algorithm (slowest)
*
* \see Faster: problem_5/sol2.c
* \see Fastest: problem_5/sol3.c
*/
#include <stdio.h>
#include <stdlib.h>

/** Pretty naive implementation. Just checks every number if it's devisable by 1
* through 20
* @param n number to check
* @returns 0 if not divisible
* @returns 1 if divisible
*/
static char check_number(unsigned long long n)
{
for (unsigned long long i = 1; i <= 20; ++i)
{
if (n % i != 0)
{
return 0;
}
}

return 1;
}

/**
* @brief Main function
*
* @return 0 on exit
*/
int main(void)
{
for (unsigned long long n = 1;; ++n)
{
if (check_number(n))
{
printf("Result: %llu\n", n);
break;
}
}

return 0;
}
59 changes: 59 additions & 0 deletions project_euler/problem_5/sol2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* \file
* \brief [Problem 5](https://projecteuler.net/problem=5) solution - Naive
* algorithm (Improved over problem_5/sol1.c)
* @details Little bit improved version of the naive `problem_5/sol1.c`. Since
* the number has to be divisable by 20, we can start at 20 and go in 20 steps.
* Also we don't have to check against any number, since most of them are
* implied by other divisions (i.e. if a number is divisable by 20, it's also
* divisable by 2, 5, and 10). This all gives a 97% perfomance increase on my
* machine (9.562 vs 0.257)
*
* \see Slower: problem_5/sol1.c
* \see Faster: problem_5/sol3.c
*/
#include <stdio.h>
#include <stdlib.h>

/**
* @brief Hack to store divisors between 1 & 20
*/
static unsigned int divisors[] = {
11, 13, 14, 16, 17, 18, 19, 20,
};

/** Checks if a given number is devisable by every number between 1 and 20
* @param n number to check
* @returns 0 if not divisible
* @returns 1 if divisible
*/
static int check_number(unsigned long long n)
{
for (size_t i = 0; i < 7; ++i)
{
if (n % divisors[i] != 0)
{
return 0;
}
}

return 1;
}

/**
* @brief Main function
*
* @return 0 on exit
*/
int main(void)
{
for (unsigned long long n = 20;; n += 20)
{
if (check_number(n))
{
printf("Result: %llu\n", n);
break;
}
}
return 0;
}
16 changes: 14 additions & 2 deletions project_euler/problem_5/sol.c → project_euler/problem_5/sol3.c
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
/**
* \file
* \brief [Problem 5](https://projecteuler.net/problem=5) solution
* \brief [Problem 5](https://projecteuler.net/problem=5) solution (Fastest).
* @details Solution is the LCM of all numbers between 1 and 20.
*
* \see Slowest: problem_5/sol1.c
* \see Slower: problem_5/sol2.c
*/
#include <stdio.h>

/** Compute [Greatest Common Divisor
* (GCD)](https://en.wikipedia.org/wiki/Greatest_common_divisor) of two numbers
* using Euclids algorithm
* @param a first number
* @param b second number
* @return GCD of `a` and `b`
*/
unsigned long gcd(unsigned long a, unsigned long b)
{
Expand All @@ -27,14 +34,19 @@ unsigned long gcd(unsigned long a, unsigned long b)

/** Compute [Least Common Multiple
* (LCM)](https://en.wikipedia.org/wiki/Least_common_multiple) of two numbers
* @param a first number
* @param b second number
* @return LCM of `a` and `b`
*/
unsigned long lcm(unsigned long a, unsigned long b)
{
unsigned long long p = (unsigned long long)a * b;
return p / gcd(a, b);
}

/** Main function */
/** Main function
* @returns 0 on exit
*/
int main(void)
{
unsigned long ans = 1;
Expand Down

0 comments on commit bb6c62a

Please sign in to comment.