# Project Euler solutions

## Introduction

I solve Project Euler problems to practice and extend my math and program­ming skills, all while having fun at the same time. Here I make my solutions publicly available for other enthusiasts to learn from and to critique. This page lists all of my Project Euler solution code, along with other helpful information like bench­mark timings and my overall thoughts on the nature of math and programming in Project Euler.

Each problem that I solved always includes a Java program. Almost all my solved problems also include a Python program (except for a few). Many problems additionally have a Mathematica and Haskell program. Numerous solutions contain a detailed mathematical proof to justify why the imple­mented algorithm is correct. Among the web, this is perhaps the largest collection of Project Euler solutions in the Java programming language. All my code is original work, not based on anyone else’s code, although a couple of times I obtained the high-level approach from reading various literature on the web.

## Solution code ### Git repositories

GitHub (primary) Browse files Download ZIP Answers.txt

### Individual files

Every Java solution depends on these shared classes: EulerSolution.java, Library.java.
Many Python solutions depend on my shared math library module: eulerlib.py.
Many Haskell solutions depend on my shared math library module: EulerLib.hs.
Some solution code contains a detailed mathematical proof of correctness.

Problem Java Python Mathematica Haskell Explanation
Problem 1 p001.java p001.py p001.mathematica p001.hs Yes
Problem 2 p002.java p002.py p002.mathematica p002.hs Yes
Problem 3 p003.java p003.py p003.mathematica p003.hs Yes
Problem 4 p004.java p004.py p004.mathematica p004.hs Yes
Problem 5 p005.java p005.py p005.mathematica p005.hs Yes
Problem 6 p006.java p006.py p006.mathematica p006.hs Yes
Problem 7 p007.java p007.py p007.mathematica p007.hs Yes
Problem 8 p008.java p008.py p008.mathematica p008.hs Yes
Problem 9 p009.java p009.py p009.mathematica p009.hs Yes
Problem 10 p010.java p010.py p010.mathematica p010.hs Yes
Problem 11 p011.java p011.py p011.mathematica p011.hs Yes
Problem 12 p012.java p012.py p012.mathematica p012.hs Yes
Problem 13 p013.java p013.py p013.mathematica p013.hs Yes
Problem 14 p014.java p014.py p014.mathematica p014.hs Yes
Problem 15 p015.java p015.py p015.mathematica p015.hs Yes
Problem 16 p016.java p016.py p016.mathematica p016.hs Yes
Problem 17 p017.java p017.py p017.mathematica p017.hs Yes
Problem 18 p018.java p018.py p018.mathematica p018.hs Yes
Problem 19 p019.java p019.py p019.mathematica p019.hs Yes
Problem 20 p020.java p020.py p020.mathematica p020.hs Yes
Problem 21 p021.java p021.py p021.mathematica p021.hs Yes
Problem 22 p022.java p022.py p022.mathematica p022.hs Yes
Problem 23 p023.java p023.py p023.mathematica p023.hs
Problem 24 p024.java p024.py p024.mathematica p024.hs Yes
Problem 25 p025.java p025.py p025.mathematica p025.hs Yes
Problem 26 p026.java p026.py p026.mathematica p026.hs
Problem 27 p027.java p027.py p027.mathematica
Problem 28 p028.java p028.py p028.mathematica p028.hs Yes
Problem 29 p029.java p029.py p029.mathematica p029.hs Yes
Problem 30 p030.java p030.py p030.mathematica p030.hs Yes
Problem 31 p031.java p031.py p031.mathematica p031.hs Yes
Problem 32 p032.java p032.py p032.mathematica p032.hs Yes
Problem 33 p033.java p033.py p033.mathematica p033.hs Yes
Problem 34 p034.java p034.py p034.mathematica p034.hs Yes
Problem 35 p035.java p035.py p035.mathematica
Problem 36 p036.java p036.py p036.mathematica p036.hs
Problem 37 p037.java p037.py p037.mathematica
Problem 38 p038.java p038.py p038.mathematica p038.hs
Problem 39 p039.java p039.py p039.mathematica p039.hs
Problem 40 p040.java p040.py p040.mathematica p040.hs
Problem 41 p041.java p041.py p041.mathematica
Problem 42 p042.java p042.py p042.mathematica p042.hs Yes
Problem 43 p043.java p043.py p043.mathematica
Problem 44 p044.java p044.py p044.mathematica Yes
Problem 45 p045.java p045.py p045.mathematica p045.hs
Problem 46 p046.java p046.py p046.mathematica p046.hs
Problem 47 p047.java p047.py p047.mathematica
Problem 48 p048.java p048.py p048.mathematica p048.hs
Problem 49 p049.java p049.py p049.mathematica
Problem 50 p050.java p050.py p050.mathematica
Problem 51 p051.java p051.py
Problem 52 p052.java p052.py p052.mathematica p052.hs
Problem 53 p053.java p053.py p053.mathematica p053.hs
Problem 54 p054.java p054.py
Problem 55 p055.java p055.py p055.mathematica p055.hs
Problem 56 p056.java p056.py p056.mathematica p056.hs
Problem 57 p057.java p057.py p057.mathematica p057.hs
Problem 58 p058.java p058.py p058.mathematica p058.hs Yes
Problem 59 p059.java p059.py
Problem 60 p060.java p060.py p060.hs Yes
Problem 61 p061.java p061.py
Problem 62 p062.java p062.py
Problem 63 p063.java p063.py p063.mathematica p063.hs Yes
Problem 64 p064.java p064.py p064.mathematica
Problem 65 p065.java p065.py p065.mathematica p065.hs
Problem 66 p066.java p066.py p066.mathematica Yes
Problem 67 p067.java p067.py p067.mathematica p067.hs Yes
Problem 68 p068.java p068.py
Problem 69 p069.java p069.py p069.mathematica
Problem 70 p070.java p070.py p070.mathematica
Problem 71 p071.java p071.py p071.mathematica p071.hs Yes
Problem 72 p072.java p072.py p072.mathematica
Problem 73 p073.java p073.py p073.hs Yes
Problem 74 p074.java p074.py
Problem 75 p075.java p075.py Yes
Problem 76 p076.java p076.py p076.mathematica p076.hs
Problem 77 p077.java p077.py p077.mathematica p077.hs Yes
Problem 78 p078.java p078.py Yes
Problem 79 p079.java p079.py
Problem 80 p080.java p080.py p080.mathematica Yes
Problem 81 p081.java p081.py p081.mathematica p081.hs
Problem 82 p082.java p082.py p082.mathematica
Problem 83 p083.java p083.py p083.mathematica
Problem 84 p084.java p084.py
Problem 85 p085.java p085.py p085.mathematica p085.hs
Problem 86 p086.java p086.py
Problem 87 p087.java p087.py
Problem 88 p088.java p088.py Yes
Problem 89 p089.java p089.py p089.mathematica p089.hs
Problem 90 p090.java p090.py
Problem 91 p091.java p091.py p091.mathematica p091.hs
Problem 92 p092.java p092.py p092.mathematica p092.hs
Problem 93 p093.java p093.py
Problem 94 p094.java p094.py Yes
Problem 95 p095.java p095.py
Problem 96 p096.java p096.py
Problem 97 p097.java p097.py p097.mathematica p097.hs
Problem 98 p098.java p098.py
Problem 99 p099.java p099.py p099.mathematica
Problem 100 p100.java p100.py p100.mathematica p100.hs Yes
Problem 101 p101.java p101.py p101.mathematica Yes
Problem 102 p102.java p102.py p102.mathematica p102.hs
Problem 103 p103.java p103.py Yes
Problem 104 p104.java p104.py p104.mathematica Yes
Problem 105 p105.java p105.py p105.mathematica
Problem 106 p106.java p106.py p106.mathematica p106.hs Yes
Problem 107 p107.java p107.py Yes
Problem 108 p108.java p108.py p108.mathematica Yes
Problem 109 p109.java p109.py p109.mathematica
Problem 111 p111.java p111.py Yes
Problem 112 p112.java p112.py p112.mathematica p112.hs
Problem 113 p113.java p113.py p113.mathematica p113.hs Yes
Problem 114 p114.java p114.py p114.mathematica p114.hs Yes
Problem 115 p115.java p115.py p115.mathematica p115.hs Yes
Problem 116 p116.java p116.py p116.mathematica p116.hs Yes
Problem 117 p117.java p117.py p117.mathematica p117.hs Yes
Problem 118 p118.java p118.py
Problem 119 p119.java p119.py Yes
Problem 120 p120.java p120.py p120.mathematica p120.hs Yes
Problem 121 p121.java p121.py p121.mathematica p121.hs Yes
Problem 122 p122.java p122.py Yes
Problem 123 p123.java p123.py p123.mathematica p123.hs Yes
Problem 124 p124.java p124.py
Problem 125 p125.java p125.py
Problem 127 p127.java p127.py Yes
Problem 128 p128.java p128.py p128.mathematica p128.hs Yes
Problem 129 p129.java p129.py p129.mathematica p129.hs
Problem 130 p130.java p130.py p130.hs
Problem 132 p132.java p132.py p132.mathematica p132.hs
Problem 133 p133.java p133.py p133.mathematica Yes
Problem 134 p134.java p134.py p134.mathematica Yes
Problem 135 p135.java p135.py Yes
Problem 139 p139.java p139.py p139.hs
Problem 142 p142.java p142.py Yes
Problem 145 p145.java p145.py p145.mathematica p145.hs Yes
Problem 146 p146.java p146.py Yes
Problem 149 p149.java p149.py
Problem 150 p150.java p150.py
Problem 151 p151.java p151.py
Problem 155 p155.java p155.py
Problem 160 p160.java p160.py p160.mathematica p160.hs Yes
Problem 162 p162.java p162.py p162.mathematica p162.hs Yes
Problem 164 p164.java p164.py p164.mathematica p164.hs Yes
Problem 164 p165.java p165.py
Problem 166 p166.java p166.py p166.hs Yes
Problem 169 p169.java p169.py p169.mathematica
Problem 171 p171.java p171.py p171.mathematica Yes
Problem 172 p172.java p172.py p172.mathematica Yes
Problem 173 p173.java p173.py p173.mathematica p173.hs Yes
Problem 174 p174.java p174.py p174.mathematica
Problem 178 p178.java p178.py p178.mathematica
Problem 179 p179.java p179.py p179.mathematica
Problem 182 p182.java p182.py p182.hs
Problem 186 p186.java p186.py
Problem 187 p187.java p187.py p187.mathematica Yes
Problem 188 p188.java p188.py p188.mathematica p188.hs
Problem 191 p191.java p191.py p191.mathematica p191.hs
Problem 197 p197.java p197.py p197.mathematica Yes
Problem 203 p203.java p203.py p203.mathematica
Problem 204 p204.java p204.py
Problem 205 p205.java p205.py p205.mathematica p205.hs
Problem 206 p206.java p206.py Yes
Problem 208 p208.java p208.py Yes
Problem 211 p211.java p211.py
Problem 214 p214.java p214.py
Problem 215 p215.java p215.py
Problem 216 p216.java p216.py Yes
Problem 218 p218.java p218.py p218.mathematica p218.hs Yes
Problem 222 p222.java p222.py
Problem 225 p225.java p225.py p225.hs
Problem 231 p231.java p231.py p231.mathematica
Problem 243 p243.java p243.py p243.mathematica Yes
Problem 249 p249.java p249.py
Problem 250 p250.java p250.py p250.mathematica
Problem 265 p265.java p265.py p265.hs
Problem 267 p267.java p267.py Yes
Problem 271 p271.java p271.py Yes
Problem 280 p280.java p280.py
Problem 287 p287.java p287.py p287.hs Yes
Problem 301 p301.java p301.py p301.mathematica p301.hs Yes
Problem 303 p303.java p303.py Yes
Problem 304 p304.java p304.py
Problem 315 p315.java p315.py
Problem 323 p323.java p323.py p323.mathematica p323.hs Yes
Problem 329 p329.java p329.py Yes
Problem 345 p345.java p345.py
Problem 346 p346.java p346.py Yes
Problem 347 p347.java p347.py
Problem 348 p348.java p348.py Yes
Problem 357 p357.java p357.py Yes
Problem 381 p381.java p381.py p381.mathematica Yes
Problem 387 p387.java p387.py
Problem 401 p401.java p401.py p401.mathematica Yes
Problem 407 p407.java p407.py Yes
Problem 417 p417.java Yes
Problem 425 p425.java p425.py Yes
Problem 429 p429.java p429.py p429.mathematica Yes
Problem 431 p431.java
Problem 433 p433.java Yes
Problem 451 p451.java p451.py Yes
Problem 493 p493.java p493.py
Problem 500 p500.java p500.py Yes
Problem 518 p518.java p518.py Yes
Problem 549 p549.java p549.py Yes
Problem 587 p587.java p587.py p587.mathematica p587.hs Yes

