diff --git a/README.rst b/README.rst
index 14cb29cb..27e42d4b 100644
--- a/README.rst
+++ b/README.rst
@@ -60,16 +60,16 @@ Olivia's Project Euler Solutions
+============+============================+========+===================+
| C | C99+ in: |clang|, |br| | 25 | |Ci| |br| |
| | |gcc|, |pcc|, & |tcc| |br| | | |C-Cov| |br| |
-| | C11+ in: |msvc| [1]_ | | |CodeQL| |br| |
-| | | | |C-lint| |
+| | C11+ in: |msvc| [1]_ |br| | | |CodeQL| |br| |
+| | Browser [2]_ | | |C-lint| |
+------------+----------------------------+--------+-------------------+
| C++ | C++98+ in: |br| |clang|, & | 18 | |Cpi| |br| |
| | |gcc| |br| | | |Cp-Cov| |br| |
| | C++14+ in: |msvc| [1]_ | | |CodeQL| |br| |
-| | | | |Cp-lint| |
+| | |br| Browser [3]_ | | |Cp-lint| |
+------------+----------------------------+--------+-------------------+
-| C# | .NET 2+ | 18 | |C#i| |br| |
-| | | | |Cs-Cov| |br| |
+| C# | .NET 2+ |br| | 18 | |C#i| |br| |
+| | Browser [#]_ | | |Cs-Cov| |br| |
| | | | |CodeQL| |br| |
| | | | |C#-lint| |
+------------+----------------------------+--------+-------------------+
@@ -77,6 +77,7 @@ Olivia's Project Euler Solutions
| | Dragonwell, Liberica, |br| | | |Ja-Cov| |br| |
| | Microsoft, Oracle, |br| | | |CodeQL| |br| |
| | Semeru, Temurin, & Zulu | | |Java-lint| |
+| | |br| Browser [#]_ | | |Java-lint| |
+------------+----------------------------+--------+-------------------+
| JavaScript | Node 12+ |br| | 26 | |JavaScript| |br| |
| | Bun 1.0+ |br| | | |Js-Cov| |br| |
@@ -93,6 +94,22 @@ Olivia's Project Euler Solutions
| | | | |RustClippy| |
+------------+----------------------------+--------+-------------------+
+.. |test-c-link| raw:: html
+
+ click here!
+
+.. |test-cp-link| raw:: html
+
+ click here!
+
+.. |test-cs-link| raw:: html
+
+ click here!
+
+.. |test-ja-link| raw:: html
+
+ click here!
+
.. |test-js-link| raw:: html
click here!
@@ -106,6 +123,14 @@ Olivia's Project Euler Solutions
click here!
.. [1] This is the earliest standard the MSVC explicitly supports.
+.. [2] While these solutions do run in most browsers, they need to be bundled with Emscripten first,
+ and these tests not yet automated as in |clang| and |gcc|. To run these tests yourself, |test-c-link|
+.. [3] While these solutions do run in most browsers, they need to be bundled with Emscripten first,
+ and these tests not yet automated as in |clang| and |gcc|. To run these tests yourself, |test-cp-link|
+.. [#] While these solutions do run in most browsers, they need to be bundled with DotNetAnywhere first,
+ and these tests not yet automated as in mainline .NET. To run these tests yourself, |test-cs-link|
+.. [#] While these solutions do run in most browsers, they need to be bundled with CheerpJ first,
+ and these tests not yet automated as in mainline Java. To run these tests yourself, |test-ja-link|
.. [#] While these solutions do run in most browsers, they need to be bundled with WebPack 5.93+ & Babel 7.25+ first,
and these tests not yet automated as in Nodejs and Bun. To run these tests yourself, |test-js-link|
.. [#] While these solutions do run in most browsers, they need to be bundled with Pyodide 0.26.2+ first, and these
diff --git a/cplusplus/src/include/macros.hpp b/cplusplus/src/include/macros.hpp
index 751f5f03..8c11b9b0 100644
--- a/cplusplus/src/include/macros.hpp
+++ b/cplusplus/src/include/macros.hpp
@@ -18,6 +18,11 @@
#else
#define GCC_COMPILER 0
#endif
+#ifdef __EMSCRIPTEN__
+ #define EMCC_COMPILER 1
+#else
+ #define EMCC_COMPILER 0
+#endif
#if (defined(_M_X64) || defined(_M_AMD64) || defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64))
#define X64_COMPILER 1
@@ -38,6 +43,13 @@
#define ARM_THUMB 1
#else
#define ARM_THUMB 0
+#
+#if (defined(__wasm__) || defined(__wasm32__) || defined(__wasm64__))
+ #define WASM_COMPILER 1
+ #include
+#else
+ #define WASM_COMPILER 0
+ #define EMSCRIPTEN_KEEPALIVE
#endif
// helper macro function section
diff --git a/cplusplus/src/p0000_template.cpp b/cplusplus/src/p0000_template.cpp
index c16b47e3..41102d6e 100644
--- a/cplusplus/src/p0000_template.cpp
+++ b/cplusplus/src/p0000_template.cpp
@@ -11,8 +11,9 @@ This paragraph should be replaced by the problem description, excluding images.
#define EULER_P0000
#include
#include
+#include "../macros.hpp"
-uint64_t p0000() {
+uint64_t EMSCRIPTEN_KEEPALIVE p0000() {
return 0;
}
diff --git a/cplusplus/src/p0001.cpp b/cplusplus/src/p0001.cpp
index 6b668681..b020e0f0 100644
--- a/cplusplus/src/p0001.cpp
+++ b/cplusplus/src/p0001.cpp
@@ -16,8 +16,9 @@
#define EULER_P0001
#include
#include
+#include "../macros.hpp"
-uint64_t p0001() {
+uint64_t EMSCRIPTEN_KEEPALIVE p0001() {
uint64_t answer = 0;
for (int i = 0; i < 1000; i += 3)
answer += i;
diff --git a/cplusplus/src/p0002.cpp b/cplusplus/src/p0002.cpp
index f877a577..51ee988b 100644
--- a/cplusplus/src/p0002.cpp
+++ b/cplusplus/src/p0002.cpp
@@ -18,8 +18,9 @@ four million, find the sum of the even-valued terms.
#define EULER_P0002
#include
#include
+#include "../macros.hpp"
-uint64_t p0002() {
+uint64_t EMSCRIPTEN_KEEPALIVE p0002() {
uint64_t answer = 0,
a = 1, b = 2, t;
while (b < 4000000) {
diff --git a/cplusplus/src/p0004.cpp b/cplusplus/src/p0004.cpp
index e95ae437..b92d3b1c 100644
--- a/cplusplus/src/p0004.cpp
+++ b/cplusplus/src/p0004.cpp
@@ -16,8 +16,9 @@ Find the largest palindrome made from the product of two 3-digit numbers.
#include
#include
#include
+#include "../macros.hpp"
-uint32_t p0004() {
+uint32_t EMSCRIPTEN_KEEPALIVE p0004() {
uint32_t answer = 0, i, j, prod;
for (i = 100; i < 1000; i++) {
for (j = 100; j < 1000; j++) {
diff --git a/cplusplus/src/p0006.cpp b/cplusplus/src/p0006.cpp
index 8a28fd44..c32f61b9 100644
--- a/cplusplus/src/p0006.cpp
+++ b/cplusplus/src/p0006.cpp
@@ -23,8 +23,9 @@ natural numbers and the square of the sum.
#define EULER_P0006
#include
#include
+#include "../macros.hpp"
-uint64_t p0006() {
+uint64_t EMSCRIPTEN_KEEPALIVE p0006() {
uint64_t sum = 100 * 101 / 2, sum_of_squares = 0;
for (uint64_t i = 1; i < 101; i++)
sum_of_squares += i * i;
diff --git a/cplusplus/src/p0008.cpp b/cplusplus/src/p0008.cpp
index 4d034c5d..83a3ae71 100644
--- a/cplusplus/src/p0008.cpp
+++ b/cplusplus/src/p0008.cpp
@@ -34,8 +34,9 @@ Find the thirteen adjacent digits in the 1000-digit number that have the greates
#define EULER_P0008
#include
#include
+#include "../macros.hpp"
-uint64_t p0008() {
+uint64_t EMSCRIPTEN_KEEPALIVE p0008() {
size_t i, j;
uint64_t answer = 0, tmp;
const char *plain_digits = ("73167176531330624919225119674426574742355349194934"
diff --git a/cplusplus/src/p0009.cpp b/cplusplus/src/p0009.cpp
index 16d7994f..533bea89 100644
--- a/cplusplus/src/p0009.cpp
+++ b/cplusplus/src/p0009.cpp
@@ -17,8 +17,9 @@ Find the product abc.
#define EULER_P0009
#include
#include
+#include "../macros.hpp"
-uint64_t p0009() {
+uint64_t EMSCRIPTEN_KEEPALIVE p0009() {
uint64_t answer = 0;
for (uint32_t c = 3; !answer && c < 1000; c++) {
for (uint32_t b = 2; b < c; b++) {
diff --git a/cplusplus/src/p0011.cpp b/cplusplus/src/p0011.cpp
index 5183bf39..e3ea72c2 100644
--- a/cplusplus/src/p0011.cpp
+++ b/cplusplus/src/p0011.cpp
@@ -35,6 +35,7 @@ the 20×20 grid?
#define EULER_P0011
#include
#include
+#include "../macros.hpp"
static const uint8_t grid[20][20] = {
{ 8, 2, 22, 97, 38, 15, 0, 40, 0, 75, 4, 5, 7, 78, 52, 12, 50, 77, 91, 8},
@@ -59,7 +60,7 @@ static const uint8_t grid[20][20] = {
{ 1, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 1, 89, 19, 67, 48}
};
-uint64_t p0011() {
+uint64_t EMSCRIPTEN_KEEPALIVE p0011() {
uint64_t answer = 0, tmp;
uint8_t i, j;
for (i = 0; i < 20; i++) {
diff --git a/cplusplus/src/p0013.cpp b/cplusplus/src/p0013.cpp
index e5d3e843..36d2c19d 100644
--- a/cplusplus/src/p0013.cpp
+++ b/cplusplus/src/p0013.cpp
@@ -109,6 +109,7 @@ Work out the first ten digits of the sum of the following one-hundred 50-digit n
#define EULER_P0013
#include
#include
+#include "../macros.hpp"
static const uint64_t numbers[100][3] = {
{ 37107287533902, 102798797998220837, 590246510135740250 },
@@ -215,7 +216,7 @@ static const uint64_t numbers[100][3] = {
static const uint64_t ten18 = 1000000000000000000;
static const uint64_t ten10 = 10000000000;
-uint64_t p0013() {
+uint64_t EMSCRIPTEN_KEEPALIVE p0013() {
uint64_t high = 0, med = 0, low = 0;
for (uint8_t i = 0; i < 100; ++i) {
low += numbers[i][2];
diff --git a/cplusplus/src/p0014.cpp b/cplusplus/src/p0014.cpp
index 394de22d..fa9961a9 100644
--- a/cplusplus/src/p0014.cpp
+++ b/cplusplus/src/p0014.cpp
@@ -24,6 +24,7 @@ NOTE: Once the chain starts the terms are allowed to go above one million.
#define EULER_P0014
#include
#include
+#include "../macros.hpp"
#define CACHE_SIZE 1000000
static uint32_t collatz_len_cache[CACHE_SIZE] = {0, 1, 0};
@@ -43,7 +44,7 @@ uint32_t collatz_len(uint64_t n) {
return ret;
}
-uint64_t p0014() {
+uint64_t EMSCRIPTEN_KEEPALIVE p0014() {
uint64_t answer = 2, length = 2, tmp;
for (uint64_t test = 3; test < 1000000; test++) {
tmp = collatz_len(test);
diff --git a/cplusplus/src/p0015.cpp b/cplusplus/src/p0015.cpp
index 3a40093b..a6787f98 100644
--- a/cplusplus/src/p0015.cpp
+++ b/cplusplus/src/p0015.cpp
@@ -18,11 +18,12 @@ How many such routes are there through a 20×20 grid?
#define EULER_P0015
#include
#include
+#include "../macros.hpp"
#include "include/math.hpp"
#define lattice_paths(height, width) (n_choose_r(height + width, height))
-uint64_t p0015() {
+uint64_t EMSCRIPTEN_KEEPALIVE p0015() {
return lattice_paths(20, 20);
}
diff --git a/cplusplus/src/p0016.cpp b/cplusplus/src/p0016.cpp
index 56ea8f96..0ab12316 100644
--- a/cplusplus/src/p0016.cpp
+++ b/cplusplus/src/p0016.cpp
@@ -12,9 +12,10 @@ What is the sum of the digits of the number 2**1000?
#include
#include
#include
+#include "../macros.hpp"
-uint64_t p0016() {
+uint64_t EMSCRIPTEN_KEEPALIVE p0016() {
std::vector numbers(18, 0);
const uint64_t ten17 = 100000000000000000;
numbers[0] = 1;
diff --git a/cplusplus/src/p0017.cpp b/cplusplus/src/p0017.cpp
index 3946f263..c22bbb7c 100644
--- a/cplusplus/src/p0017.cpp
+++ b/cplusplus/src/p0017.cpp
@@ -23,6 +23,7 @@ British usage.
#include
#include
#include
+#include "../macros.hpp"
std::string ToString(uint64_t n);
std::string ToString(uint64_t n) {
@@ -93,7 +94,7 @@ std::string ToString(uint64_t n) {
}
}
-uint64_t p0017() {
+uint64_t EMSCRIPTEN_KEEPALIVE p0017() {
uint64_t answer = 0;
for (uint32_t x = 1; x < 1001; x += 1) {
std::string str = ToString(x);
diff --git a/cplusplus/src/p0019.cpp b/cplusplus/src/p0019.cpp
index 0e0c691b..a107f51a 100644
--- a/cplusplus/src/p0019.cpp
+++ b/cplusplus/src/p0019.cpp
@@ -26,6 +26,7 @@ How many Sundays fell on the first of the month during the twentieth century
#include
#include
#include
+#include "../macros.hpp"
#ifdef _WIN32
#include
@@ -34,7 +35,7 @@ How many Sundays fell on the first of the month during the twentieth century
#include
#endif
-uint16_t p0019() {
+uint16_t EMSCRIPTEN_KEEPALIVE p0019() {
uint16_t answer = 0;
#ifdef _WIN32
diff --git a/cplusplus/src/p0020.cpp b/cplusplus/src/p0020.cpp
index 50dea2a7..2fdc612f 100644
--- a/cplusplus/src/p0020.cpp
+++ b/cplusplus/src/p0020.cpp
@@ -15,9 +15,10 @@ Find the sum of the digits in the number 100!
#include
#include
#include
+#include "../macros.hpp"
-uint64_t p0020() {
+uint64_t EMSCRIPTEN_KEEPALIVE p0020() {
std::vector numbers(10, 0);
const uint64_t ten17 = 100000000000000000;
numbers[0] = 1;
diff --git a/cplusplus/src/p0022.cpp b/cplusplus/src/p0022.cpp
index bcd60e26..bd4971e9 100644
--- a/cplusplus/src/p0022.cpp
+++ b/cplusplus/src/p0022.cpp
@@ -18,9 +18,10 @@
#include
#include
#include
+#include "../macros.hpp"
#include "include/utils.hpp"
-uint64_t p0022() {
+uint64_t EMSCRIPTEN_KEEPALIVE p0022() {
uint64_t answer = 0;
std::string fstring = get_data_file("p0022_names.txt");
const uint32_t name_count = 5163;
diff --git a/cplusplus/src/p0034.cpp b/cplusplus/src/p0034.cpp
index 942c2a20..e82359cb 100644
--- a/cplusplus/src/p0034.cpp
+++ b/cplusplus/src/p0034.cpp
@@ -15,9 +15,10 @@ Note: as 1! = 1 and 2! = 2 are not sums they are not included.
#include
#include
#include
+#include "../macros.hpp"
#include "include/math.hpp"
-uint64_t p0034() {
+uint64_t EMSCRIPTEN_KEEPALIVE p0034() {
uint64_t answer = 0, sum;
for (uint64_t i = 10; i < 100000; i++) {
sum = 0;
diff --git a/cplusplus/src/p0076.cpp b/cplusplus/src/p0076.cpp
index e2f35403..7b45ab22 100644
--- a/cplusplus/src/p0076.cpp
+++ b/cplusplus/src/p0076.cpp
@@ -44,7 +44,7 @@ positive integers?
#include
#include "include/macros.hpp"
-uint32_t p0076() {
+uint32_t EMSCRIPTEN_KEEPALIVE p0076() {
uint32_t answer = 0;
uint8_t idx, i, sum = 100, counts[101] = {0, 0, 100, 0};
while (!counts[100]) {
diff --git a/cplusplus/src/p0836.cpp b/cplusplus/src/p0836.cpp
index a2cb0564..0f96a1e8 100644
--- a/cplusplus/src/p0836.cpp
+++ b/cplusplus/src/p0836.cpp
@@ -17,8 +17,9 @@ Find f(20230401, 57). Give as your answer the concatenation of the first letters
#ifndef EULER_P0836
#define EULER_P0836
#include
+#include "../macros.hpp"
-std::string p0836() {
+std::string EMSCRIPTEN_KEEPALIVE p0836() {
return "aprilfoolsjoke";
}
diff --git a/cplusplus/src/tests/test_compiler_macros.cpp b/cplusplus/src/tests/test_compiler_macros.cpp
index 42291619..48769d4b 100644
--- a/cplusplus/src/tests/test_compiler_macros.cpp
+++ b/cplusplus/src/tests/test_compiler_macros.cpp
@@ -3,13 +3,15 @@
int main(int argc, char const *argv[]) {
printf(
- "%d %d %d %d %d %d",
+ "%d %d %d %d %d %d %d %d",
CL_COMPILER,
CLANG_COMPILER,
GCC_COMPILER,
+ EMCC_COMPILER,
X86_COMPILER,
X64_COMPILER,
- ARM_COMPILER
+ ARM_COMPILER,
+ WASM_COMPILER
);
return 0;
}
diff --git a/cplusplus/test_euler.py b/cplusplus/test_euler.py
index f4525f25..5fc985c8 100644
--- a/cplusplus/test_euler.py
+++ b/cplusplus/test_euler.py
@@ -211,9 +211,11 @@ def test_compiler_macros(compiler):
assert flags[0] == compiler.startswith("CL+")
assert flags[1] == compiler.startswith("CLANG")
assert flags[2] == compiler.startswith("GCC")
- assert flags[3] == (EXE_EXT == "x86" or expect_32)
- assert flags[4] == (EXE_EXT == "x86_64" and not expect_32)
- assert flags[5] == (EXE_EXT not in ("x86", "x86_64", "exe"))
+ assert flags[3] == compiler.startswith("EMCC")
+ assert flags[4] == (EXE_EXT == "x86" or expect_32)
+ assert flags[5] == (EXE_EXT == "x86_64" and not expect_32)
+ assert flags[6] == ("arm" in EXE_EXT.lower())
+ assert flags[7] == ("wasm" in EXE_EXT.lower())
# @mark.skipif('NO_OPTIONAL_TESTS or ONLY_SLOW')