Added more problems solutions

This commit is contained in:
erick-alcachofa 2025-09-07 00:13:35 -06:00
parent d47324e483
commit ed6344bb87
Signed by: me
GPG Key ID: 6FA5F8643444BAFA
33 changed files with 916 additions and 1 deletions

View File

@ -16,6 +16,9 @@
#pragma once
#include <vector>
#include <cstdio>
struct SieveAutoFill{};
template <std::integral T>
struct Sieve {
@ -23,6 +26,12 @@ struct Sieve {
: MaxPrime(MaxPrime)
, isPrime(MaxPrime + 1, true) { }
Sieve(T MaxPrime, SieveAutoFill)
: MaxPrime(MaxPrime)
, isPrime(MaxPrime + 1, true) {
Fill();
}
~Sieve() = default;
void Fill() {

20
gen.sh Executable file
View File

@ -0,0 +1,20 @@
#!/usr/bin/env bash
PROBLEM_NUMBER="$1"
PROBLEM_NAME="$2"
cp -r ./.template problem-$PROBLEM_NUMBER
cd problem-$PROBLEM_NUMBER
grep -I -r "{{ problem_name }}" -l \
| xargs -I$ sed -i "s#{{ problem_name }}#$PROBLEM_NAME#" $
grep -I -r "{{ author_name }}" -l \
| xargs -I$ sed -i "s#{{ author_name }}#erick-alcachofa#" $
grep -I -r "{{ date }}" -l \
| xargs -I$ sed -i "s#{{ date }}#$(date +'%A, %B %d %Y')#" $
grep -I -r "1" -l \
| xargs -I$ sed -i "s#1#$PROBLEM_NUMBER#" $

1
problem-12/data/example Normal file
View File

@ -0,0 +1 @@
5

1
problem-12/data/input Normal file
View File

@ -0,0 +1 @@
500

68
problem-12/src/impl.hpp Normal file
View File

@ -0,0 +1,68 @@
/*
* Project Euler Solutions - Core Implementation
* ---------------------------------------------
* Problem : Highly Divisible Triangular Number
* URL : https://projecteuler.net/problem=12
*
* Author : erick-alcachofa
* Created : Tuesday, August 05 2025
*
* Notes:
* -
*
* License : GNU Affero General Public License v3.0 (AGPLv3)
* https://www.gnu.org/licenses/agpl-3.0.html
*/
#pragma once
#include <cstdint>
#include <sstream>
#include "sqrt.hpp"
#include "sieve.hpp"
constexpr const int64_t MaxPrime = ct_sqrt<int64_t>(1e9 + 7);
static Sieve sieve(MaxPrime);
static int64_t Solve(std::stringstream in) {
int64_t n = 0;
int64_t accumulated = 0;
int64_t iter = 0;
int64_t count = 0;
in >> n;
sieve.Fill();
while (count < n) {
iter++;
accumulated += iter;
int64_t number = accumulated;
count = 1;
for (auto prime : sieve) {
if ((prime * prime) > number) {
break;
}
if (number % prime == 0) {
int64_t exponent = 0;
do {
exponent += 1;
number /= prime;
} while (number % prime == 0);
count *= (exponent + 1);
}
}
if (number != 1) {
count *= 2;
}
}
return accumulated;
}

View File

@ -0,0 +1,40 @@
/*
* Project Euler Solutions - Main Translation Unit
* ------------------------------------------
* Problem : Highly Divisible Triangular Number
* URL : https://projecteuler.net/problem=12
*
* Author : erick-alcachofa
* Created : Tuesday, August 05 2025
*
* Notes:
* -
*
* License : GNU Affero General Public License v3.0 (AGPLv3)
* https://www.gnu.org/licenses/agpl-3.0.html
*/
#include <iostream>
#include <print>
#include <sstream>
#include <string>
#include "timer.hpp"
#include "impl.hpp"
int main(int, char *[]) {
std::ios_base::sync_with_stdio(false),
std::cin.tie(nullptr),
std::cout.tie(nullptr);
std::string input = R"(@input@)";
decltype(Solve({})) ans = {};
{
Timer<Milliseconds> timer;
ans = Solve(std::stringstream{input});
}
std::println("{}", ans);
}

28
problem-12/src/test.cpp Normal file
View File

@ -0,0 +1,28 @@
/*
* Project Euler Solutions - Test File
* ------------------------------------
* Problem : Highly Divisible Triangular Number
* URL : https://projecteuler.net/problem=12
*
* Author : erick-alcachofa
* Created : Tuesday, August 05 2025
*
* Notes:
* -
*
* License : GNU Affero General Public License v3.0 (AGPLv3)
* https://www.gnu.org/licenses/agpl-3.0.html
*/
#include <gtest/gtest.h>
#include <sstream>
#include "impl.hpp"
const char *input = R"(@example@)";
TEST(Problem12, test) {
const auto ans = Solve(std::stringstream{input});
EXPECT_EQ(ans, 28);
}

1
problem-14/data/example Normal file
View File

@ -0,0 +1 @@
15

1
problem-14/data/input Normal file
View File

@ -0,0 +1 @@
1000000

61
problem-14/src/impl.hpp Normal file
View File

@ -0,0 +1,61 @@
/*
* Project Euler Solutions - Core Implementation
* ---------------------------------------------
* Problem : Longest Collatz Sequence
* URL : https://projecteuler.net/problem=14
*
* Author : erick-alcachofa
* Created : Tuesday, August 05 2025
*
* Notes:
* -
*
* License : GNU Affero General Public License v3.0 (AGPLv3)
* https://www.gnu.org/licenses/agpl-3.0.html
*/
#pragma once
#include <map>
#include <unordered_map>
#include <stack>
#include <queue>
#include <print>
#include <cstdint>
#include <sstream>
static int64_t Solve(std::stringstream in) {
int64_t n = 0;
int64_t maxN = 0;
in >> n;
std::unordered_map<int64_t, int64_t> length;
length[1] = 1;
auto fn = [&length](this auto &&self, int64_t n) -> int64_t {
if (length.contains(n)) {
return length[n];
}
if (n & 1) {
return length[n] = (1 + self((3 * n) + 1));
} else {
return length[n] = (1 + self(n / 2));
}
};
auto maxLength = 0l;
auto maxLenElem = 0l;
for (int64_t i = 1; i < n; ++i) {
auto clength = fn(i);
if (clength > maxLength) {
maxLength = clength;
maxLenElem = i;
}
}
return maxLenElem;
}

View File

@ -0,0 +1,40 @@
/*
* Project Euler Solutions - Main Translation Unit
* ------------------------------------------
* Problem : Longest Collatz Sequence
* URL : https://projecteuler.net/problem=14
*
* Author : erick-alcachofa
* Created : Tuesday, August 05 2025
*
* Notes:
* -
*
* License : GNU Affero General Public License v3.0 (AGPLv3)
* https://www.gnu.org/licenses/agpl-3.0.html
*/
#include <iostream>
#include <print>
#include <sstream>
#include <string>
#include "timer.hpp"
#include "impl.hpp"
int main(int, char *[]) {
std::ios_base::sync_with_stdio(false),
std::cin.tie(nullptr),
std::cout.tie(nullptr);
std::string input = R"(@input@)";
decltype(Solve({})) ans = {};
{
Timer<Milliseconds> timer;
ans = Solve(std::stringstream{input});
}
std::println("{}", ans);
}

28
problem-14/src/test.cpp Normal file
View File

@ -0,0 +1,28 @@
/*
* Project Euler Solutions - Test File
* ------------------------------------
* Problem : Longest Collatz Sequence
* URL : https://projecteuler.net/problem=14
*
* Author : erick-alcachofa
* Created : Tuesday, August 05 2025
*
* Notes:
* -
*
* License : GNU Affero General Public License v3.0 (AGPLv3)
* https://www.gnu.org/licenses/agpl-3.0.html
*/
#include <gtest/gtest.h>
#include <sstream>
#include "impl.hpp"
const char *input = R"(@example@)";
TEST(Problem14, test) {
const auto ans = Solve(std::stringstream{input});
EXPECT_EQ(ans, 9);
}

0
problem-21/data/example Normal file
View File

0
problem-21/data/input Normal file
View File

77
problem-21/src/impl.hpp Normal file
View File

@ -0,0 +1,77 @@
/*
* Project Euler Solutions - Core Implementation
* ---------------------------------------------
* Problem : Amicable Numbers
* URL : https://projecteuler.net/problem=21
*
* Author : erick-alcachofa
* Created : Sunday, August 210 2025
*
* Notes:
* -
*
* License : GNU Affero General Public License v3.0 (AGPLv3)
* https://www.gnu.org/licenses/agpl-3.0.html
*/
#pragma once
#include <cstdint>
#include <sstream>
#include "sieve.hpp"
#include "sqrt.hpp"
constexpr const int64_t MaxPrime = ct_sqrt<int64_t>(1e9 + 7);
static Sieve sieve(MaxPrime);
static int64_t SumOfDivisors(int64_t number) {
int64_t total = 1;
for (auto prime : sieve) {
if ((prime * prime) > number) {
break;
}
if (number % prime == 0) {
int64_t exponent = 0;
do {
exponent += 1;
number /= prime;
} while (number % prime == 0);
int64_t sum = 0;
int64_t pow = 1;
do {
sum += pow;
pow *= prime;
} while (exponent-- > 0);
total *= sum;
}
}
if (number != 1) {
total *= (1 + number);
}
return total;
}
static int64_t Solve(std::stringstream) {
int64_t sum = 0;
sieve.Fill();
for (int64_t a = 2; a < 10000; ++a) {
auto b = SumOfDivisors(a) - a;
if (a != b && (SumOfDivisors(b) - b) == a) {
sum += a;
}
}
return sum;
}

View File

@ -0,0 +1,40 @@
/*
* Project Euler Solutions - Main Translation Unit
* ------------------------------------------
* Problem : Amicable Numbers
* URL : https://projecteuler.net/problem=21
*
* Author : erick-alcachofa
* Created : Sunday, August 210 2025
*
* Notes:
* -
*
* License : GNU Affero General Public License v3.0 (AGPLv3)
* https://www.gnu.org/licenses/agpl-3.0.html
*/
#include <iostream>
#include <print>
#include <sstream>
#include <string>
#include "timer.hpp"
#include "impl.hpp"
int main(int, char *[]) {
std::ios_base::sync_with_stdio(false),
std::cin.tie(nullptr),
std::cout.tie(nullptr);
std::string input = R"(@input@)";
decltype(Solve({})) ans = {};
{
Timer<Milliseconds> timer;
ans = Solve(std::stringstream{input});
}
std::println("{}", ans);
}

29
problem-21/src/test.cpp Normal file
View File

@ -0,0 +1,29 @@
/*
* Project Euler Solutions - Test File
* ------------------------------------
* Problem : Amicable Numbers
* URL : https://projecteuler.net/problem=21
*
* Author : erick-alcachofa
* Created : Sunday, August 210 2025
*
* Notes:
* -
*
* License : GNU Affero General Public License v3.0 (AGPLv3)
* https://www.gnu.org/licenses/agpl-3.0.html
*/
#include <gtest/gtest.h>
#include <sstream>
#include "impl.hpp"
const char *input = R"(@example@)";
TEST(Problem21, testAmicables) {
const int64_t a = 220;
const int64_t b = 284;
EXPECT_EQ(SumOfDivisors(a) - a, SumOfDivisors(b) - b);
}

0
problem-23/data/example Normal file
View File

0
problem-23/data/input Normal file
View File

110
problem-23/src/impl.hpp Normal file
View File

@ -0,0 +1,110 @@
/*
* Project Euler Solutions - Core Implementation
* ---------------------------------------------
* Problem : Non-Abundant Sums
* URL : https://projecteuler.net/problem=23
*
* Author : erick-alcachofa
* Created : Sunday, August 230 2025
*
* Notes:
* -
*
* License : GNU Affero General Public License v3.0 (AGPLv3)
* https://www.gnu.org/licenses/agpl-3.0.html
*/
#pragma once
#include <cstdint>
#include <sstream>
#include <algorithm>
#include "sieve.hpp"
#include "sqrt.hpp"
constexpr const int64_t MaxPrime = ct_sqrt<int64_t>(1e9 + 7);
static Sieve sieve(MaxPrime);
static int64_t SumOfDivisors(int64_t number) {
int64_t total = 1;
for (auto prime : sieve) {
if ((prime * prime) > number) {
break;
}
if (number % prime == 0) {
int64_t exponent = 0;
do {
exponent += 1;
number /= prime;
} while (number % prime == 0);
int64_t sum = 0;
int64_t pow = 1;
do {
sum += pow;
pow *= prime;
} while (exponent-- > 0);
total *= sum;
}
}
if (number != 1) {
total *= (1 + number);
}
return total;
}
static int64_t Solve(std::stringstream) {
sieve.Fill();
std::vector<int64_t> abundants;
for (int64_t i = 2; i <= 28123; ++i) {
auto di = SumOfDivisors(i) - i;
if (di > i) {
abundants.push_back(i);
}
}
int64_t sum = 0;
for (int64_t target = 1; target <= 28123; ++target) {
bool foundSum = false;
int64_t left = 0;
int64_t right =
std::ranges::distance(
abundants.begin(),
std::ranges::lower_bound(abundants, target)
) - 1;
while (left <= right) {
auto tsum = abundants[size_t(left)] + abundants[size_t(right)];
if (tsum == target) {
foundSum = true;
break;
}
else if (tsum < target) {
left++;
}
else {
right--;
}
}
if (not foundSum) {
sum += target;
}
}
return sum;
}

View File

@ -0,0 +1,40 @@
/*
* Project Euler Solutions - Main Translation Unit
* ------------------------------------------
* Problem : Non-Abundant Sums
* URL : https://projecteuler.net/problem=23
*
* Author : erick-alcachofa
* Created : Sunday, August 230 2025
*
* Notes:
* -
*
* License : GNU Affero General Public License v3.0 (AGPLv3)
* https://www.gnu.org/licenses/agpl-3.0.html
*/
#include <iostream>
#include <print>
#include <sstream>
#include <string>
#include "timer.hpp"
#include "impl.hpp"
int main(int, char *[]) {
std::ios_base::sync_with_stdio(false),
std::cin.tie(nullptr),
std::cout.tie(nullptr);
std::string input = R"(@input@)";
decltype(Solve({})) ans = {};
{
Timer<Milliseconds> timer;
ans = Solve(std::stringstream{input});
}
std::println("{}", ans);
}

28
problem-23/src/test.cpp Normal file
View File

@ -0,0 +1,28 @@
/*
* Project Euler Solutions - Test File
* ------------------------------------
* Problem : Non-Abundant Sums
* URL : https://projecteuler.net/problem=23
*
* Author : erick-alcachofa
* Created : Sunday, August 230 2025
*
* Notes:
* -
*
* License : GNU Affero General Public License v3.0 (AGPLv3)
* https://www.gnu.org/licenses/agpl-3.0.html
*/
#include <gtest/gtest.h>
#include <sstream>
#include "impl.hpp"
const char *input = R"(@example@)";
TEST(Problem23, test) {
const auto ans = Solve(std::stringstream{input});
EXPECT_EQ(ans, 0);
}

1
problem-35/data/example Normal file
View File

@ -0,0 +1 @@
100

1
problem-35/data/input Normal file
View File

@ -0,0 +1 @@
1000000

74
problem-35/src/impl.hpp Normal file
View File

@ -0,0 +1,74 @@
/*
* Project Euler Solutions - Core Implementation
* ---------------------------------------------
* Problem : Circular Primes
* URL : https://projecteuler.net/problem=35
*
* Author : erick-alcachofa
* Created : Sunday, August 350 2025
*
* Notes:
* -
*
* License : GNU Affero General Public License v3.0 (AGPLv3)
* https://www.gnu.org/licenses/agpl-3.0.html
*/
#pragma once
#include <cstdint>
#include <sstream>
#include "sieve.hpp"
constexpr const int64_t MaxPrime = 1e6;
static Sieve sieve(MaxPrime);
static int64_t Solve(std::stringstream in) {
int64_t maxN = 0;
in >> maxN;
sieve.Fill();
auto numDigitsAndFactor = [](int64_t n) -> std::pair<int64_t, int64_t> {
int64_t power = 1;
int64_t counter = 0;
while (n > 0) {
counter++;
power *= 10;
n /= 10;
}
return {counter, power / 10};
};
int64_t count = 0;
for (auto prime : sieve) {
if (prime > maxN) {
break;
}
auto [ndigits, pow] = numDigitsAndFactor(prime);
bool isCircular = true;
auto number = prime;
for (int64_t i = 1; i < ndigits; ++i) {
number = ((number % 10) * pow) + (number / 10);
if (not sieve.IsPrime(number)) {
isCircular = false;
break;
}
}
if (isCircular) {
count += 1;
}
}
return count;
}

View File

@ -0,0 +1,40 @@
/*
* Project Euler Solutions - Main Translation Unit
* ------------------------------------------
* Problem : Circular Primes
* URL : https://projecteuler.net/problem=35
*
* Author : erick-alcachofa
* Created : Sunday, August 350 2025
*
* Notes:
* -
*
* License : GNU Affero General Public License v3.0 (AGPLv3)
* https://www.gnu.org/licenses/agpl-3.0.html
*/
#include <iostream>
#include <print>
#include <sstream>
#include <string>
#include "timer.hpp"
#include "impl.hpp"
int main(int, char *[]) {
std::ios_base::sync_with_stdio(false),
std::cin.tie(nullptr),
std::cout.tie(nullptr);
std::string input = R"(@input@)";
decltype(Solve({})) ans = {};
{
Timer<Milliseconds> timer;
ans = Solve(std::stringstream{input});
}
std::println("{}", ans);
}

28
problem-35/src/test.cpp Normal file
View File

@ -0,0 +1,28 @@
/*
* Project Euler Solutions - Test File
* ------------------------------------
* Problem : Circular Primes
* URL : https://projecteuler.net/problem=35
*
* Author : erick-alcachofa
* Created : Sunday, August 350 2025
*
* Notes:
* -
*
* License : GNU Affero General Public License v3.0 (AGPLv3)
* https://www.gnu.org/licenses/agpl-3.0.html
*/
#include <gtest/gtest.h>
#include <sstream>
#include "impl.hpp"
const char *input = R"(@example@)";
TEST(Problem35, test) {
const auto ans = Solve(std::stringstream{input});
EXPECT_EQ(ans, 13);
}

0
problem-37/data/example Normal file
View File

0
problem-37/data/input Normal file
View File

76
problem-37/src/impl.hpp Normal file
View File

@ -0,0 +1,76 @@
/*
* Project Euler Solutions - Core Implementation
* ---------------------------------------------
* Problem : Truncatable Primes
* URL : https://projecteuler.net/problem=37
*
* Author : erick-alcachofa
* Created : Sunday, August 370 2025
*
* Notes:
* -
*
* License : GNU Affero General Public License v3.0 (AGPLv3)
* https://www.gnu.org/licenses/agpl-3.0.html
*/
#pragma once
#include <ranges>
#include <cstdint>
#include <sstream>
#include <functional>
#include "sieve.hpp"
constexpr const int64_t MaxPrime = 1e6;
static Sieve sieve(MaxPrime);
static int64_t Solve(std::stringstream) {
sieve.Fill();
int64_t sum = 0;
int64_t found = 0;
auto numDigitsAndFactor = [](int64_t n) -> std::pair<int64_t, int64_t> {
int64_t power = 1;
int64_t counter = 0;
while (n > 0) {
counter++;
power *= 10;
n /= 10;
}
return {counter, power / 10};
};
auto invalid = std::bind_back(std::less<int64_t>{}, 10);
for (auto prime : sieve | std::views::drop_while(invalid)) {
auto [ndigits, factor] = numDigitsAndFactor(prime);
auto dl = prime;
auto dr = prime;
auto isTruncatable = true;
for (int64_t i = 1; i < ndigits; ++i) {
dl %= factor;
dr /= 10;
factor /= 10;
if (not (sieve.IsPrime(dl) && sieve.IsPrime(dr))) {
isTruncatable = false;
break;
}
}
if (isTruncatable) {
sum += prime;
}
}
return sum;
}

View File

@ -0,0 +1,40 @@
/*
* Project Euler Solutions - Main Translation Unit
* ------------------------------------------
* Problem : Truncatable Primes
* URL : https://projecteuler.net/problem=37
*
* Author : erick-alcachofa
* Created : Sunday, August 370 2025
*
* Notes:
* -
*
* License : GNU Affero General Public License v3.0 (AGPLv3)
* https://www.gnu.org/licenses/agpl-3.0.html
*/
#include <iostream>
#include <print>
#include <sstream>
#include <string>
#include "timer.hpp"
#include "impl.hpp"
int main(int, char *[]) {
std::ios_base::sync_with_stdio(false),
std::cin.tie(nullptr),
std::cout.tie(nullptr);
std::string input = R"(@input@)";
decltype(Solve({})) ans = {};
{
Timer<Milliseconds> timer;
ans = Solve(std::stringstream{input});
}
std::println("{}", ans);
}

28
problem-37/src/test.cpp Normal file
View File

@ -0,0 +1,28 @@
/*
* Project Euler Solutions - Test File
* ------------------------------------
* Problem : Truncatable Primes
* URL : https://projecteuler.net/problem=37
*
* Author : erick-alcachofa
* Created : Sunday, August 370 2025
*
* Notes:
* -
*
* License : GNU Affero General Public License v3.0 (AGPLv3)
* https://www.gnu.org/licenses/agpl-3.0.html
*/
#include <gtest/gtest.h>
#include <sstream>
#include "impl.hpp"
const char *input = R"(@example@)";
TEST(Problem37, test) {
const auto ans = Solve(std::stringstream{input});
EXPECT_EQ(ans, 0);
}

View File

@ -1,7 +1,12 @@
#!/usr/bin/env bash
for i in {1..10}
for i in {1..37}
do
if ! [[ -d problem-$i ]]
then
continue
fi
{
IFS=$'\n' read -r -d '' STDERR;
IFS=$'\n' read -r -d '' STDOUT;