## Language usage

### Java

For every problem that I solved, I have a Java solution for it (and possibly code in other languages as well). I like using Java because it is fast, safe, and expressive. To elaborate on these points, I will compare it to other program­ming languages: Python and Mathematica are slow for basic integer arithmetic (~1/30× of Java speed) because they natively use bigint and are also dynami­cally typed. Also, Mathematica uses a lot of memory to store an array of integers because it doesn’t have packed fixed-width integers. C and C++ are unsafe because of the lack of array bounds checking, having signed integer overflow, and having tons of easily invoked undefined behaviors. Custom data structures like graphs are difficult to express cleanly in Mathematica. Custom algorithms like the sieve of Eratosthenes, especially ones most naturally expressed in terms of imperative state updates, are difficult to implement correctly or efficiently in Haskell. Non-strict evaluation in Haskell makes it easy to accidentally leak large amounts of memory in unexpected places.

However on the flip side, I prefer to solve a problem in Mathematica first if it’s possible. This is because it has many useful built-in mathematical functions (like prime testing) and objects (like fractions) that would require manual effort to implement in Java. Also, my Java solutions tend to be long due to types on every variable, lots of custom code, and low-level loops instead of higher-order functions. If I was aiming for raw execution speed, writing comparable code in C or C++ would probably run 3× as fast as Java.

