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')