diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 24fd6f33..d1dbf543 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -21,6 +21,7 @@ on:
- 'c/**'
- 'cplusplus/**'
- 'csharp/**'
+ - 'java/**'
- 'javascript/**'
- 'python/**'
- '!*/README.rst'
@@ -60,6 +61,9 @@ jobs:
- name: csharp
language: csharp
build-mode: none
+ - name: java
+ language: java-kotlin
+ build-mode: none
- name: javascript
language: javascript-typescript
build-mode: none
diff --git a/.github/workflows/java-lint.yml b/.github/workflows/java-lint.yml
new file mode 100644
index 00000000..4fc08d7a
--- /dev/null
+++ b/.github/workflows/java-lint.yml
@@ -0,0 +1,44 @@
+name: Java Lint
+
+on:
+ push:
+ paths:
+ - 'java/**'
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Set up Git
+ run: git config --global user.email "actions@github.com" && git config --global user.name "GitHub Actions"
+
+ - name: Checkout code
+ uses: actions/checkout@v3
+
+ - name: Set up Java
+ uses: actions/setup-java@v3
+ with:
+ java-version: '21'
+ distribution: 'adopt'
+
+ - name: Build with Maven
+ run: make ja_dependencies
+
+ - name: Run linter
+ run: make ja_lint
+
+ - name: Check for differences
+ run: |
+ # Get the diff from the last commit to the current working tree
+ if [ -n "$(git diff HEAD)" ]; then
+ echo "There are changes detected:"
+ git diff HEAD
+ exit 1
+ else
+ echo "No changes detected."
+ fi
\ No newline at end of file
diff --git a/.github/workflows/java.yml b/.github/workflows/java.yml
new file mode 100644
index 00000000..1be4f94d
--- /dev/null
+++ b/.github/workflows/java.yml
@@ -0,0 +1,47 @@
+name: Java
+
+on:
+ push:
+ paths:
+ - 'java/**'
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ test:
+ strategy:
+ matrix:
+ os: ['ubuntu-latest']
+ java-version: [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
+ include:
+ - os: windows-latest
+ java-version: 21
+ - os: macos-latest
+ java-version: 21
+ - os: macos-13
+ java-version: 21
+
+ runs-on: ${{ matrix.os }}
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+
+ - name: Set up Java
+ uses: actions/setup-java@v3
+ with:
+ java-version: ${{ matrix.java-version }}
+ distribution: 'adopt'
+
+ - name: Build with Maven
+ run: make ja_dependencies
+
+ - name: Run tests
+ run: make ja_test
+
+ - name: Upload code coverage to Codecov
+ uses: codecov/codecov-action@v3
+ with:
+ files: '**.xml'
\ No newline at end of file
diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
index 7f6ee792..53f02dae 100644
--- a/.github/workflows/pages.yml
+++ b/.github/workflows/pages.yml
@@ -10,6 +10,7 @@ on:
- '**/*.cpp'
- '**/*.cs'
- '**/*.h'
+ - '**/*.java'
- '**/*.js'
- '**/*.py'
- '**/*.rs'
diff --git a/Makefile b/Makefile
index 9d25f446..0f98b450 100644
--- a/Makefile
+++ b/Makefile
@@ -23,9 +23,9 @@ help:
@echo
@echo "The following jobs are available under the cs_ prefix"
@$(MAKE) cs_help $(MFLAGS) --no-print-directory
-# @echo
-# @echo "The following jobs are available under the ja_ prefix"
-# @$(MAKE) ja_help $(MFLAGS) --no-print-directory
+ @echo
+ @echo "The following jobs are available under the ja_ prefix"
+ @$(MAKE) ja_help $(MFLAGS) --no-print-directory
@echo
@echo "The following jobs are available under the js_ prefix"
@$(MAKE) js_help $(MFLAGS) --no-print-directory
@@ -54,8 +54,8 @@ c_%:
docs_%:
@cd docs && $(MAKE) $* $(MFLAGS)
-# ja_%:
-# @cd java && $(MAKE) $* $(MFLAGS)
+ja_%:
+ @cd java && $(MAKE) $* $(MFLAGS)
js_%:
@cd javascript && $(MAKE) $* $(MFLAGS)
diff --git a/README.rst b/README.rst
index 705c1cf9..45265323 100644
--- a/README.rst
+++ b/README.rst
@@ -13,6 +13,10 @@ Olivia's Project Euler Solutions
:target: https://github.com/LivInTheLookingGlass/Euler/actions/workflows/csharp.yml
.. |C#-lint| image:: https://img.shields.io/github/actions/workflow/status/LivInTheLookingGlass/Euler/csharp-lint.yml?logo=github&label=Linting
:target: https://github.com/LivInTheLookingGlass/Euler/actions/workflows/csharp-lint.yml
+.. |Javai| image:: https://img.shields.io/github/actions/workflow/status/LivInTheLookingGlass/Euler/java.yml?logo=github&label=Java%20Tests
+ :target: https://github.com/LivInTheLookingGlass/Euler/actions/workflows/java.yml
+.. |Java-lint| image:: https://img.shields.io/github/actions/workflow/status/LivInTheLookingGlass/Euler/java-lint.yml?logo=github&label=Linting
+ :target: https://github.com/LivInTheLookingGlass/Euler/actions/workflows/java-lint.yml
.. |JavaScript| image:: https://img.shields.io/github/actions/workflow/status/LivInTheLookingGlass/Euler/javascript.yml?logo=github&label=Js%20Tests
:target: https://github.com/LivInTheLookingGlass/Euler/actions/workflows/javascript.yml
.. |ESLint| image:: https://img.shields.io/github/actions/workflow/status/LivInTheLookingGlass/Euler/eslint.yml?logo=github&label=ESLint
@@ -33,6 +37,8 @@ Olivia's Project Euler Solutions
:target: https://app.codecov.io/github/LivInTheLookingGlass/Euler?flags%5B0%5D=Cpp
.. |Cs-Cov| image:: https://img.shields.io/codecov/c/github/LivInTheLookingGlass/Euler?flag=Csharp&logo=codecov&label=C%23%20Cov
:target: https://app.codecov.io/github/LivInTheLookingGlass/Euler?flags%5B0%5D=Csharp
+.. |Ja-Cov| image:: https://img.shields.io/codecov/c/github/LivInTheLookingGlass/Euler?flag=Java&logo=codecov&label=Java20Cov
+ :target: https://app.codecov.io/github/LivInTheLookingGlass/Euler?flags%5B0%5D=Java
.. |Js-Cov| image:: https://img.shields.io/codecov/c/github/LivInTheLookingGlass/Euler?flag=JavaScript&logo=codecov&label=Js%20Cov
:target: https://app.codecov.io/github/LivInTheLookingGlass/Euler?flags%5B0%5D=JavaScript
.. |Py-Cov| image:: https://img.shields.io/codecov/c/github/LivInTheLookingGlass/Euler?flag=Python&logo=codecov&label=Py%20Cov
@@ -67,6 +73,11 @@ Olivia's Project Euler Solutions
| | | | |CodeQL| |br| |
| | | | |C#-lint| |
+------------+--------------------------+--------+-------------------+
+| Java | Java 8+ | 2 | |Javai| |br| |
+| | | | |Java-Cov| |br| |
+| | | | |CodeQL| |br| |
+| | | | |Java-lint| |
++------------+--------------------------+--------+-------------------+
| JavaScript | Node 12+ |br| | 20 | |JavaScript| |br| |
| | Bun 1.0+ |br| | | |Js-Cov| |br| |
| | Firefox [2]_ |br| | | |CodeQL| |br| |
@@ -124,6 +135,7 @@ Makefile will direct recipes using prefixes
- ``make cp_*`` will go to the csharp Makefile
- ``make cs_*`` will go to the csharp Makefile
- ``make docs_*`` will go to the docs Makefile
+- ``make ja_*`` will go to the java Makefile
- ``make js_*`` will go to the javascript Makefile
- ``make py_*`` will go to the python Makefile
- ``make rs_*`` will go to the rust Makefile
@@ -131,14 +143,3 @@ Makefile will direct recipes using prefixes
- All other recipes will be run for all languages
For more information, please see the README documents in each section.
-
-Roadmap
--------
-
-1. Make sure no language is below Makefile in code percentage
-2. For each language in: Ruby, ...
- a. Create a new section
- b. Make stubs for test code
- c. Write minimal documentation
- d. Port problems 1-n, until higher than Makefile percentage
- e. Repeat step 1
diff --git a/docs/conf.py b/docs/conf.py
index 1d540de3..87fc0fef 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -208,3 +208,15 @@ def setup(app):
}
))
+ app.add_domain(custom_domain(
+ 'JavaDomain',
+ 'java',
+ 'Java',
+ {
+ 'class': {
+ },
+ 'method': {
+ },
+ }
+ ))
+
diff --git a/docs/csharp.rst b/docs/csharp.rst
index 51a9f32a..ce35265b 100644
--- a/docs/csharp.rst
+++ b/docs/csharp.rst
@@ -5,8 +5,8 @@ Euler C# Implementation
:start-line: 2
:end-before: Makefile
-.. include:: ../rust/README.rst
- :start-after: Alias for ``cargo clean``
+.. include:: ../csharp/README.rst
+ :start-after: dependencies for this section.
:end-before: Problems Solved
Usage
diff --git a/docs/index.rst b/docs/index.rst
index e09dc2c9..66a404f5 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -31,6 +31,7 @@ Problems Solved
.. |C| replace:: **C**
.. |Cp| replace:: **C++**
.. |C#| replace:: **C#**
+.. |Ja| replace:: **Java**
.. |Js| replace:: **JavaScript**
.. |Py| replace:: **Python**
.. |Rs| replace:: **Rust**
@@ -56,176 +57,176 @@ Problems Solved
.. rst-class:: centertable
-+-----------+------------+------------+------------+------------+------------+------------+
-| | |C| | |Cp| | |C#| | |Js| | |Py| | |Rs| |
-+===========+============+============+============+============+============+============+
-|Coverage | |d| | |d| | |d| | |d| | |d| | |d| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|Docs | |d| | |d| | |d| | |d| | |d| | |d| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|Linting | |d| | |d| | |d| | |d| | |d| | |d| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|Testing | |d| | |d| | |d| | |d| | |d| | |d| |
-+-----------+------------+------------+------------+------------+------------+------------+
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`1` |:c-d:`0001` |:cp-d:`0001`|:cs-d:`0001`|:js-d:`0001`|:py-d:`0001`|:rs-d:`0001`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`2` |:c-d:`0002` |:cp-d:`0002`|:cs-d:`0002`|:js-d:`0002`|:py-d:`0002`|:rs-d:`0002`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`3` |:c-d:`0003` | | |:js-d:`0003`|:py-d:`0003`|:rs-d:`0003`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`4` |:c-d:`0004` |:cp-d:`0004`|:cs-d:`0004`|:js-d:`0004`|:py-d:`0004`|:rs-d:`0004`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`5` |:c-d:`0005` | | | |:py-d:`0005`|:rs-d:`0005`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`6` |:c-d:`0006` |:cp-d:`0006`|:cs-d:`0006`|:js-d:`0006`|:py-d:`0006`|:rs-d:`0006`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`7` |:c-d:`0007` | | |:js-d:`0007`|:py-d:`0007`|:rs-d:`0007`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`8` |:c-d:`0008` |:cp-d:`0008`|:cs-d:`0008`|:js-d:`0008`|:py-d:`0008`|:rs-d:`0008`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`9` |:c-d:`0009` |:cp-d:`0009`|:cs-d:`0009`|:js-d:`0009`|:py-d:`0009`|:rs-d:`0009`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`10` |:c-d:`0010` | | |:js-d:`0010`|:py-d:`0010`|:rs-d:`0010`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`11` |:c-d:`0011` |:cp-d:`0011`|:cs-d:`0011`|:js-d:`0011`|:py-d:`0011`|:rs-d:`0011`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`12` |:c-s:`0012` | | | |:py-d:`0012`|:rs-d:`0012`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`13` |:c-d:`0013` |:cp-d:`0013`|:cs-d:`0013`|:js-d:`0013`|:py-d:`0013`|:rs-d:`0013`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`14` |:c-d:`0014` |:cp-d:`0014`|:cs-d:`0014`|:js-d:`0014`|:py-d:`0014`|:rs-d:`0014`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`15` |:c-d:`0015` |:cp-d:`0015`|:cs-d:`0015`|:js-d:`0015`|:py-d:`0015`|:rs-d:`0015`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`16` |:c-d:`0016` |:cp-d:`0016`|:cs-d:`0016`|:js-d:`0016`|:py-d:`0016`|:rs-d:`0016`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`17` |:c-d:`0017` |:cp-d:`0017`|:cs-d:`0017`|:js-d:`0017`|:py-d:`0017`|:rs-d:`0017`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`18` | | | | |:py-d:`0018`|:rs-d:`0018`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`19` | | | | |:py-d:`0019`|:rs-d:`0019`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`20` |:c-d:`0020` |:cp-d:`0020`|:cs-d:`0020`|:js-d:`0020`|:py-d:`0020`|:rs-d:`0020`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`21` | | | | |:py-d:`0021`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`22` |:c-d:`0022` |:cp-d:`0022`|:cs-d:`0022`|:js-d:`0022`|:py-d:`0022`|:rs-d:`0022`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`23` | | | | |:py-d:`0023`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`24` | | | | |:py-d:`0024`|:rs-d:`0024`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`25` | | | | |:py-d:`0025`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`27` | | | | |:py-d:`0027`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`28` | | | | |:py-d:`0028`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`29` | | | | |:py-d:`0029`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`30` | | | | |:py-d:`0030`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`31` | | | | |:py-d:`0031`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`32` | | | | |:py-d:`0032`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`33` | | | | |:py-d:`0033`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`34` |:c-d:`0034` |:cp-d:`0034`|:cs-d:`0034`|:js-d:`0034`|:py-d:`0034`|:rs-d:`0034`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`35` | | | | |:py-d:`0035`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`36` | | | | |:py-d:`0036`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`37` | | | | |:py-d:`0037`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`38` | | | | |:py-d:`0038`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`39` | | | | |:py-d:`0039`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`40` | | | | |:py-d:`0040`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`41` | | | | |:py-d:`0041`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`42` | | | | |:py-d:`0042`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`43` | | | | |:py-d:`0043`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`44` | | | | |:py-d:`0044`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`45` | | | | |:py-d:`0045`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`46` | | | | |:py-d:`0046`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`47` | | | | |:py-d:`0047`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`48` | | | | |:py-d:`0048`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`49` | | | | |:py-d:`0049`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`50` | | | | |:py-d:`0050`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`52` | | | | |:py-d:`0052`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`53` | | | | |:py-d:`0053`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`55` | | | | |:py-d:`0055`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`56` | | | | |:py-d:`0056`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`57` | | | | |:py-d:`0057`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`58` | | | | |:py-d:`0058`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`59` | | | | |:py-d:`0059`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`60` | | | | |:py-d:`0060`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`63` | | | | |:py-d:`0063`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`67` | | | | |:py-d:`0067`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`69` | | | | |:py-d:`0069`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`71` | | | | |:py-d:`0071`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`73` | | | | |:py-d:`0073`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`74` | | | | |:py-d:`0074`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`76` |:c-d:`0076` |:cp-d:`0076`|:cs-s:`0076`|:js-s:`0076`|:py-d:`0076`|:rs-d:`0076`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`77` | | | | |:py-d:`0077`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`81` | | | | |:py-d:`0081`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`87` | | | | |:py-d:`0087`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`89` | | | | |:py-d:`0089`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`92` | | | | |:py-d:`0092`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`97` | | | | |:py-d:`0097`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`99` | | | | |:py-d:`0099`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`118`| | | | |:py-s:`0118`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`123`| | | | |:py-d:`0123`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`134`| | | | |:py-d:`0134`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`145`| | | | |:py-d:`0145`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`187`| | | | |:py-d:`0187`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`206`| | | | |:py-d:`0206`| |
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`357`| | | | |:py-s:`0357`|:rs-i:`0357`|
-+-----------+------------+------------+------------+------------+------------+------------+
-|:prob:`836`|:c-d:`0836` |:cp-d:`0836`|:cs-d:`0836`|:js-d:`0836`|:py-d:`0836`|:rs-d:`0836`|
-+-----------+------------+------------+------------+------------+------------+------------+
++-----------+------------+------------+------------+------------+------------+------------+------------+
+| | |C| | |Cp| | |C#| | |Ja| | |Js| | |Py| | |Rs| |
++===========+============+============+============+============+============+============+============+
+|Coverage | |d| | |d| | |d| | |ip| | |d| | |d| | |d| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|Docs | |d| | |d| | |d| | |ip| | |d| | |d| | |d| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|Linting | |d| | |d| | |d| | |ip| | |d| | |d| | |d| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|Testing | |d| | |d| | |d| | |ip| | |d| | |d| | |d| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`1` |:c-d:`0001` |:cp-d:`0001`|:cs-d:`0001`|:ja-i:`0001`|:js-d:`0001`|:py-d:`0001`|:rs-d:`0001`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`2` |:c-d:`0002` |:cp-d:`0002`|:cs-d:`0002`| |:js-d:`0002`|:py-d:`0002`|:rs-d:`0002`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`3` |:c-d:`0003` | | | |:js-d:`0003`|:py-d:`0003`|:rs-d:`0003`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`4` |:c-d:`0004` |:cp-d:`0004`|:cs-d:`0004`| |:js-d:`0004`|:py-d:`0004`|:rs-d:`0004`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`5` |:c-d:`0005` | | | | |:py-d:`0005`|:rs-d:`0005`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`6` |:c-d:`0006` |:cp-d:`0006`|:cs-d:`0006`| |:js-d:`0006`|:py-d:`0006`|:rs-d:`0006`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`7` |:c-d:`0007` | | | |:js-d:`0007`|:py-d:`0007`|:rs-d:`0007`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`8` |:c-d:`0008` |:cp-d:`0008`|:cs-d:`0008`| |:js-d:`0008`|:py-d:`0008`|:rs-d:`0008`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`9` |:c-d:`0009` |:cp-d:`0009`|:cs-d:`0009`| |:js-d:`0009`|:py-d:`0009`|:rs-d:`0009`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`10` |:c-d:`0010` | | | |:js-d:`0010`|:py-d:`0010`|:rs-d:`0010`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`11` |:c-d:`0011` |:cp-d:`0011`|:cs-d:`0011`| |:js-d:`0011`|:py-d:`0011`|:rs-d:`0011`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`12` |:c-s:`0012` | | | | |:py-d:`0012`|:rs-d:`0012`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`13` |:c-d:`0013` |:cp-d:`0013`|:cs-d:`0013`| |:js-d:`0013`|:py-d:`0013`|:rs-d:`0013`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`14` |:c-d:`0014` |:cp-d:`0014`|:cs-d:`0014`| |:js-d:`0014`|:py-d:`0014`|:rs-d:`0014`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`15` |:c-d:`0015` |:cp-d:`0015`|:cs-d:`0015`| |:js-d:`0015`|:py-d:`0015`|:rs-d:`0015`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`16` |:c-d:`0016` |:cp-d:`0016`|:cs-d:`0016`| |:js-d:`0016`|:py-d:`0016`|:rs-d:`0016`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`17` |:c-d:`0017` |:cp-d:`0017`|:cs-d:`0017`| |:js-d:`0017`|:py-d:`0017`|:rs-d:`0017`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`18` | | | | | |:py-d:`0018`|:rs-d:`0018`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`19` | | | | | |:py-d:`0019`|:rs-d:`0019`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`20` |:c-d:`0020` |:cp-d:`0020`|:cs-d:`0020`| |:js-d:`0020`|:py-d:`0020`|:rs-d:`0020`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`21` | | | | | |:py-d:`0021`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`22` |:c-d:`0022` |:cp-d:`0022`|:cs-d:`0022`| |:js-d:`0022`|:py-d:`0022`|:rs-d:`0022`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`23` | | | | | |:py-d:`0023`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`24` | | | | | |:py-d:`0024`|:rs-d:`0024`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`25` | | | | | |:py-d:`0025`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`27` | | | | | |:py-d:`0027`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`28` | | | | | |:py-d:`0028`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`29` | | | | | |:py-d:`0029`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`30` | | | | | |:py-d:`0030`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`31` | | | | | |:py-d:`0031`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`32` | | | | | |:py-d:`0032`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`33` | | | | | |:py-d:`0033`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`34` |:c-d:`0034` |:cp-d:`0034`|:cs-d:`0034`| |:js-d:`0034`|:py-d:`0034`|:rs-d:`0034`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`35` | | | | | |:py-d:`0035`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`36` | | | | | |:py-d:`0036`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`37` | | | | | |:py-d:`0037`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`38` | | | | | |:py-d:`0038`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`39` | | | | | |:py-d:`0039`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`40` | | | | | |:py-d:`0040`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`41` | | | | | |:py-d:`0041`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`42` | | | | | |:py-d:`0042`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`43` | | | | | |:py-d:`0043`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`44` | | | | | |:py-d:`0044`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`45` | | | | | |:py-d:`0045`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`46` | | | | | |:py-d:`0046`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`47` | | | | | |:py-d:`0047`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`48` | | | | | |:py-d:`0048`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`49` | | | | | |:py-d:`0049`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`50` | | | | | |:py-d:`0050`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`52` | | | | | |:py-d:`0052`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`53` | | | | | |:py-d:`0053`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`55` | | | | | |:py-d:`0055`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`56` | | | | | |:py-d:`0056`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`57` | | | | | |:py-d:`0057`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`58` | | | | | |:py-d:`0058`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`59` | | | | | |:py-d:`0059`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`60` | | | | | |:py-d:`0060`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`63` | | | | | |:py-d:`0063`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`67` | | | | | |:py-d:`0067`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`69` | | | | | |:py-d:`0069`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`71` | | | | | |:py-d:`0071`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`73` | | | | | |:py-d:`0073`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`74` | | | | | |:py-d:`0074`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`76` |:c-d:`0076` |:cp-d:`0076`|:cs-s:`0076`| |:js-s:`0076`|:py-d:`0076`|:rs-d:`0076`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`77` | | | | | |:py-d:`0077`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`81` | | | | | |:py-d:`0081`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`87` | | | | | |:py-d:`0087`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`89` | | | | | |:py-d:`0089`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`92` | | | | | |:py-d:`0092`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`97` | | | | | |:py-d:`0097`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`99` | | | | | |:py-d:`0099`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`118`| | | | | |:py-s:`0118`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`123`| | | | | |:py-d:`0123`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`134`| | | | | |:py-d:`0134`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`145`| | | | | |:py-d:`0145`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`187`| | | | | |:py-d:`0187`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`206`| | | | | |:py-d:`0206`| |
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`357`| | | | | |:py-s:`0357`|:rs-i:`0357`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
+|:prob:`836`|:c-d:`0836` |:cp-d:`0836`|:cs-d:`0836`|:ja-i:`0836`|:js-d:`0836`|:py-d:`0836`|:rs-d:`0836`|
++-----------+------------+------------+------------+------------+------------+------------+------------+
.. toctree::
:maxdepth: 2
diff --git a/docs/java.rst b/docs/java.rst
new file mode 100644
index 00000000..78b0c063
--- /dev/null
+++ b/docs/java.rst
@@ -0,0 +1,81 @@
+Euler Java Implementation
+=======================
+
+.. include:: ../java/README.rst
+ :start-line: 2
+ :end-before: Makefile
+
+.. include:: ../java/README.rst
+ :start-after: dependencies for this section.
+ :end-before: Problems Solved
+
+Usage
+-----
+
+.. highlight:: make
+
+This folder contains a Makefile with several recipes, most of which are aliases to ``dotnet`` commands.
+This facilitates the root Makefile dispatching tasks to each language, many of which have more complex
+build or test processes.
+
+.. make:target:: test
+
+ Alias for ``maven test -Dtest.single``.
+
+.. make:target:: test_auto
+
+ .. note::
+
+ WIP
+
+ Runs tests in parallel with one less thread than you have CPUs. Alias for ``maven test-T 1C``.
+
+.. make:target:: test_%
+
+ .. note::
+
+ WIP
+
+ Runs tests in parallel with the specified number of threads. Alias for ``maven test -T $*``.
+
+.. make:target:: clean
+
+ Alias for ``maven clean``, with some degree of fallback if ``maven`` is not installed.
+
+.. make:target:: lint
+
+ Alias for ``maven formatter:format``.
+
+Test Infrastructure
+-------------------
+
+.. java:class:: IEuler
+
+ .. java:method:: Object answer()
+
+.. java:class:: EulerTest
+
+ .. java:method:: void eulerTestProblem()
+
+ A JUnit theory that, for each registered solution, will test against the known answer and a one minute time limit.
+
+Library Code
+------------
+
+.. toctree::
+ :numbered:
+ :maxdepth: 1
+
+ java/math
+ java/primes
+ java/utils
+
+Problems Solved
+---------------
+
+.. toctree::
+ :glob:
+ :numbered:
+ :maxdepth: 1
+
+ java/p[0-9][0-9][0-9][0-9]
\ No newline at end of file
diff --git a/docs/java/p0001.rst b/docs/java/p0001.rst
new file mode 100644
index 00000000..787a48ad
--- /dev/null
+++ b/docs/java/p0001.rst
@@ -0,0 +1,12 @@
+Java Implementation of Problem 1
+================================
+
+View source code :source:`java/src/main/java/euler/p0001.java`
+
+.. java:class:: p0001 implements Euler.IEuler
+
+ .. java:method:: Object answer()
+
+.. literalinclude:: ../../java/src/main/java/euler/p0001.java
+ :language: java
+ :linenos:
diff --git a/docs/java/p0836.rst b/docs/java/p0836.rst
new file mode 100644
index 00000000..8fdd696c
--- /dev/null
+++ b/docs/java/p0836.rst
@@ -0,0 +1,12 @@
+Java Implementation of Problem 836
+==================================
+
+View source code :source:`java/src/main/java/euler/p0836.java`
+
+.. java:class:: p0836 implements Euler.IEuler
+
+ .. java:method:: Object answer()
+
+.. literalinclude:: ../../java/src/main/java/euler/p0836.java
+ :language: java
+ :linenos:
diff --git a/java/Makefile b/java/Makefile
new file mode 100644
index 00000000..dc355112
--- /dev/null
+++ b/java/Makefile
@@ -0,0 +1,28 @@
+MVN?=mvn
+BLUE=\033[0;34m
+NC=\033[0m # No Color
+
+help:
+ @echo " $(BLUE)test$(NC) run through all tests in sequence"
+ @echo " $(BLUE)test_*$(NC) run through all tests in parallel with the given number of threads. Use auto to allow the test runner to determine it"
+ @echo " $(BLUE)dependencies$(NC) grabs all dependencies through maven"
+ @echo " $(BLUE)clean$(NC) clean up any stray files"
+ @echo " $(BLUE)lint$(NC) Run the maven formatter"
+
+clean:
+ $(MVN) clean || echo
+
+dependencies:
+ $(MVN) install -B
+
+test: dependencies
+ $(MVN) test -Dtest.single
+
+test_auto: dependencies
+ $(MVN) test -T 1C
+
+test_%: dependencies
+ $(MVN) test -T $*
+
+lint:
+ $(MVN) formatter:format
\ No newline at end of file
diff --git a/java/README.rst b/java/README.rst
new file mode 100644
index 00000000..487a1929
--- /dev/null
+++ b/java/README.rst
@@ -0,0 +1,78 @@
+Java Section
+============
+
+.. |Java Check| image:: https://github.com/LivInTheLookingGlass/Euler/actions/workflows/java.yml/badge.svg
+ :target: https://github.com/LivInTheLookingGlass/Euler/actions/workflows/java.yml
+
+|Java Check|
+
+All problems are solved in Java 8+.
+
+Organization
+------------
+
+All Java files share a common prefix with their problem number. All shared
+functions are defined in the include folder.
+
+Makefile
+--------
+
+There are three main recipes in this Makefile
+
+dependencies
+~~~~~~~~~~~~
+
+This recipe installs all the required and test dependencies. See the
+Dependencies section for more info
+
+test
+~~~~
+
+This recipe runs tests in multiple threads
+
+lint
+~~~~
+
+This recipe runs ``maven``\ s builtin formatter
+
+Tests
+-----
+
+Prime Infrastructure Test
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This test checks five things:
+
+1. It checks ``is_prime()`` for numbers up to ``MAX_PRIME``, where that
+ is defined in the test
+2. It checks that ``is_composite()`` returns truthy values on composites
+ in that range, and falsey values on primes
+3. It checks that ``is_composite()`` returns the smallest prime factor
+ on composite numbers
+4. It checks that the prime numbers are generated in the correct order
+5. It checks that all these operations are completed in less than 200ns
+ \* ``MAX_PRIME``
+
+Generic Problems
+~~~~~~~~~~~~~~~~
+
+For each problem it will check the answer against a known dictionary. If
+the problem is not in the "known slow" category (meaning that I generate
+the correct answer with a poor solution), it will always be run.
+Otherwise it tries to detect the ``NO_SLOW`` environment variable and
+dynamically skip them.
+
+A test fails if it gets the wrong answer or if it takes more than 1
+minute.
+
+Dependencies
+------------
+
+I try to keep the dependencies of this project as small as possible,
+except for test plugins. At the moment there are no non-test
+dependencies for this section.
+
+Problems Solved
+---------------
+
+- ☒ `1 <./src/main/p0001.java>`__
diff --git a/java/pom.xml b/java/pom.xml
new file mode 100644
index 00000000..13e3ece8
--- /dev/null
+++ b/java/pom.xml
@@ -0,0 +1,54 @@
+
+ 4.0.0
+ euler
+ java
+ 1.0-SNAPSHOT
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.8.2
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ 5.8.2
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-params
+ 5.8.2
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.22.2
+
+
+ **/*Test.java
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+
+ 1.8
+
+
+
+
+
\ No newline at end of file
diff --git a/java/src/main/java/euler/IEuler.java b/java/src/main/java/euler/IEuler.java
new file mode 100644
index 00000000..a93a47e3
--- /dev/null
+++ b/java/src/main/java/euler/IEuler.java
@@ -0,0 +1,5 @@
+package euler;
+
+public interface IEuler {
+ Object answer();
+}
\ No newline at end of file
diff --git a/java/src/main/java/euler/lib/Utilities.java b/java/src/main/java/euler/lib/Utilities.java
new file mode 100644
index 00000000..2d850b2e
--- /dev/null
+++ b/java/src/main/java/euler/lib/Utilities.java
@@ -0,0 +1,85 @@
+package euler;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class Utilities {
+
+ private static Path getDataPath(String name) throws IOException {
+ String thisFile = new Exception().getStackTrace()[0].getFileName();
+ if (thisFile == null) {
+ throw new IOException("Unable to determine file path.");
+ }
+ Path filePath = Paths.get(thisFile).getParent().resolve("../../../_data").resolve(name);
+ return filePath.toAbsolutePath();
+ }
+
+ public static String getDataFileText(String name) throws IOException {
+ Path filePath = getDataPath(name);
+ return new String(Files.readAllBytes(filePath));
+ }
+
+ public static byte[] getDataFileBytes(String name) throws IOException {
+ Path filePath = getDataPath(name);
+ return Files.readAllBytes(filePath);
+ }
+
+ public static Object getAnswer(long n) throws IOException {
+ String csvContent = getDataFileText("answers.csv");
+ try (BufferedReader reader = new BufferedReader(new StringReader(csvContent))) {
+ String line;
+ while ((line = reader.readLine()) != null) {
+ String[] arr = line.split("\t");
+ if (arr.length < 4) continue;
+ long key = Long.parseLong(arr[0]);
+ if (key != n) continue;
+
+ String type = arr[1];
+ int bitLength = Integer.parseInt(arr[2]);
+ String value = arr[3];
+
+ switch (type) {
+ case "str":
+ return value;
+ case "int":
+ switch (bitLength) {
+ case 8:
+ return (byte)Integer.parseInt(value);
+ case 16:
+ return (short)Integer.parseInt(value);
+ case 32:
+ return Integer.parseInt(value);
+ case 64:
+ return Long.parseLong(value);
+ default:
+ // no return, just continue
+ }
+ break;
+ case "uint":
+ switch (bitLength) {
+ case 8:
+ return (byte)Integer.parseUnsignedInt(value);
+ case 16:
+ return (short)Integer.parseUnsignedInt(value);
+ case 32:
+ return Integer.parseUnsignedInt(value);
+ case 64:
+ return Long.parseUnsignedLong(value);
+ default:
+ // no return, just continue
+ }
+ default:
+ // no return, just continue
+ }
+
+ // If no valid type or bit length was found
+ throw new IOException("Unsupported type/length: " + type + ", " + bitLength);
+ }
+ }
+ throw new IOException("Answer not found.");
+ }
+}
\ No newline at end of file
diff --git a/java/src/main/java/euler/p0000.java b/java/src/main/java/euler/p0000.java
new file mode 100644
index 00000000..144103ee
--- /dev/null
+++ b/java/src/main/java/euler/p0000.java
@@ -0,0 +1,8 @@
+package euler;
+
+public class p0000 implements IEuler {
+ @Override
+ public Object answer() {
+ return 0;
+ }
+}
\ No newline at end of file
diff --git a/java/src/main/java/euler/p0001.java b/java/src/main/java/euler/p0001.java
new file mode 100644
index 00000000..318888f9
--- /dev/null
+++ b/java/src/main/java/euler/p0001.java
@@ -0,0 +1,18 @@
+package euler;
+
+public class p0001 implements IEuler {
+ @Override
+ public Object answer() {
+ int answer = 0;
+ for (int i = 0; i < 1000; i += 3)
+ answer += i;
+
+ for (int i = 0; i < 1000; i += 5)
+ answer += i;
+
+ for (int i = 0; i < 1000; i += 15)
+ answer -= i;
+
+ return answer;
+ }
+}
\ No newline at end of file
diff --git a/java/src/main/java/euler/p0836.java b/java/src/main/java/euler/p0836.java
new file mode 100644
index 00000000..b8b7a755
--- /dev/null
+++ b/java/src/main/java/euler/p0836.java
@@ -0,0 +1,8 @@
+package euler;
+
+public class p0836 implements IEuler {
+ @Override
+ public Object answer() {
+ return "aprilfoolsjoke";
+ }
+}
\ No newline at end of file
diff --git a/java/src/test/java/EulerTest.java b/java/src/test/java/EulerTest.java
new file mode 100644
index 00000000..8b30b15a
--- /dev/null
+++ b/java/src/test/java/EulerTest.java
@@ -0,0 +1,52 @@
+package euler;
+
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.api.Assertions;
+
+import java.lang.reflect.Method;
+import java.util.stream.Stream;
+
+public class EulerTest {
+ private static final long ONE_MINUTE_NS = 60_000_000_000L; // 1 minute in nanoseconds
+
+ // Data provider for parameterized tests
+ static Stream