Note that for problems involving non-whole numbers, I try to use exact integer arithmetic or fractions as much as possible, which ensures that the solution is provably correct. As a result I strongly avoid any floating-point arithmetic at all, unless there is no other reasonable way (that I know of) to solve the problem. Also I study the numerical bounds carefully to avoid integer overflow, and use the most reasonably narrow type for speed (choosing between `int`, `long`, or `BigInteger`).

To run a Java solution, compile the Java file (e.g. `p001.java`) and also the shared classes `EulerSolution.java` and `Library.java`. Then run with a command like `java p001`, and the answer will be printed to standard output.

Sample code (problem 117) (most other solutions are many times longer):

```public class p117 {
private static final int LENGTH = 50;
public static void main(String[] args) {
// Dynamic programming
long[] ways = new long[LENGTH + 1];
ways = 1;
for (int n = 1; n <= LENGTH; n++) {
for (int k = 1; k <= 4 && k <= n; k++)
ways[n] += ways[n - k];
}
System.out.println(ways[LENGTH]);
}
}
```

Resources:

### Python

Almost all solutions are made available in Python, which is an imperative object-oriented language with many conceptual similarities to Java. These pieces of code are interesting for a couple of reasons: One is that it caters to programmers who prefer to read Python code over Java due to familiar­ity with the language. Another is that the Python code has less syntactic “noise” due to the lack of types, variable declarations, and integer size distinctions – so the Python code expresses the essential ideas of the mathematical algorithms more directly. My code requires Python 3 (but old versions can be found that support both 2 and 3).

