diff --git a/.gitignore b/.gitignore
index 74ab857f..bb4f20a6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,11 +18,10 @@ csharp/*/obj
csharp/*/bin
**/TestResults
docs/_build
-rust/target
+*/target
**/.coverage
**/.coverage.*
**/coverage
**/dist/*
-docs/_static/test-js.html
javascript/src/lib/fallbacks
-java/target
\ No newline at end of file
+docs/languages*.svg
\ No newline at end of file
diff --git a/README.rst b/README.rst
index 10de4c58..e32f8001 100644
--- a/README.rst
+++ b/README.rst
@@ -80,16 +80,16 @@ Olivia's Project Euler Solutions
+------------+----------------------------+--------+-------------------+
| JavaScript | Node 12+ |br| | 25 | |JavaScript| |br| |
| | Bun 1.0+ |br| | | |Js-Cov| |br| |
-| | Browser [2]_ | | |CodeQL| |br| |
+| | Browser [#]_ | | |CodeQL| |br| |
| | | | |ESLint| |
+------------+----------------------------+--------+-------------------+
| Python | CPython 3.6+ |br| | 79 | |Python| |br| |
| | Pypy 3.6+ |br| | | |Py-Cov| |br| |
| | GraalPy 23.1+ |br| | | |CodeQL| |br| |
-| | Browser [3]_ | | |PythonLint| |
+| | Browser [#]_ | | |PythonLint| |
+------------+----------------------------+--------+-------------------+
| Rust | 1.69+ |br| | 28 | |Rust| |br| |
-| | Browser [4]_ | | |Rs-Cov| |br| |
+| | Browser [#]_ | | |Rs-Cov| |br| |
| | | | |RustClippy| |
+------------+----------------------------+--------+-------------------+
@@ -106,11 +106,11 @@ 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 WebPack 5.93+ & Babel 7.25+ first,
+.. [#] 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|
-.. [3] While these solutions do run in most browsers, they need to be bundled with Pyodide 0.26.2+ first, and these
+.. [#] While these solutions do run in most browsers, they need to be bundled with Pyodide 0.26.2+ first, and these
tests are not yet automated as in CPython and pypy. To run these tests yourself, |test-py-link|
-.. [4] While these solutions will run in most browsers, they need to be bundled with wasm-pack 0.2+ first, and these
+.. [#] While these solutions will run in most browsers, they need to be bundled with wasm-pack 0.2+ first, and these
tests are not yet automated as on non-web platforms. To run these tests yourself, |test-rs-link|
Coverage
diff --git a/c/src/include/bcd.h b/c/src/include/bcd.h
index 741f0e16..2bdfec29 100644
--- a/c/src/include/bcd.h
+++ b/c/src/include/bcd.h
@@ -20,13 +20,41 @@ typedef struct {
size_t decimal_digits;
bool negative : 1;
bool zero : 1;
+ bool even : 1;
+ bool constant : 1;
} BCD_int;
+
+const BCD_int BCD_two = {
+ .digits = (packed_BCD_pair[]) {2},
+ .bcd_digits = 1,
+ .decimal_digits = 1,
+ .even = true,
+ .constant = true
+}; // note that non-specified values are initialized to NULL or 0
+
+
+const BCD_int BCD_one = {
+ .digits = (packed_BCD_pair[]) {1},
+ .bcd_digits = 1,
+ .decimal_digits = 1,
+ .constant = true
+}; // note that non-specified values are initialized to NULL or 0
+
+
+const BCD_int BCD_zero = {
+ .zero = true,
+ .even = true,
+ .constant = true
+}; // note that non-specified values are initialized to NULL or 0
+
void free_BCD_int(BCD_int x);
inline void free_BCD_int(BCD_int x) {
- free(x.digits);
- x.digits = NULL;
- x.bcd_digits = x.decimal_digits = x.negative = x.zero = 0;
+ if (!x.constant) {
+ free(x.digits);
+ x.digits = NULL;
+ x.bcd_digits = x.decimal_digits = x.negative = x.zero = 0;
+ }
}
BCD_int new_BCD_int(uintmax_t a, bool negative) {
@@ -539,6 +567,12 @@ inline BCD_int shift_bcd_right(BCD_int a, uintmax_t tens) {
return div_bcd_pow_10(a, tens);
}
+void iadd_bcd(BCD_int *const x, const BCD_int y) {
+ BCD_int ret = add_bcd(*x, y);
+ free_BCD_int(*x);
+ *x = ret;
+}
+
uintmax_t bcd_to_unsigned(BCD_int a) {
if (a.zero)
return 0;
diff --git a/c/src/include/macros.h b/c/src/include/macros.h
index 972aca79..3688efca 100644
--- a/c/src/include/macros.h
+++ b/c/src/include/macros.h
@@ -65,6 +65,10 @@
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
+#ifndef swap
+ #define swap(x, y, T) do { T SWAP = x; x = y; y = SWAP; } while (0)
+#endif
+
#if !(CL_COMPILER || TCC_COMPILER)
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
diff --git a/c/src/p0022.c b/c/src/p0022.c
index 42c2243b..02a305e7 100644
--- a/c/src/p0022.c
+++ b/c/src/p0022.c
@@ -1,17 +1,17 @@
-/**
- * Project Euler Problem 22
- *
- * I know that this could be done faster with a traditional for loop, but I wanted
- * to see if iterators were reasonably possible in C, since it makes the prime
- * number infrastructure a lot easier to set up.
- *
- * Problem:
- *
- * If we list all the natural numbers below 10 that are multiples of 3 or 5, we
- * get 3, 5, 6 and 9. The sum of these multiples is 23.
- *
- * Find the sum of all the multiples of 3 or 5 below 1000.
- */
+/*
+Project Euler Problem 22
+
+I know that this could be done faster with a traditional for loop, but I wanted
+to see if iterators were reasonably possible in C, since it makes the prime
+number infrastructure a lot easier to set up.
+
+Problem:
+
+If we list all the natural numbers below 10 that are multiples of 3 or 5, we
+get 3, 5, 6 and 9. The sum of these multiples is 23.
+
+Find the sum of all the multiples of 3 or 5 below 1000.
+*/
#ifndef EULER_P0022
#define EULER_P0022
#include
diff --git a/c/src/p0025.c b/c/src/p0025.c
new file mode 100644
index 00000000..d1274c39
--- /dev/null
+++ b/c/src/p0025.c
@@ -0,0 +1,54 @@
+/*
+Project Euler Problem 25
+
+Problem:
+
+The Fibonacci sequence is defined by the recurrence relation:
+
+ Fn = Fn−1 + Fn−2, where F1 = 1 and F2 = 1.
+
+Hence the first 12 terms will be:
+
+ F1 = 1
+ F2 = 1
+ F3 = 2
+ F4 = 3
+ F5 = 5
+ F6 = 8
+ F7 = 13
+ F8 = 21
+ F9 = 34
+ F10 = 55
+ F11 = 89
+ F12 = 144
+
+The 12th term, F12, is the first term to contain three digits.
+
+What is the index of the first term in the Fibonacci sequence to contain 1000 digits?
+*/
+#ifndef EULER_P0025
+#define EULER_P0025
+#include
+#include "include/bcd.h"
+
+unsigned long long p0025() {
+ unsigned long long answer = 2;
+ BCD_int a = BCD_one, b = BCD_one;
+ while (b.decimal_digits < 1000) {
+ iadd_bcd(&a, b);
+ swap(a, b, BCD_int);
+ answer++;
+ }
+ free_BCD_int(a);
+ free_BCD_int(b);
+ return answer;
+}
+
+#ifndef UNITY_END
+int main(int argc, char const *argv[]) {
+ unsigned long long answer = p0025();
+ printf("%llu\n", answer);
+ return 0;
+}
+#endif
+#endif
diff --git a/c/src/p0030.c b/c/src/p0030.c
new file mode 100644
index 00000000..ab6313dd
--- /dev/null
+++ b/c/src/p0030.c
@@ -0,0 +1,47 @@
+/*
+Project Euler Problem 30
+
+Problem:
+
+Surprisingly there are only three numbers that can be written as the sum of fourth powers of their digits:
+
+ 1634 = 1^4 + 6^4 + 3^4 + 4^4
+ 8208 = 8^4 + 2^4 + 0^4 + 8^4
+ 9474 = 9^4 + 4^4 + 7^4 + 4^4
+
+As 1 = 1^4 is not a sum it is not included.
+
+The sum of these numbers is 1634 + 8208 + 9474 = 19316.
+
+Find the sum of all the numbers that can be written as the sum of fifth powers of their digits.
+*/
+#ifndef EULER_P0030
+#define EULER_P0030
+#include
+#include "include/digits.h"
+
+unsigned long long p0030() {
+ unsigned long long answer = 0, sum, tmp;
+ for (unsigned long long i = 2; i < 1000000; i++) {
+ digit_counter dc = digits(i);
+ sum = 0;
+ while (!dc.exhausted) {
+ tmp = next(dc);
+ sum += tmp * tmp * tmp * tmp * tmp;
+ }
+ if (sum == i) {
+ answer += i;
+ }
+ free_digit_counter(dc);
+ }
+ return answer;
+}
+
+#ifndef UNITY_END
+int main(int argc, char const *argv[]) {
+ unsigned long long answer = p0030();
+ printf("%llu\n", answer);
+ return 0;
+}
+#endif
+#endif
diff --git a/c/test.c b/c/test.c
index 690f4994..9ced1bdf 100644
--- a/c/test.c
+++ b/c/test.c
@@ -19,6 +19,8 @@
#include "src/p0017.c"
#include "src/p0020.c"
#include "src/p0022.c"
+#include "src/p0025.c"
+#include "src/p0030.c"
#include "src/p0034.c"
#include "src/p0076.c"
#include "src/p0836.c"
@@ -48,6 +50,8 @@ const Answer answers[] = {
{17, 21124, p0017},
{20, 648, p0020},
{22, 871198282, p0022},
+ {25, 4782, p0025},
+ {30, 443839, p0030},
{34, 40730, p0034},
{76, 190569291, (unsigned long long (*)()) p0076},
};
diff --git a/c/test_euler.py b/c/test_euler.py
index aad73a72..aff51c37 100644
--- a/c/test_euler.py
+++ b/c/test_euler.py
@@ -25,6 +25,8 @@
*range(1, 18),
20,
22,
+ 25,
+ 30,
34,
76,
836,
diff --git a/docs/index.rst b/docs/index.rst
index fc051ea9..cb5f2853 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -124,7 +124,7 @@ Problems Solved
+-----------+------------+------------+------------+------------+------------+------------+------------+
|:prob:`24` | | | | | |:py-d:`0024`|:rs-d:`0024`|
+-----------+------------+------------+------------+------------+------------+------------+------------+
-|:prob:`25` | | | | | |:py-d:`0025`| |
+|:prob:`25` |:c-i:`0025` | | | | |:py-d:`0025`| |
+-----------+------------+------------+------------+------------+------------+------------+------------+
|:prob:`27` | | | | |:js-d:`0027`|:py-d:`0027`|:rs-d:`0027`|
+-----------+------------+------------+------------+------------+------------+------------+------------+
@@ -132,7 +132,7 @@ Problems Solved
+-----------+------------+------------+------------+------------+------------+------------+------------+
|:prob:`29` | | | | | |:py-d:`0029`| |
+-----------+------------+------------+------------+------------+------------+------------+------------+
-|:prob:`30` | | | | | |:py-d:`0030`| |
+|:prob:`30` |:c-d:`0030` | | | | |:py-d:`0030`| |
+-----------+------------+------------+------------+------------+------------+------------+------------+
|:prob:`31` | | | | | |:py-d:`0031`| |
+-----------+------------+------------+------------+------------+------------+------------+------------+
diff --git a/docs/src/c/lib/bcd.rst b/docs/src/c/lib/bcd.rst
index 5e79565f..982d332d 100644
--- a/docs/src/c/lib/bcd.rst
+++ b/docs/src/c/lib/bcd.rst
@@ -83,6 +83,10 @@ It was also a good exercise in x86 assembly, as several portions are accellerate
Returns ``x // 10**tens``.
+.. c:function:: void iadd_bcd(BCD_int *const x, const BCD_int y)
+
+ Transforms ``x`` to be ``x + y`` without needing to make a new assignment.
+
.. c:function:: signed char cmp_bcd(BCD_int x, BCD_int y)
Returns 1 if ``x > y``, -1 if ``y > x``, and otherwise 0.
diff --git a/docs/src/c/p0025.rst b/docs/src/c/p0025.rst
new file mode 100644
index 00000000..ad5cd4ec
--- /dev/null
+++ b/docs/src/c/p0025.rst
@@ -0,0 +1,25 @@
+C Implementation of Problem 25
+==============================
+
+View source code :source:`c/src/p0025.c`
+
+Includes
+--------
+
+- `bcd.h <./lib/bcd.html>`__
+
+Solution
+--------
+
+.. c:function:: unsigned long long p0025()
+
+.. c:function:: int main(int argc, char const *argv[])
+
+ .. note::
+
+ This function is only present in the Python test runner, or when compiling as a standalone program.
+ It is not present when compiling for the Unity test runner.
+
+.. literalinclude:: ../../../c/src/p0025.c
+ :language: C
+ :linenos:
diff --git a/docs/src/c/p0030.rst b/docs/src/c/p0030.rst
new file mode 100644
index 00000000..2f97e8d6
--- /dev/null
+++ b/docs/src/c/p0030.rst
@@ -0,0 +1,25 @@
+C Implementation of Problem 30
+==============================
+
+View source code :source:`c/src/p0030.c`
+
+Includes
+--------
+
+- `digits.h <./lib/digits.html>`__
+
+Solution
+--------
+
+.. c:function:: unsigned long long p0030()
+
+.. c:function:: int main(int argc, char const *argv[])
+
+ .. note::
+
+ This function is only present in the Python test runner, or when compiling as a standalone program.
+ It is not present when compiling for the Unity test runner.
+
+.. literalinclude:: ../../../c/src/p0030.c
+ :language: C
+ :linenos: