-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Solve problems 6, 9, 11, 14, 15, 34, 76 in C++
- Loading branch information
1 parent
cf48976
commit e463195
Showing
21 changed files
with
731 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
#ifndef EULER_MATH_H | ||
#define EULER_MATH_H | ||
|
||
#include "macros.h" | ||
#include <math.h> | ||
#include <stdlib.h> | ||
#include <stdint.h> | ||
|
||
using namespace std; | ||
|
||
uintmax_t factorial(unsigned int n); | ||
inline uintmax_t factorial(unsigned int n) { | ||
// note that this function only works for numbers smaller than MAX_FACTORIAL_64 | ||
if ((sizeof(uintmax_t) == 8 && n > MAX_FACTORIAL_64) || (sizeof(uintmax_t) == 16 && n > MAX_FACTORIAL_128)) | ||
return -1; | ||
uintmax_t ret = 1; | ||
for (unsigned int i = 2; i <= n; ++i) { | ||
ret *= i; | ||
} | ||
return ret; | ||
} | ||
|
||
uintmax_t n_choose_r(unsigned int n, unsigned int r) { | ||
// function returns -1 if it overflows | ||
if ((sizeof(uintmax_t) == 8 && n <= MAX_FACTORIAL_64) || (sizeof(uintmax_t) == 16 && n <= MAX_FACTORIAL_128)) { | ||
// fast path if small enough | ||
return factorial(n) / factorial(r) / factorial(n-r); | ||
} | ||
// slow path for larger numbers | ||
int *factors; | ||
uintmax_t answer, tmp; | ||
unsigned int i, j; | ||
factors = (int *) malloc(sizeof(int) * (n + 1)); | ||
// collect factors of final number | ||
for (i = 2; i <= n; i++) { | ||
factors[i] = 1; | ||
} | ||
// negative factor values indicate need to divide | ||
for (i = 2; i <= r; i++) { | ||
factors[i] -= 1; | ||
} | ||
for (i = 2; i <= n - r; i++) { | ||
factors[i] -= 1; | ||
} | ||
// this loop reduces to prime factors only | ||
for (i = n; i > 1; i--) { | ||
for (j = 2; j < i; j++) { | ||
if (i % j == 0) { | ||
factors[j] += factors[i]; | ||
factors[i / j] += factors[i]; | ||
factors[i] = 0; | ||
break; | ||
} | ||
} | ||
} | ||
i = j = 2; | ||
answer = 1; | ||
while (i <= n) { | ||
while (factors[i] > 0) { | ||
tmp = answer; | ||
answer *= i; | ||
while (answer < tmp && j <= n) { | ||
while (factors[j] < 0) { | ||
tmp /= j; | ||
factors[j]++; | ||
} | ||
j++; | ||
answer = tmp * i; | ||
} | ||
if (answer < tmp) { | ||
return -1; // this indicates an overflow | ||
} | ||
factors[i]--; | ||
} | ||
i++; | ||
} | ||
while (j <= n) { | ||
while (factors[j] < 0) { | ||
answer /= j; | ||
factors[j]++; | ||
} | ||
j++; | ||
} | ||
free(factors); | ||
return answer; | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* | ||
Project Euler Problem 6 | ||
I know there is a closed form solution to sum of squares, but I didn't want to | ||
cheat and look it up. I was able to remember the closed form formula for sum of | ||
natural numbers, though, so this is still pretty fast. | ||
Problem: | ||
The sum of the squares of the first ten natural numbers is, | ||
1**2 + 2**2 + ... + 10**2 = 385 | ||
The square of the sum of the first ten natural numbers is, | ||
(1 + 2 + ... + 10)**2 = 55**2 = 3025 | ||
Hence the difference between the sum of the squares of the first ten natural | ||
numbers and the square of the sum is 3025 − 385 = 2640. | ||
Find the difference between the sum of the squares of the first one hundred | ||
natural numbers and the square of the sum. | ||
*/ | ||
#ifndef EULER_P0006 | ||
#define EULER_P0006 | ||
#include <iostream> | ||
|
||
unsigned long long p0006() { | ||
unsigned long long sum = 100 * 101 / 2, sum_of_squares = 0; | ||
for (unsigned long long i = 1; i < 101; i++) { | ||
sum_of_squares += i * i; | ||
} | ||
return sum * sum - sum_of_squares; | ||
} | ||
|
||
#ifndef UNITY_END | ||
int main(int argc, char const *argv[]) { | ||
std::cout << p0006() << std::endl; | ||
return 0; | ||
} | ||
#endif | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* | ||
Project Euler Problem 9 | ||
This was fairly short to code, but it took me a minute to figure out how to deal with the lack of multi-loop breaking | ||
Problem: | ||
A Pythagorean triplet is a set of three natural numbers, a < b < c, for which, | ||
a2 + b2 = c2 | ||
For example, 32 + 42 = 9 + 16 = 25 = 52. | ||
There exists exactly one Pythagorean triplet for which a + b + c = 1000. | ||
Find the product abc. | ||
*/ | ||
#ifndef EULER_P0009 | ||
#define EULER_P0009 | ||
#include <iostream> | ||
|
||
unsigned long long p0009() { | ||
unsigned long long answer = 0; | ||
for (unsigned int c = 3; !answer && c < 1000; c++) { | ||
for (unsigned int b = 2; b < c; b++) { | ||
unsigned int a = 1000 - c - b; | ||
if (a < b && a*a + b*b == c*c) { | ||
answer = (unsigned long long) a * b * c; | ||
break; | ||
} | ||
} | ||
} | ||
return answer; | ||
} | ||
|
||
#ifndef UNITY_END | ||
int main(int argc, char const *argv[]) { | ||
std::cout << p0009() << std::endl; | ||
return 0; | ||
} | ||
#endif | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/* | ||
Project Euler Problem 11 | ||
Problem: | ||
In the 20×20 grid below, four numbers along a diagonal line have been marked in red. | ||
08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 | ||
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 | ||
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 | ||
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 | ||
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 | ||
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 | ||
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 | ||
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 | ||
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 | ||
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 | ||
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 | ||
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 | ||
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 | ||
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 | ||
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 | ||
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 | ||
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 | ||
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 | ||
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 | ||
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48 | ||
The product of these numbers is 26 × 63 × 78 × 14 = 1788696. | ||
What is the greatest product of four adjacent numbers in the same direction (up, down, left, right, or diagonally) in | ||
the 20×20 grid? | ||
*/ | ||
#ifndef EULER_P0011 | ||
#define EULER_P0011 | ||
#include <iostream> | ||
|
||
static const unsigned char grid[20][20] = { | ||
{ 8, 2, 22, 97, 38, 15, 0, 40, 0, 75, 4, 5, 7, 78, 52, 12, 50, 77, 91, 8}, | ||
{49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 4, 56, 62, 0}, | ||
{81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 3, 49, 13, 36, 65}, | ||
{52, 70, 95, 23, 4, 60, 11, 42, 69, 24, 68, 56, 1, 32, 56, 71, 37, 2, 36, 91}, | ||
{22, 31, 16, 71, 51, 67, 63, 89, 41, 92, 36, 54, 22, 40, 40, 28, 66, 33, 13, 80}, | ||
{24, 47, 32, 60, 99, 03, 45, 2, 44, 75, 33, 53, 78, 36, 84, 20, 35, 17, 12, 50}, | ||
{32, 98, 81, 28, 64, 23, 67, 10, 26, 38, 40, 67, 59, 54, 70, 66, 18, 38, 64, 70}, | ||
{67, 26, 20, 68, 2, 62, 12, 20, 95, 63, 94, 39, 63, 8, 40, 91, 66, 49, 94, 21}, | ||
{24, 55, 58, 5, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72}, | ||
{21, 36, 23, 9, 75, 0, 76, 44, 20, 45, 35, 14, 0, 61, 33, 97, 34, 31, 33, 95}, | ||
{78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 3, 80, 4, 62, 16, 14, 9, 53, 56, 92}, | ||
{16, 39, 5, 42, 96, 35, 31, 47, 55, 58, 88, 24, 0, 17, 54, 24, 36, 29, 85, 57}, | ||
{86, 56, 0, 48, 35, 71, 89, 7, 5, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58}, | ||
{19, 80, 81, 68, 5, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 4, 89, 55, 40}, | ||
{ 4, 52, 8, 83, 97, 35, 99, 16, 7, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 66}, | ||
{88, 36, 68, 87, 57, 62, 20, 72, 3, 46, 33, 67, 46, 55, 12, 32, 63, 93, 53, 69}, | ||
{ 4, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 8, 46, 29, 32, 40, 62, 76, 36}, | ||
{20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 04, 36, 16}, | ||
{20, 73, 35, 29, 78, 31, 90, 1, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 5, 54}, | ||
{ 1, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 1, 89, 19, 67, 48} | ||
}; | ||
|
||
unsigned long long p0011() { | ||
unsigned long answer = 0, tmp; | ||
unsigned char i, j; | ||
for (i = 0; i < 20; i++) { | ||
for (j = 0; j < 17; j++) { | ||
// horizontal section | ||
tmp = grid[i][j] * grid[i][j + 1] * grid[i][j + 2] * grid[i][j + 3]; | ||
answer = std::max(answer, tmp); | ||
// vertical section | ||
tmp = grid[j][i] * grid[j + 1][i] * grid[j + 2][i] * grid[j + 3][i]; | ||
answer = std::max(answer, tmp); | ||
} | ||
} | ||
for (i = 0; i < 17; i++) { | ||
for (j = 0; j < 17; j++) { | ||
// right diagonal section | ||
tmp = grid[i][j] * grid[i + 1][j + 1] * grid[i + 2][j + 2] * grid[i + 3][j + 3]; | ||
answer = std::max(answer, tmp); | ||
// left diagonal section | ||
tmp = grid[i][j + 3] * grid[i + 1][j + 2] * grid[i + 2][j + 1] * grid[i + 3][j]; | ||
answer = std::max(answer, tmp); | ||
} | ||
} | ||
return answer; | ||
} | ||
|
||
#ifndef UNITY_END | ||
int main(int argc, char const *argv[]) { | ||
std::cout << p0011() << std::endl; | ||
return 0; | ||
} | ||
#endif | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
Project Euler Problem 14 | ||
This was easier to do in C++ than I would have thought | ||
Problem: | ||
The following iterative sequence is defined for the set of positive integers: | ||
n → n/2 (n is even) | ||
n → 3n + 1 (n is odd) | ||
Using the rule above and starting with 13, we generate the following sequence: | ||
13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1 | ||
It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been | ||
proved yet (Collatz Problem), it is thought that all starting numbers finish at 1. | ||
Which starting number, under one million, produces the longest chain? | ||
NOTE: Once the chain starts the terms are allowed to go above one million. | ||
*/ | ||
#ifndef EULER_P0014 | ||
#define EULER_P0014 | ||
#include <iostream> | ||
|
||
#define CACHE_SIZE 1000000 | ||
static unsigned int collatz_len_cache[CACHE_SIZE] = {0, 1, 0}; | ||
|
||
unsigned int collatz_len(unsigned long long n); | ||
|
||
unsigned int collatz_len(unsigned long long n) { | ||
if (n < CACHE_SIZE && collatz_len_cache[n]) { | ||
return collatz_len_cache[n]; | ||
} | ||
unsigned int ret = 0; | ||
if (n % 2) { | ||
ret = 2 + collatz_len((3 * n + 1) / 2); | ||
} else { | ||
ret = 1 + collatz_len(n / 2); | ||
} | ||
if (n < CACHE_SIZE) { | ||
collatz_len_cache[n] = ret; | ||
} | ||
return ret; | ||
} | ||
|
||
unsigned long long p0014() { | ||
unsigned long long answer = 2, length = 2, tmp; | ||
for (unsigned long long test = 3; test < 1000000; test++) { | ||
tmp = collatz_len(test); | ||
if (tmp > length) { | ||
answer = test; | ||
length = tmp; | ||
} | ||
} | ||
return answer; | ||
} | ||
|
||
#ifndef UNITY_END | ||
int main(int argc, char const *argv[]) { | ||
std::cout << p0014() << std::endl; | ||
return 0; | ||
} | ||
#endif | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
Project Euler Problem 15 | ||
Turns out this is easy, if you think sideways a bit | ||
You can only go down or right. If we say right=1, then you can only have 20 1s, since otherwise you go off the grid. | ||
You also can't have fewer than 20 1s, since then you go off the grid the other way. This means you can look at it as a | ||
bit string, and the number of 40-bit strings with 20 1s is 40c20. | ||
Problem: | ||
Starting in the top left corner of a 2×2 grid, and only being able to move to the right and down, there are exactly 6 | ||
routes to the bottom right corner. | ||
How many such routes are there through a 20×20 grid? | ||
*/ | ||
#ifndef EULER_P0015 | ||
#define EULER_P0015 | ||
#include <iostream> | ||
#include "include/math.h" | ||
|
||
#define lattice_paths(height, width) (n_choose_r(height + width, height)) | ||
|
||
unsigned long long p0015() { | ||
return lattice_paths(20, 20); | ||
} | ||
|
||
#ifndef UNITY_END | ||
int main(int argc, char const *argv[]) { | ||
std::cout << p0015() << std::endl; | ||
return 0; | ||
} | ||
#endif | ||
#endif |
Oops, something went wrong.