The Python solutions were initially based on the Java solutions, often starting with a direct literal port of the Java code into Python. Over time, the Python code was adapted to fit the characteristics of the language – such as using idiomatic/Pythonic approaches, tweaking or changing algorithms to increase speed (whereas Java can sometimes get away with less efficient but simpler algorithms), and making heavy use of generators. The style of using generators/filters/`itertools` can be considered about halfway between Java’s imperative style and {Haskell or Mathematica}’s functional style. Unfortunately due to Python’s slow performance on arrays and machine-word-sized integer values, many solutions are not worth the time to run it compared to the Java implementations.

Sample code (problem 10):

```# Sieve of Eratosthenes
ans = 0
isprime = [True] * 2000001
for i in range(2, len(isprime)):
if isprime[i]:
ans += i
for j in range(i * i, len(isprime), i):
isprime[j] = False
print(ans)```

Resources:

### Mathematica

I used Mathematica for many of the earlier problems, because compactness and convenient library functions were more impor­tant than running time or memory. Mathematica provides easy access to prime numbers, big integers, high-precision floats, fractions, continued fractions, and more. My code tends to be quite short: one-liners are very common, and typically the solution is less than 5 lines of code. For problems that involve computing and/or storing millions of numbers, my experience has been that Mathematica takes too long to run my algorithm or exceeds the memory limit.

In Mathematica, I make heavy use of nested expressions, functional program­ming core functions like `Map` and `Select`, and aggregation functions like `Total`, `Length`, `Sum`. Occasionally I write imperative code in Mathematica, usually for unbounded searching. I write Mathematica code in a rather plain style, using only `[]` for function application (not `@` or `//`), avoid pattern processing, and avoid declaring functions with the `#`-and-`&` syntax.

To run a Mathematica solution, copy the entire code into a new Mathematica notebook and evaluate the whole block of text. The solution is shown in the output.

Sample code (problem 7):

`Prime`

Sample code (problem 20):

`Total[IntegerDigits[100!]]`

Sample code (problem 29):

`Length[Union[Flatten[Table[a^b, {a, 2, 100}, {b, 2, 100}]]]]`

Sample code (problem 323):

```cdf[n_] := (1 - (1/2)^n) ^ 32
pdf[n_] := cdf[n] - cdf[n - 1]
Sum[n * pdf[n], {n, Infinity}]  (* Exact *)
N[%, 11]  (* Rounded *)```

Resources:

I’m a beginner at Haskell programming, and only know how to use it to solve the easier problems in Project Euler. When I do use it, I end up learning many new concepts in functional program­ming, such map/filter/fold, infinite lists, converting iterative algorithms to recursive functions, memoization, etc. When a problem can be solved in a purely functional way without impera­tively updating variables, my Haskell solution will be structured very similarly to my Mathematica solution.

To run a Haskell solution, run the Haskell file as a main program.

Sample code (problem 21):

```main = putStrLn (show ans)
ans = sum [n | n <- [1..10^4], amicable n]

amicable :: Int -> Bool
amicable n = let m = divisorSum n in (m /= n) && (divisorSum m) == n

divisorSum :: Int -> Int
divisorSum n = sum [k | k <- [1..n-1], (mod n k) == 0]```

Resources:

## Benchmark timings

The Project Euler solution programs listed above were bench­marked to see how much time it took to compute the answer. This information gives a rough sense of which problems are easy or hard, and how the choice of program­ming language affects the running time.

Note that the benchmark does not attempt to be “fair” in any way. My solution code is first designed to run within an “accept­able” running time (not targeting absolute fastest code), and then heavily optimized for human clarity (both in terms of the code implementation and the underlying mathematical concepts). Sometimes, slightly inefficient constructs (such as list comprehen­sions) are used for the sake of clarity. The algorithms between different languages are not exactly the same; instead I try to write code that is most idiomatic and clear for the given language. However, it can still be observed that Python is generally 10× to 30× slower than Java for pure number-crunching code.

All the numbers listed in the table below are in seconds, and these computing environments were used:

• Oracle Java 10.0.2+13 (64-bit), Intel Core i5-4690 (Haswell) 3.50 GHz, Windows 8.1 Pro (64-bit).
• CPython 3.7.0 (64-bit), Intel Core i5-4690 (Haswell) 3.50 GHz, Windows 8.1 Pro (64-bit).
• Wolfram Mathematica 5.1 (32-bit), Intel Core i5-2450M (Sandy Bridge) 2.50 GHz, Windows 7 Pro SP1 (64-bit).
• Glasgow Haskell Compiler 7.10.3, compiling with -O option to 64-bit executables, Intel Core i5-4690 (Haswell) 3.50 GHz, Ubuntu Linux 16.04 (64-bit).