├── 112 ├── answer.txt ├── bouncy.hs ├── bouncy.py └── question.markdown ├── 206 ├── answer.txt ├── concealed.py └── question.markdown ├── 243 ├── answer.txt ├── question.markdown └── resilience.hs ├── 379 ├── summatory.py.wip └── summatory.rb.wip ├── .gitignore ├── 001 ├── answer.txt ├── natural.c ├── natural.clj ├── natural.go ├── natural.hs ├── natural.js ├── natural.py ├── natural.rb ├── natural.rs ├── natural.scm └── question.markdown ├── 002 ├── answer.txt ├── fibonacci.clj ├── fibonacci.go ├── fibonacci.hs ├── fibonacci.js ├── fibonacci.rb ├── fibonacci.rs └── question.html ├── 003 ├── answer.txt ├── prime-factor.go ├── prime-factor.hs ├── prime-factor.js ├── prime-factor.py ├── prime-factor.rb ├── prime-factor.rs └── question.markdown ├── 004 ├── answer.txt ├── palindrome.clj ├── palindrome.go ├── palindrome.hs ├── palindrome.js ├── palindrome.py ├── palindrome.rb ├── palindrome.rs └── question.html ├── 005 ├── answer.txt ├── commentary.markdown ├── divisible.clj.wip ├── divisible.go ├── divisible.hs ├── divisible.js ├── divisible.py ├── divisible.rb ├── divisible.rs └── question.markdown ├── 006 ├── answer.txt ├── question.html ├── square-sum.go ├── square-sum.js ├── squareSum.hs ├── square_sum.clj ├── square_sum.py ├── square_sum.rb └── squaresum.rs ├── 007 ├── 10001st-prime.go ├── 10001st-prime.hs ├── 10001st-prime.js ├── answer.txt ├── find-primes.clj ├── find-primes.py ├── find-primes.rb ├── question.markdown └── sieve.rs ├── 008 ├── adjacent-product.go ├── adjacent_product.rs ├── answer.txt ├── great-prod.hs ├── great_prod.py ├── great_prod.rb ├── largest-product.js ├── numbers.txt └── question.markdown ├── 009 ├── answer.txt ├── pythagorean-triples.clj ├── pythagorean-triples.rb ├── pythagorean.go ├── pythagorean.hs ├── pythagorean.js ├── pythagorean.rs └── question.markdown ├── 010 ├── answer.txt ├── primes.rs ├── question.html ├── sum-primes.clj ├── sum-primes.go ├── sum-primes.hs ├── sum-primes.js ├── sum-primes.py └── sum-primes.rb ├── 011 ├── answer.txt ├── grid-product.hs ├── grid-product.py ├── grid-product.rb ├── grid.rs ├── grid.txt └── question.html ├── 012 ├── answer.txt ├── question.html ├── triangle-numbers.clj.wip ├── triangle-numbers.hs ├── triangle-numbers.py ├── triangle-numbers.rb └── triangle.rs ├── 013 ├── answer.txt ├── digits.txt ├── large-sum.hs ├── large-sum.py ├── large-sum.rb ├── question.markdown └── sum.rs ├── 014 ├── answer.txt ├── collatz.rs ├── longest-chain.c.wip ├── longest-chain.clj.wip ├── longest-chain.hs ├── longest-chain.py ├── longest-chain.rb └── question.markdown ├── 015 ├── answer.txt ├── binom.hs ├── binom.rs ├── commentary.markdown ├── grid-routes.py ├── pascal.clj.wip ├── pascal.rb └── question.html ├── 016 ├── answer.txt ├── digits.rs ├── question.html ├── sum-exp.py ├── sum-exp.rb └── sumExp.hs ├── 017 ├── answer.txt ├── english-numbers.js ├── num-string-sum.py ├── number-to-words.rb └── question.html ├── 018 ├── answer.txt ├── max-route.hs ├── max-route.rb ├── pathfinder.rs ├── question.html ├── triangle-max.py └── triangle.txt ├── 019 ├── answer.txt ├── calendar-module-first-sunday.py ├── commentary.markdown ├── first-sunday.py ├── first-sunday.rb └── question.markdown ├── 020 ├── answer.txt ├── factorial.clj ├── factorial.hs ├── factorial.rb ├── factorial_digits.rs └── question.html ├── 021 ├── amicable.clj ├── amicable.hs ├── amicable.rb ├── amicable.rs ├── answer.txt └── question.html ├── 022 ├── answer.txt ├── names.hs ├── names.py ├── names.rb ├── names.rs ├── names.txt └── question.markdown ├── 023 ├── abundant.clj.wip ├── abundant.hs ├── abundant.py ├── abundant.rb ├── abundant.rs ├── answer.txt └── question.markdown ├── 024 ├── answer.txt ├── permutations.hs ├── permutations.js ├── permutations.py ├── permutations.rb ├── permutations.rs └── question.html ├── 025 ├── answer.txt ├── fibonacci.clj ├── fibonacci.hs ├── fibonacci.rb ├── fibonacci.rs └── question.markdown ├── 026 ├── answer.txt ├── cycle.rs ├── decimal-cycle.hs ├── decimal-cycle.rb ├── question.markdown └── recurring-decimal.py ├── 027 ├── answer.txt ├── quadratic-primes.hs ├── quadratic-primes.py ├── quadratic-primes.rb ├── quadratic.rs └── question.markdown ├── 028 ├── answer.txt ├── question.markdown ├── spiral.hs ├── spiral.py ├── spiral.rb └── spiral.rs ├── 029 ├── answer.txt ├── exponent-combinations.py ├── exponent-combinations.rb ├── exponentComb.hs ├── exponents.rs └── question.markdown ├── 030 ├── answer.txt ├── fifth-powers.clj ├── question.markdown ├── sum-of-fifths.rb └── sumFifths.hs ├── 031 ├── answer.txt ├── currency.hs ├── currency.py ├── currency.rb └── question.md ├── 032 ├── answer.txt ├── pandigital-products.py ├── pandigital.hs ├── pandigital.rb └── question.markdown ├── 033 ├── answer.txt ├── curious-fractions.hs ├── curious-fractions.py ├── curious-fractions.rb └── question.markdown ├── 034 ├── answer.txt ├── curious.clj ├── curious.hs ├── curious.rb ├── curious.scm └── question.markdown ├── 035 ├── answer.txt ├── circular-primes.clj.wip ├── circular-primes.hs ├── circular-primes.rb └── question.markdown ├── 036 ├── answer.txt ├── binary-palindrome.rb ├── double-palindrome.hs ├── palindromic-bases.clj └── question.html ├── 037 ├── answer.txt ├── question.markdown ├── truncatable-primes.hs ├── truncatable-primes.py └── truncatable-primes.rb ├── 038 ├── answer.txt ├── pandigital-concatenation.py ├── pandigital-concatenation.rb ├── pandigital-multiples.hs └── question.markdown ├── 039 ├── answer.txt ├── question.html ├── right-triangles.hs ├── triangle-solve.clj.wip ├── triangle-solve.py └── triangle-solve.rb ├── 040 ├── answer.txt ├── champernowne.hs ├── irrational-part.py ├── irrational-part.rb └── question.html ├── 041 ├── answer.txt ├── pandigital-prime.hs ├── pandigital-prime.py ├── pandigital-prime.rb └── question.markdown ├── 042 ├── answer.txt ├── question.html ├── triangle-words.hs ├── triangle-words.py ├── triangle-words.rb └── words.txt ├── 043 ├── answer.txt ├── pandigital-substrings.hs ├── pandigital-substrings.py ├── pandigital-substrings.rb └── question.markdown ├── 044 ├── answer.txt ├── pentagonal-nums.hs ├── pentagonal-nums.py ├── pentagonal-nums.rb └── question.html ├── 045 ├── answer.txt ├── question.markdown ├── tri-pen-hex.hs ├── tri-pen-hex.py └── tri-pen-hex.rb ├── 046 ├── answer.txt ├── composite-prime.py ├── composite-prime.rb ├── goldbach.hs └── question.markdown ├── 047 ├── answer.txt ├── consecutive-factors.hs ├── consecutive-factors.py ├── consecutive-factors.rb └── question.markdown ├── 048 ├── answer.txt ├── power-series.rb ├── question.html ├── raise-to-itself.clj └── self-powers.hs ├── 049 ├── answer.txt ├── prime-permutations.hs ├── prime-sequence.py ├── prime-sequence.rb └── question.markdown ├── 050 ├── answer.txt ├── consecutive-prime-sum.hs ├── consecutive-prime-sum.py ├── consecutive-prime-sum.rb └── question.html ├── 051 ├── answer.txt ├── changing-primes.py ├── prime-replacement.hs └── question.markdown ├── 052 ├── answer.txt ├── permuted-multiples.hs ├── question.markdown └── same-digits.py ├── 053 ├── answer.txt ├── combinatoric-selections.hs ├── large-combos.py └── question.html ├── 054 ├── answer.txt ├── poker.hs ├── poker.py ├── poker.txt └── question.html ├── 055 ├── answer.txt ├── lychrel.hs ├── lychrel.py └── question.markdown ├── 056 ├── answer.txt ├── digit-sum.hs ├── digital-sum.py └── question.markdown ├── 057 ├── answer.txt ├── question.markdown ├── root-two.hs └── root-two.py ├── 058 ├── answer.txt ├── question.html ├── spiral-primes.hs └── spiral-primes.py ├── 059 ├── answer.txt ├── cipher1.txt ├── question.html └── xor-encryption.py ├── 060 ├── answer.txt ├── concatenate-primes.py.wip ├── prime-pairs.hs └── question.md ├── 061 ├── answer.txt ├── figurate-numbers-recursive.py.wip ├── figurate-numbers.hs ├── figurate-numbers.py └── question.markdown ├── 062 ├── answer.txt ├── cube-permutations.py ├── cubic-permutations.hs └── question.html ├── 063 ├── answer.txt ├── n-power.py ├── nPower.hs └── question.html ├── 064 ├── answer.txt ├── continued-fractions.hs └── question.md ├── 065 ├── answer.txt ├── continued.py ├── e-convergents.hs └── question.markdown ├── 066 ├── answer.txt ├── diophantine.hs └── question.md ├── 067 ├── answer.txt ├── maximum-path-sum.hs ├── question.md ├── triangle-max.py └── triangle.txt ├── 068 ├── answer.txt ├── magic-5-gon.hs └── question.html ├── 069 ├── answer.txt ├── question.html ├── totient.hs ├── totient.py └── totient.rb ├── 070 ├── answer.txt ├── question.html ├── totient-permutation.hs ├── totient.py └── totient.rb ├── 071 ├── answer.txt ├── ordered-fractions.hs ├── prop-frac.py └── question.markdown ├── 072 ├── answer.txt ├── counting-fractions.hs ├── farey.py └── question.markdown ├── 073 ├── answer.txt ├── fraction-range.hs ├── fraction-range.py └── question.markdown ├── 074 ├── answer.txt ├── factorial-chains.hs └── question.md ├── 075 ├── answer.txt ├── question.md └── singular-triangles.hs ├── 076 ├── answer.txt ├── counting-summations.hs ├── partitions.py └── question.markdown ├── 077 ├── answer.txt ├── prime-summations.hs └── question.md ├── 078 ├── answer.txt ├── coin-partitions.hs ├── partitions.py └── question.html ├── 079 ├── answer.txt ├── commentary.markdown ├── keylog.txt ├── passcode-derivation.hs ├── password-crack.py └── question.markdown ├── 080 ├── answer.txt ├── question.md └── root-expansion.hs ├── 081 ├── answer.txt ├── matrix.txt ├── minimal_path.py ├── path-sum.js └── question.html ├── 082 ├── answer.txt ├── matrix.txt ├── path-sum.js ├── path-sum.py └── question.html ├── 083 ├── answer.txt ├── matrix.txt ├── path-sum.js ├── path-sum.py └── question.html ├── 084 ├── answer.txt ├── monopoly.py └── question.html ├── 085 ├── answer.txt ├── question.html └── rectangles.py ├── 086 ├── answer.txt ├── cuboid.hs ├── cuboid.py.wip └── question.html ├── 087 ├── answer.txt ├── question.html └── triples.py ├── 088 ├── product-sum.hs.wip ├── product_sum.py.wip └── question.md ├── 089 ├── answer.txt ├── minimal.py ├── question.html └── roman.txt ├── 092 ├── answer.txt ├── number-chain.py └── question.markdown ├── 096 ├── answer.txt ├── question.html ├── sudoku.js └── sudoku.txt ├── 097 ├── answer.txt ├── commentary.markdown ├── non-mersenne.go.wip ├── non-mersenne.py └── question.html ├── 099 ├── answer.txt ├── base_exp.txt ├── commentary.html ├── largest-exponent.py └── question.html ├── LICENSE └── README /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.swp 3 | a.out 4 | -------------------------------------------------------------------------------- /001/answer.txt: -------------------------------------------------------------------------------- 1 | 233168 2 | -------------------------------------------------------------------------------- /001/natural.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char **argv) 4 | { 5 | int sum = 0; 6 | for (int i = 0; i < 1000; i++) { 7 | if (i % 3 == 0 || i % 5 == 0) { 8 | sum += i; 9 | } 10 | } 11 | printf("%d\n", sum); 12 | return 0; 13 | } 14 | 15 | -------------------------------------------------------------------------------- /001/natural.clj: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env clojure 2 | (defn multiple? [n] 3 | (or (= (rem n 3) 0) (= (rem n 5) 0))) 4 | 5 | (println (reduce + (filter multiple? (range 1000)))) 6 | -------------------------------------------------------------------------------- /001/natural.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | sum := 0 7 | for i := 0; i < 1000; i++ { 8 | if i%3 == 0 || i%5 == 0 { 9 | sum += i 10 | } 11 | } 12 | fmt.Println(sum) 13 | } 14 | -------------------------------------------------------------------------------- /001/natural.hs: -------------------------------------------------------------------------------- 1 | main :: IO () 2 | main = print $ sum [n | n <- [1..999], or [(n `mod` 3 == 0), (n `mod` 5 == 0)]] 3 | -------------------------------------------------------------------------------- /001/natural.js: -------------------------------------------------------------------------------- 1 | let s = 0 2 | for (var i = 1; i < 1000; i++) { 3 | if (i % 3 === 0 || i % 5 === 0) { 4 | s += i 5 | } 6 | } 7 | console.log(s) 8 | -------------------------------------------------------------------------------- /001/natural.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | print(sum(i for i in range(1000) if (i % 3 == 0) or (i % 5 == 0))) 3 | -------------------------------------------------------------------------------- /001/natural.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | sum = 0 3 | 1000.times do |i| 4 | if i % 3 == 0 or i % 5 == 0 5 | sum += i 6 | end 7 | end 8 | puts sum 9 | -------------------------------------------------------------------------------- /001/natural.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let result: u64 = (1..1000).filter(|x| x % 3 == 0 || x % 5 == 0).sum(); 3 | println!("{}", result); 4 | } 5 | -------------------------------------------------------------------------------- /001/natural.scm: -------------------------------------------------------------------------------- 1 | (display 2 | (reduce + 0 3 | (filter 4 | (lambda (n) 5 | (or (= (remainder n 3) 0) (= (remainder n 5) 0))) 6 | (iota 1000)))) 7 | (newline) 8 | -------------------------------------------------------------------------------- /001/question.markdown: -------------------------------------------------------------------------------- 1 | If we list all the natural numbers below 10 that are multiples of 3 or 5, we 2 | get 3, 5, 6 and 9. The sum of these multiples is 23. 3 | 4 | Find the sum of all the multiples of 3 or 5 below 1000. 5 | -------------------------------------------------------------------------------- /002/answer.txt: -------------------------------------------------------------------------------- 1 | 4613732 2 | -------------------------------------------------------------------------------- /002/fibonacci.clj: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env clojure 2 | (def fibs (lazy-cat [0 1] (map + (rest fibs) fibs))) 3 | (println (reduce + (filter even? (take-while #(< % 4000000) fibs)))) 4 | 5 | -------------------------------------------------------------------------------- /002/fibonacci.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | sum := 0 7 | for a, b := 1, 2; b <= 4e6; a, b = b, a+b { 8 | if b%2 == 0 { 9 | sum += b 10 | } 11 | } 12 | fmt.Println(sum) 13 | } 14 | -------------------------------------------------------------------------------- /002/fibonacci.hs: -------------------------------------------------------------------------------- 1 | fibs :: [Integer] 2 | fibs = 0 : 1 : zipWith (+) fibs (tail fibs) 3 | 4 | main :: IO () 5 | main = print $ sum $ filter even $ takeWhile (<4000000) fibs 6 | -------------------------------------------------------------------------------- /002/fibonacci.js: -------------------------------------------------------------------------------- 1 | let s = 0 2 | let f = [1, 1] 3 | while (f[0] < 4e6) { 4 | if (f[0] % 2 === 0) s+= f[0] 5 | f = [f[1], f[0] + f[1]] 6 | } 7 | console.log(s) 8 | -------------------------------------------------------------------------------- /002/fibonacci.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | sum, a, b = 0, 1, 2 3 | while b < 4000000 4 | sum += b if b.even? 5 | a, b = b, a + b 6 | end 7 | puts sum 8 | -------------------------------------------------------------------------------- /002/fibonacci.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut sum = 0; 3 | let mut a = 1; 4 | let mut b = 2; 5 | let mut tmp; 6 | while b <= 4000000 { 7 | if b % 2 == 0 { 8 | sum += b; 9 | } 10 | tmp = a + b; 11 | a = b; 12 | b = tmp; 13 | } 14 | println!("{}", sum); 15 | } 16 | -------------------------------------------------------------------------------- /002/question.html: -------------------------------------------------------------------------------- 1 |

2 | Each new term in the Fibonacci sequence is generated by adding the previous two 3 | terms. By starting with 1 and 2, the first 10 terms will be: 4 |

5 | 6 | $$1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...$$ 7 | 8 |

9 | Find the sum of all the even-valued terms in the sequence which do not exceed 10 | four million. 11 |

12 | -------------------------------------------------------------------------------- /003/answer.txt: -------------------------------------------------------------------------------- 1 | 6857 2 | -------------------------------------------------------------------------------- /003/prime-factor.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | import "math" 5 | import "math/big" 6 | 7 | func eratosthenes(max int) []int { 8 | nums := make([]int, max) 9 | 10 | p := 2 // first prime, 2 11 | for { 12 | i := p - 1 13 | // mark multiples not prime 14 | for i += p; i < max; i += p { 15 | nums[i] = -1 16 | } 17 | // find first unmarked number greater than p 18 | for i = p; i < max; i++ { 19 | if nums[i] != -1 { 20 | p = i + 1 21 | break 22 | } 23 | } 24 | // no unmarked numbers greater than p found; finished 25 | if i == max { 26 | break 27 | } 28 | } 29 | // filter out all marked numbers 30 | primes := make([]int, max) 31 | j := 0 32 | for i := range nums { 33 | if nums[i] == 0 { 34 | primes[j] = i + 1 35 | j++ 36 | } 37 | } 38 | return primes[:j] 39 | } 40 | 41 | func main() { 42 | n := new(big.Int) 43 | n.SetString("600851475143", 10) 44 | m := new(big.Int) 45 | max := int(math.Sqrt(600851475143)) 46 | primes := eratosthenes(max) 47 | // find the largest prime factor of n 48 | for i := len(primes) - 1; i >= 0; i-- { 49 | p := big.NewInt(int64(primes[i])) 50 | m.Mod(n, p) 51 | if m.Int64() == 0 { 52 | fmt.Println(p) 53 | break 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /003/prime-factor.hs: -------------------------------------------------------------------------------- 1 | primes :: [Integer] 2 | primes = sieve [2..] where 3 | sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p > 0] 4 | 5 | factorize :: Integer -> [Integer] 6 | factorize n = primeFactors n primes where 7 | primeFactors 1 _ = [] 8 | primeFactors m (p:ps) | m < p * p = [m] 9 | | r == 0 = p : primeFactors q (p:ps) 10 | | otherwise = primeFactors m ps 11 | where (q, r) = quotRem m p 12 | 13 | main :: IO () 14 | main = print $ maximum $ factorize 600851475143 15 | -------------------------------------------------------------------------------- /003/prime-factor.js: -------------------------------------------------------------------------------- 1 | let n = 600851475143 2 | let limit = Math.ceil(Math.sqrt(n)) 3 | for (var i = 3; i <= limit; i += 2) { 4 | while (n % i === 0) { 5 | n = Math.floor(n / i) 6 | limit = Math.ceil(Math.sqrt(n)) 7 | } 8 | } 9 | console.log(n) 10 | -------------------------------------------------------------------------------- /003/prime-factor.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import math 3 | 4 | def factorize(n): 5 | res = [] 6 | # iterate over all even numbers first. 7 | while n % 2 == 0: 8 | res.append(2) 9 | n //= 2 10 | # try odd numbers up to sqrt(n) 11 | limit = math.sqrt(n+1) 12 | i = 3 13 | while i <= limit: 14 | if n % i == 0: 15 | res.append(i) 16 | n //= i 17 | limit = math.sqrt(n+i) 18 | else: 19 | i += 2 20 | if n != 1: 21 | res.append(n) 22 | return res 23 | 24 | print(max(factorize(600851475143))) 25 | -------------------------------------------------------------------------------- /003/prime-factor.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | def factorize(orig) 4 | factors = {} 5 | factors.default = 0 # return 0 instead nil if key not found in hash 6 | n = orig 7 | i = 2 8 | sqi = 4 # square of i 9 | while sqi <= n do 10 | while n.modulo(i) == 0 do 11 | n /= i 12 | factors[i] += 1 13 | # puts "Found factor #{i}" 14 | end 15 | # we take advantage of the fact that (i +1)**2 = i**2 + 2*i +1 16 | sqi += 2 * i + 1 17 | i += 1 18 | end 19 | 20 | if (n != 1) && (n != orig) 21 | factors[n] += 1 22 | end 23 | factors 24 | end 25 | 26 | puts factorize(600851475143).keys.max 27 | -------------------------------------------------------------------------------- /003/prime-factor.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut n: u64 = 600851475143; 3 | let mut limit = n / 2; 4 | let mut i = 3; 5 | while i < limit { 6 | while n % i == 0 { 7 | n = n / i; 8 | limit = n / 2; 9 | } 10 | i += 2; 11 | } 12 | println!("{}", n); 13 | } 14 | -------------------------------------------------------------------------------- /003/question.markdown: -------------------------------------------------------------------------------- 1 | The prime factors of 13195 are 5, 7, 13 and 29. 2 | 3 | What is the largest prime factor of the number 600851475143 ? 4 | -------------------------------------------------------------------------------- /004/answer.txt: -------------------------------------------------------------------------------- 1 | 906609 2 | -------------------------------------------------------------------------------- /004/palindrome.clj: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env clojure 2 | (defn palindrome? [n] 3 | (= (seq (str n)) (reverse (str n)))) 4 | 5 | (defn palindromes [limit] 6 | (filter palindrome? (for [a (range 100 1000) b (range a 1000)] (* a b)))) 7 | 8 | (println (reduce max (palindromes 1000))) 9 | -------------------------------------------------------------------------------- /004/palindrome.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func IsPalindrome(number int) bool { 6 | n := number 7 | reversed, digit := 0, 0 8 | for n > 0 { 9 | digit = n % 10 10 | reversed = reversed*10 + digit 11 | n /= 10 12 | } 13 | return number == reversed 14 | } 15 | 16 | func main() { 17 | product, max := 0, 0 18 | for a := 100; a < 1000; a++ { 19 | for b := a; b < 1000; b++ { 20 | product = a * b 21 | if product > max && IsPalindrome(product) { 22 | max = product 23 | } 24 | } 25 | } 26 | fmt.Println(max) 27 | } 28 | -------------------------------------------------------------------------------- /004/palindrome.hs: -------------------------------------------------------------------------------- 1 | isPalindrome :: Integer -> Bool 2 | isPalindrome n = show n == reverse (show n) 3 | 4 | main :: IO () 5 | main = print $ maximum [prod | a <- [100..999], b <- [a..999], let prod = a * b, isPalindrome prod] 6 | -------------------------------------------------------------------------------- /004/palindrome.js: -------------------------------------------------------------------------------- 1 | const isPalindrome = (s) => s === s.split("").reverse().join("") 2 | let max = 0 3 | for (let i = 100; i < 1000; i++) { 4 | for (let j = 100; j < 1000; j++) { 5 | const s = (i * j) 6 | if (s > max && isPalindrome(s.toString())) { 7 | max = s 8 | } 9 | } 10 | } 11 | console.log(max) 12 | -------------------------------------------------------------------------------- /004/palindrome.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | print(max(a * b for a in range(100, 1000) for b in range(a, 1000) if str(a * b) == str(a * b)[::-1])) 3 | -------------------------------------------------------------------------------- /004/palindrome.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | class Integer 4 | def palindromic? 5 | digits = self.to_s.split('') 6 | return digits == digits.reverse 7 | end 8 | end 9 | 10 | max = 0 11 | (100..999).each do |a| 12 | (a..999).each do |b| 13 | product = a * b 14 | if product > max and product.palindromic? 15 | max = product 16 | end 17 | end 18 | end 19 | puts max 20 | -------------------------------------------------------------------------------- /004/palindrome.rs: -------------------------------------------------------------------------------- 1 | fn is_palindrome(number: u64) -> bool { 2 | let mut n = number; 3 | let mut reversed = 0; 4 | while n > 0 { 5 | let digit = n % 10; 6 | reversed = reversed * 10 + digit; 7 | n /= 10; 8 | } 9 | number == reversed 10 | } 11 | 12 | fn main() { 13 | let mut largest = 0; 14 | for a in 100..1000 { 15 | for b in 100..1000 { 16 | let product = a * b; 17 | if product > largest && is_palindrome(product) { 18 | largest = product; 19 | } 20 | } 21 | } 22 | println!("{}", largest); 23 | } 24 | -------------------------------------------------------------------------------- /004/question.html: -------------------------------------------------------------------------------- 1 |

2 | A palindromic number reads the same both ways. The largest palindrome 3 | made from the product of two 2-digit numbers is $9009 = 91 \times 99$. 4 |

5 | 6 |

7 | Find the largest palindrome made from the product of two 3-digit numbers. 8 |

9 | -------------------------------------------------------------------------------- /005/answer.txt: -------------------------------------------------------------------------------- 1 | 232792560 2 | -------------------------------------------------------------------------------- /005/commentary.markdown: -------------------------------------------------------------------------------- 1 | The critical insight of this problem is this: 2 | 3 | $$divisibleto(x) = n \times divisibleto(x-1)$$ 4 | 5 | This means that when searching for the smallest number divisible to 20, 6 | we can increment by the smallest number divisible to 19 each time (since the 7 | smallest number divisible to 19 is inherently a factor of the smallest number 8 | divisible to 20). 9 | 10 | This insight is used in the python solution on line 14: 11 | 12 | step = divisible_to(x-1) 13 | 14 | This is a recursive solution to the problem, and yields incredible performance. It can calculate 15 | the smallest number divisible to 500 in a fraction of a second. 16 | -------------------------------------------------------------------------------- /005/divisible.clj.wip: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env clojure 2 | (defn divisible-to-x? [n x] 3 | (every? #(= (rem n %) 0) (reverse (range 1 (+ x 1))))) 4 | 5 | (defn divisible-to [x] 6 | (if (= x 1) 7 | x 8 | (first (filter #(divisible-to-x? % x) (iterate inc (divisible-to (- x 1))))))) 9 | 10 | (println (divisible-to 20)) 11 | -------------------------------------------------------------------------------- /005/divisible.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func GCD(a, b int) int { 6 | for b != 0 { 7 | a, b = b, a%b 8 | } 9 | return a 10 | } 11 | 12 | func main() { 13 | lcm := 1 14 | for i := 2; i <= 20; i++ { 15 | lcm *= i / GCD(i, lcm) 16 | } 17 | fmt.Println(lcm) 18 | } 19 | -------------------------------------------------------------------------------- /005/divisible.hs: -------------------------------------------------------------------------------- 1 | isDivisibleTo :: Integer -> Integer -> Bool 2 | isDivisibleTo x n = all (\i -> n `mod` i == 0) (reverse [1..x]) 3 | 4 | divisibleTo :: Integer -> Integer 5 | divisibleTo 1 = 1 6 | divisibleTo x = let step = divisibleTo (x-1) 7 | in head $ filter (isDivisibleTo x) [step,2*step..] 8 | 9 | main :: IO () 10 | main = print $ divisibleTo 20 11 | -------------------------------------------------------------------------------- /005/divisible.js: -------------------------------------------------------------------------------- 1 | function isDivisibleTo(x, n) { 2 | for (; n > 0; n -= 1) { 3 | if (x % n !== 0) { 4 | return false 5 | } 6 | } 7 | return true 8 | } 9 | 10 | function divisibleTo(n) { 11 | if (n === 1) return 1 12 | for (var step = divisibleTo(n - 1), i = step; !isDivisibleTo(i, n); i += step); 13 | return i 14 | } 15 | 16 | console.log(divisibleTo(20)) 17 | -------------------------------------------------------------------------------- /005/divisible.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | def is_divisible_to(number, x): 3 | for i in reversed(list(range(1, x+1))): 4 | if number % i != 0: 5 | return False 6 | return True 7 | 8 | def divisible_to(x): 9 | if x < 1: 10 | return False 11 | elif x == 1: 12 | return 1 13 | else: 14 | step = divisible_to(x-1) 15 | number = 0 16 | found = False 17 | while not found: 18 | number += step 19 | found = is_divisible_to(number, x) 20 | return number 21 | 22 | print(divisible_to(20)) 23 | -------------------------------------------------------------------------------- /005/divisible.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | class Numeric 4 | def divisible_to?(x) 5 | self > 0 and x.downto(1).all? { |i| self % i == 0 } 6 | end 7 | end 8 | 9 | def divisible_to(x) 10 | if x < 1 11 | return false 12 | elsif x == 1 13 | return 1 14 | else 15 | n = 0 16 | step = divisible_to(x-1) 17 | until n.divisible_to? x 18 | n += step 19 | end 20 | return n 21 | end 22 | end 23 | 24 | puts divisible_to(20) 25 | -------------------------------------------------------------------------------- /005/divisible.rs: -------------------------------------------------------------------------------- 1 | fn gcd(mut a: u64, mut b: u64) -> u64 { 2 | while b != 0 { 3 | let t = a; 4 | a = b; 5 | b = t % b; 6 | } 7 | a 8 | } 9 | 10 | fn main() { 11 | let lcm = (2..21).fold(1, |acc, i| { 12 | acc * i / gcd(i, acc) 13 | }); 14 | println!("{}", lcm); 15 | } 16 | -------------------------------------------------------------------------------- /005/question.markdown: -------------------------------------------------------------------------------- 1 | 2520 is the smallest number that can be divided by each 2 | of the numbers from 1 to 10 without any remainder. 3 | 4 | What is the smallest positive number that is evenly divisible 5 | by all of the numbers from 1 to 20? 6 | -------------------------------------------------------------------------------- /006/answer.txt: -------------------------------------------------------------------------------- 1 | 25164150 2 | -------------------------------------------------------------------------------- /006/question.html: -------------------------------------------------------------------------------- 1 |

2 | The sum of the squares of the first ten natural numbers is, 3 |

4 | 5 | $$1^2 + 2^2 + ... + 10^2 = 385$$ 6 | 7 |

8 | The square of the sum of the first ten natural numbers is, 9 |

10 | 11 | $$(1 + 2 + ... + 10)^2 = 55^2 = 3025$$ 12 | 13 |

14 | Hence the difference between the sum of the squares of the first ten natural 15 | numbers and the square of the sum is $3025 - 385 = 2640$. 16 |

17 | 18 |

19 | Find the difference between the sum of the squares of the first one hundred 20 | natural numbers and the square of the sum. 21 |

22 | -------------------------------------------------------------------------------- /006/square-sum.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | sumSquares, squareSum := 0, 0 7 | for i := 1; i <= 100; i++ { 8 | sumSquares += i * i 9 | squareSum += i 10 | } 11 | squareSum *= squareSum 12 | fmt.Println(squareSum - sumSquares) 13 | } 14 | -------------------------------------------------------------------------------- /006/square-sum.js: -------------------------------------------------------------------------------- 1 | let sum = 0, sumSquares = 0 2 | for (let i = 1; i <= 100; i++) { 3 | sum += i 4 | sumSquares += i * i 5 | } 6 | console.log(sum * sum - sumSquares) 7 | -------------------------------------------------------------------------------- /006/squareSum.hs: -------------------------------------------------------------------------------- 1 | main :: IO () 2 | main = print $ (s*s) - sqS where 3 | s = sum [1..100] 4 | sqS = sum [i * i | i <- [1..100]] 5 | -------------------------------------------------------------------------------- /006/square_sum.clj: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env clojure 2 | (defn square [x] 3 | (* x x)) 4 | 5 | (defn sum-squares [limit] 6 | (apply + (map square (range 1 (+ limit 1))))) 7 | 8 | (defn square-sum [limit] 9 | (square (apply + (range 1 (+ limit 1))))) 10 | 11 | (println (- (square-sum 100) (sum-squares 100))) 12 | -------------------------------------------------------------------------------- /006/square_sum.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | print(sum(range(1, 101))**2 - sum(x**2 for x in range(1, 101))) 3 | -------------------------------------------------------------------------------- /006/square_sum.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | puts ((1..100).inject(0) {|s,v| s += v})**2 - ((1..100).collect {|x| x**2}.inject(0) { |s,v| s += v}) 3 | -------------------------------------------------------------------------------- /006/squaresum.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let sum_squares = (1..101).map(|x| x*x).sum::(); 3 | let square_sum = (1..101).sum::().pow(2); 4 | println!("{}", square_sum - sum_squares); 5 | } 6 | -------------------------------------------------------------------------------- /007/10001st-prime.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func iSqrt(n int64) int64 { 6 | var r1, r int64 = n, n + 1 7 | for r1 < r { 8 | r, r1 = r1, (r1+n/r1)>>1 9 | } 10 | return r 11 | } 12 | 13 | func PrimeSieve(n int64) []int64 { 14 | result := make([]int64, 0, n) 15 | sieve := make([]bool, n+1) 16 | sn := iSqrt(n) 17 | var i, j int64 18 | for i = 2; i <= sn; i++ { 19 | if !sieve[i] { 20 | for j = i * i; j <= n; j += i { 21 | sieve[j] = true 22 | } 23 | } 24 | } 25 | for i = 2; i <= n; i++ { 26 | if !sieve[i] { 27 | result = append(result, i) 28 | } 29 | } 30 | return result 31 | } 32 | 33 | func main() { 34 | primes := PrimeSieve(1000000) 35 | fmt.Println(primes[10000]) 36 | } 37 | -------------------------------------------------------------------------------- /007/10001st-prime.hs: -------------------------------------------------------------------------------- 1 | primes :: [Integer] 2 | primes = 2 : sieve primes [3,5..] where 3 | sieve (p:ps) xs = h ++ sieve ps [x | x <- t, rem x p /= 0] 4 | where (h, t) = span (< p*p) xs 5 | 6 | main :: IO () 7 | main = print $ primes !! 10000 8 | -------------------------------------------------------------------------------- /007/10001st-prime.js: -------------------------------------------------------------------------------- 1 | const sieve = {} 2 | let n = 0 3 | for (var q = 2; n < 10001; q++) { 4 | if (sieve[q]) { 5 | sieve[q].forEach((p) => { 6 | const list = sieve[p + q] || [] 7 | list.push(p) 8 | sieve[p + q] = list 9 | }) 10 | } else { 11 | sieve[q * q] = [q] 12 | n++ 13 | } 14 | } 15 | console.log(q - 1) 16 | -------------------------------------------------------------------------------- /007/answer.txt: -------------------------------------------------------------------------------- 1 | 104743 2 | -------------------------------------------------------------------------------- /007/find-primes.clj: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env clojure 2 | (defn primes [n] 3 | (defn improve [p nums] 4 | (filter #(or 5 | (not (= (rem % p) 0)) 6 | (= % p)) 7 | nums)) 8 | (defn prime-iter [p nums i] 9 | (if (> (* p p) n) 10 | nums 11 | (prime-iter (nth nums (+ i 1)) (improve (nth nums (+ i 1)) nums) (+ i 1)))) 12 | (prime-iter 2 (range 2 (+ n 1)) -1)) 13 | 14 | (println (nth (primes 1000000) 10000)) 15 | -------------------------------------------------------------------------------- /007/find-primes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | def eratosthenes(): 3 | '''Yields the sequence of prime numbers via the Sieve of Eratosthenes.''' 4 | D = {} # map composite integers to primes witnessing their compositeness 5 | q = 2 # first integer to test for primality 6 | while 1: 7 | if q not in D: 8 | yield q # not marked composite, must be prime 9 | D[q*q] = [q] # first multiple of q not already marked 10 | else: 11 | for p in D[q]: # move each witness to its next multiple 12 | D.setdefault(p+q,[]).append(p) 13 | del D[q] # no longer need D[q], free memory 14 | q += 1 15 | 16 | def nth_prime(n): 17 | for i, prime in enumerate(eratosthenes()): 18 | if i == n - 1: 19 | return prime 20 | 21 | print(nth_prime(10001)) 22 | -------------------------------------------------------------------------------- /007/find-primes.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'mathn' 3 | puts Prime.take(10001).last 4 | -------------------------------------------------------------------------------- /007/question.markdown: -------------------------------------------------------------------------------- 1 | By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, 2 | we can see that the 6th prime is 13. 3 | 4 | What is the 10001st prime number? 5 | -------------------------------------------------------------------------------- /007/sieve.rs: -------------------------------------------------------------------------------- 1 | fn eratosthenes(limit: usize) -> Vec { 2 | let mut sieve = vec![true; limit]; 3 | let mut p = 2; 4 | loop { 5 | // Eliminate multiples of p. 6 | let mut i = 2 * p - 1; 7 | while i < limit { 8 | sieve[i] = false; 9 | i += p; 10 | } 11 | // Find the next prime. 12 | if let Some(n) = (p..limit).find(|&n| sieve[n]) { 13 | p = n + 1; 14 | } else { 15 | break; 16 | } 17 | } 18 | sieve 19 | .iter() 20 | .enumerate() 21 | .filter(|&(_, &is_prime)| is_prime) 22 | .skip(1) 23 | .map(|(i, _)| i + 1) 24 | .collect() 25 | } 26 | 27 | fn main() { 28 | let primes = eratosthenes(1000000); 29 | println!("{}", primes[10000]); 30 | } 31 | -------------------------------------------------------------------------------- /008/adjacent_product.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let bytes = include_str!("numbers.txt"); 3 | let digits: Vec = bytes 4 | .chars() 5 | .filter_map(|c| c.to_digit(10)) 6 | .map(|c| c as u64) 7 | .collect(); 8 | let max: u64 = digits 9 | .windows(13) 10 | .map(|digits| digits.iter().product()) 11 | .max() 12 | .unwrap(); 13 | println!("{}", max); 14 | } 15 | -------------------------------------------------------------------------------- /008/answer.txt: -------------------------------------------------------------------------------- 1 | 23514624000 2 | -------------------------------------------------------------------------------- /008/great-prod.hs: -------------------------------------------------------------------------------- 1 | parse :: String -> [Int] 2 | parse = map (read . return) . concat . lines 3 | 4 | chunks :: Int -> [a] -> [[a]] 5 | chunks n l | length chunk < n = [] 6 | | otherwise = chunk : chunks n (tail l) 7 | where chunk = take n l 8 | 9 | largestProduct :: [[Int]] -> Int 10 | largestProduct = maximum . map product 11 | 12 | main :: IO () 13 | main = do 14 | str <- readFile "/home/zach/code/euler/008/numbers.txt" 15 | print $ largestProduct $ chunks 13 $ parse str 16 | -------------------------------------------------------------------------------- /008/numbers.txt: -------------------------------------------------------------------------------- 1 | 73167176531330624919225119674426574742355349194934 2 | 96983520312774506326239578318016984801869478851843 3 | 85861560789112949495459501737958331952853208805511 4 | 12540698747158523863050715693290963295227443043557 5 | 66896648950445244523161731856403098711121722383113 6 | 62229893423380308135336276614282806444486645238749 7 | 30358907296290491560440772390713810515859307960866 8 | 70172427121883998797908792274921901699720888093776 9 | 65727333001053367881220235421809751254540594752243 10 | 52584907711670556013604839586446706324415722155397 11 | 53697817977846174064955149290862569321978468622482 12 | 83972241375657056057490261407972968652414535100474 13 | 82166370484403199890008895243450658541227588666881 14 | 16427171479924442928230863465674813919123162824586 15 | 17866458359124566529476545682848912883142607690042 16 | 24219022671055626321111109370544217506941658960408 17 | 07198403850962455444362981230987879927244284909188 18 | 84580156166097919133875499200524063689912560717606 19 | 05886116467109405077541002256983155200055935729725 20 | 71636269561882670428252483600823257530420752963450 21 | -------------------------------------------------------------------------------- /009/answer.txt: -------------------------------------------------------------------------------- 1 | 31875000 2 | -------------------------------------------------------------------------------- /009/pythagorean-triples.clj: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env clojure 2 | (defn square [n] 3 | (* n n)) 4 | 5 | (defn triple? [a b c] 6 | (and 7 | (and (> a 0) (> b 0) (> c 0)) 8 | (and (< a b) (< b c)) 9 | (= (+ (square a) (square b)) (square c)))) 10 | 11 | (defn candidates [limit] 12 | (for [a (range 1 (inc limit)) 13 | b (range a (inc limit)) 14 | c (range b (inc limit)) 15 | :when (and 16 | (= (+ a b c) 1000) 17 | (triple? a b c))] 18 | (list a b c))) 19 | 20 | (println (reduce * (first (candidates 500)))) 21 | -------------------------------------------------------------------------------- /009/pythagorean-triples.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | for a in (1..500) 3 | for b in (a..500) 4 | for c in (b..500) 5 | if a**2 + b**2 == c**2 and a+b+c == 1000 6 | puts a*b*c 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /009/pythagorean.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var a, b, c, lb int 7 | max := 1000 8 | for a = 1; a < max; a++ { 9 | lb = max - a 10 | for b = a; b < lb; b++ { 11 | c = max - (a + b) 12 | if a*a+b*b == c*c { 13 | fmt.Println(a * b * c) 14 | return 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /009/pythagorean.hs: -------------------------------------------------------------------------------- 1 | main :: IO () 2 | main = print $ head [a*b*c | a <- [1..500], b <- [a..500], c <- [b..500], 3 | a+b+c == 1000, a*a + b*b == c*c] 4 | -------------------------------------------------------------------------------- /009/pythagorean.js: -------------------------------------------------------------------------------- 1 | for (let a = 1; a < 1000; a++) { 2 | for (let b = a, lb = 1000 - a; b < lb; b++) { 3 | const c = 1000 - (a + b) 4 | if (a * a + b * b === c * c) { 5 | return console.log(a * b * c) 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /009/pythagorean.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | for a in 1..1000 { 3 | for b in a..(1000 - a) { 4 | let c = 1000 - (a + b); 5 | if a * a + b * b == c * c { 6 | return println!("{}", a * b * c); 7 | } 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /009/question.markdown: -------------------------------------------------------------------------------- 1 | A Pythagorean triplet is a set of three natural numbers, $a \lt b \lt c$, 2 | for which 3 | 4 | $$a^2 + b^2 = c^2$$ 5 | 6 | For example, $3^2 + 4^2 = 9 + 16 = 25 = 5^2$. 7 | 8 | There exists exactly one Pythagorean triplet for which $a + b + c = 1000$. 9 | Find the product $a \times b \times c$. 10 | -------------------------------------------------------------------------------- /010/answer.txt: -------------------------------------------------------------------------------- 1 | 142913828922 2 | -------------------------------------------------------------------------------- /010/primes.rs: -------------------------------------------------------------------------------- 1 | fn eratosthenes(limit: usize) -> Vec { 2 | let mut sieve = vec![true; limit]; 3 | let mut p = 2; 4 | loop { 5 | // Eliminate multiples of p. 6 | let mut i = 2 * p - 1; 7 | while i < limit { 8 | sieve[i] = false; 9 | i += p; 10 | } 11 | // Find the next prime. 12 | if let Some(n) = (p..limit).find(|&n| sieve[n]) { 13 | p = n + 1; 14 | } else { 15 | break; 16 | } 17 | } 18 | sieve 19 | .iter() 20 | .enumerate() 21 | .filter(|&(_, &is_prime)| is_prime) 22 | .skip(1) 23 | .map(|(i, _)| i + 1) 24 | .collect() 25 | } 26 | 27 | fn main() { 28 | let sum: usize = eratosthenes(2000000).iter().sum(); 29 | println!("{}", sum); 30 | } 31 | -------------------------------------------------------------------------------- /010/question.html: -------------------------------------------------------------------------------- 1 |

2 | The sum of the primes below 10 is $2 + 3 + 5 + 7 = 17$. 3 |

4 | 5 |

6 | Find the sum of all the primes below two million. 7 |

8 | -------------------------------------------------------------------------------- /010/sum-primes.clj: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env clojure 2 | (defn primes [n] 3 | (defn improve [p nums] 4 | (filter #(or 5 | (not (= (rem % p) 0)) 6 | (= % p)) 7 | nums)) 8 | (defn prime-iter [p nums i] 9 | (if (> (* p p) n) 10 | nums 11 | (prime-iter (nth nums (+ i 1)) (improve (nth nums (+ i 1)) nums) (+ i 1)))) 12 | (prime-iter 2 (range 2 (+ n 1)) -1)) 13 | 14 | (println (reduce + (primes 2000000))) 15 | -------------------------------------------------------------------------------- /010/sum-primes.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | import "math" 5 | 6 | func PrimeSieve(n int64) []int64 { 7 | result := make([]int64, 0, n/int64(math.Log(float64(n)))) 8 | sieve := make([]bool, n+1) 9 | sn := int64(math.Sqrt(float64(n))) 10 | var i, j int64 11 | for i = 2; i <= sn; i++ { 12 | if !sieve[i] { 13 | for j = i * i; j <= n; j += i { 14 | sieve[j] = true 15 | } 16 | } 17 | } 18 | for i = 2; i <= n; i++ { 19 | if !sieve[i] { 20 | result = append(result, i) 21 | } 22 | } 23 | return result 24 | } 25 | 26 | func main() { 27 | primes := PrimeSieve(2000000) 28 | var sum int64 = 0 29 | for _, p := range primes { 30 | sum += p 31 | } 32 | fmt.Println(sum) 33 | } 34 | -------------------------------------------------------------------------------- /010/sum-primes.hs: -------------------------------------------------------------------------------- 1 | primes :: [Integer] 2 | primes = 2 : sieve primes [3,5..] where 3 | sieve (p:ps) xs = h ++ sieve ps [x | x <- t, rem x p /= 0] 4 | where (h, t) = span (< p*p) xs 5 | 6 | main :: IO () 7 | main = print $ sum $ takeWhile (< 2000000) primes 8 | -------------------------------------------------------------------------------- /010/sum-primes.js: -------------------------------------------------------------------------------- 1 | const sieve = {} 2 | let s = 0 3 | for (let q = 2; q < 2000000; q++) { 4 | if (sieve[q]) { 5 | sieve[q].forEach((p) => { 6 | const list = sieve[p + q] || [] 7 | list.push(p) 8 | sieve[p + q] = list 9 | }) 10 | delete sieve[q] 11 | } else { 12 | s += q 13 | sieve[q * q] = [q] 14 | } 15 | } 16 | console.log(s) 17 | -------------------------------------------------------------------------------- /010/sum-primes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from itertools import takewhile 3 | 4 | def eratosthenes(): 5 | '''Yields the sequence of prime numbers via the Sieve of Eratosthenes.''' 6 | D = {} # map composite integers to primes witnessing their compositeness 7 | q = 2 # first integer to test for primality 8 | while 1: 9 | if q not in D: 10 | yield q # not marked composite, must be prime 11 | D[q*q] = [q] # first multiple of q not already marked 12 | else: 13 | for p in D[q]: # move each witness to its next multiple 14 | D.setdefault(p+q,[]).append(p) 15 | del D[q] # no longer need D[q], free memory 16 | q += 1 17 | 18 | print(sum(takewhile(lambda x: x < 2000000, eratosthenes()))) 19 | -------------------------------------------------------------------------------- /010/sum-primes.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'mathn' 3 | puts Prime.take_while{ |n| n < 2000000 }.reduce(:+) 4 | -------------------------------------------------------------------------------- /011/answer.txt: -------------------------------------------------------------------------------- 1 | 70600674 2 | -------------------------------------------------------------------------------- /011/grid-product.hs: -------------------------------------------------------------------------------- 1 | import Data.List (tails, transpose) 2 | 3 | parse :: String -> [[Int]] 4 | parse = map (map read . words) . lines 5 | 6 | chunks :: Int -> [a] -> [[a]] 7 | chunks n l | length chunk < n = [] 8 | | otherwise = chunk : chunks n (tail l) 9 | where chunk = take n l 10 | 11 | horizontal :: [[Int]] -> [[Int]] 12 | horizontal = concatMap (chunks 4) 13 | 14 | vertical :: [[Int]] -> [[Int]] 15 | vertical = horizontal . transpose 16 | 17 | diagonal :: [[Int]] -> [[Int]] 18 | diagonal = vertical . zipWith drop [0..] 19 | 20 | southEast :: [[Int]] -> [[Int]] 21 | southEast = concatMap diagonal . tails 22 | 23 | southWest :: [[Int]] -> [[Int]] 24 | southWest = southEast . map reverse 25 | 26 | largestProduct :: [[Int]] -> Int 27 | largestProduct = maximum . map product 28 | 29 | main :: IO () 30 | main = do 31 | str <- readFile "/home/zach/code/euler/011/grid.txt" 32 | let grid = parse str 33 | print $ largestProduct $ concatMap ($grid) [horizontal, vertical, southEast, southWest] 34 | 35 | -------------------------------------------------------------------------------- /011/grid.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let grid: Vec = include_str!("grid.txt") 3 | .split(|c| c == ' ' || c == '\n') 4 | .filter_map(|n| n.parse().ok()) 5 | .collect(); 6 | let grid_length = grid.len() as isize; 7 | let intervals: [isize; 4] = [1, 20, 21, -19]; 8 | let max_product: u64 = grid.iter() 9 | .enumerate() 10 | .map(|(i, _)| { 11 | intervals 12 | .iter() 13 | .filter_map(|interval| { 14 | let last = (i as isize) + 3 * interval; 15 | if last >= 0 && last < grid_length { 16 | let product = (0..4) 17 | .map(|x| grid[((i as isize) + x * interval) as usize]) 18 | .product(); 19 | Some(product) 20 | } else { 21 | None 22 | } 23 | }) 24 | .max() 25 | .unwrap() 26 | }) 27 | .max() 28 | .unwrap(); 29 | println!("{}", max_product); 30 | } 31 | -------------------------------------------------------------------------------- /012/answer.txt: -------------------------------------------------------------------------------- 1 | 76576500 2 | -------------------------------------------------------------------------------- /012/question.html: -------------------------------------------------------------------------------- 1 |

2 | The sequence of triangle numbers is generated by adding 3 | the natural numbers. So the 7th triangle number would be 4 | $1 + 2 + 3 + 4 + 5 + 6 + 7 = 28$. The first ten terms would be: 5 |

6 | 7 | $$1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...$$ 8 | 9 |

10 | Let us list the factors of the first seven triangle numbers: 11 |

12 | 13 |
1:  1
14 | 3:  1,3
15 | 6:  1,2,3,6
16 | 10: 1,2,5,10
17 | 15: 1,3,5,15
18 | 21: 1,3,7,21
19 | 28: 1,2,4,7,14,28
20 | 
21 | 22 |

23 | We can see that 28 is the first triangle number to have over 24 | five divisors. What is the value of the first triangle number 25 | to have over five hundred divisors? 26 |

27 | -------------------------------------------------------------------------------- /012/triangle-numbers.clj.wip: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env clojure 2 | (defn divisor? [b n] 3 | (= (rem n b) 0)) 4 | 5 | (defn triangle-number [n] 6 | (cond 7 | (< n 1) nil 8 | (= n 1) 1 9 | :else (+ n (triangle-number (dec n))))) 10 | 11 | (defn divisors [n] 12 | (cons n (filter #(divisor? % n) (range 1 (inc (/ n 2)))))) 13 | 14 | 15 | (defn num-divisors [n]) 16 | 17 | (def triangle-numbers (map triangle-number (range 1 1000))) 18 | (println (first (filter #(> (num-divisors %) 500) triangle-numbers))) 19 | -------------------------------------------------------------------------------- /012/triangle-numbers.hs: -------------------------------------------------------------------------------- 1 | import Data.List (group) 2 | 3 | triangles :: [Int] 4 | triangles = scanl1 (+) [1..] 5 | 6 | primes :: [Int] 7 | primes = sieve [2..] where 8 | sieve [] = [] 9 | sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p > 0] 10 | 11 | factorize :: Int -> [Int] 12 | factorize n = primeFactors n primes where 13 | primeFactors 1 _ = [] 14 | primeFactors _ [] = [] 15 | primeFactors m (p:ps) | m < p * p = [m] 16 | | r == 0 = p : primeFactors q (p:ps) 17 | | otherwise = primeFactors m ps 18 | where (q, r) = quotRem m p 19 | 20 | primePowers :: Int -> [(Int, Int)] 21 | primePowers n = [(head x, length x) | x <- group $ factorize n] 22 | 23 | numDivisors :: Int -> Int 24 | numDivisors n = product [k + 1 | (_, k) <- primePowers n] 25 | 26 | main :: IO () 27 | main = print $ head $ dropWhile (\n -> numDivisors n <= 500) triangles 28 | -------------------------------------------------------------------------------- /012/triangle-numbers.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'mathn' 3 | 4 | class Integer 5 | def divisors 6 | return [1] if self == 1 7 | primes, powers = self.prime_division.transpose 8 | exponents = powers.map{|i| (0..i).to_a} 9 | divisors = exponents.shift.product(*exponents).map do |powers| 10 | primes.zip(powers).map{|prime, power| prime ** power}.inject(:*) 11 | end 12 | divisors.sort.map{|div| [div, self / div]} 13 | end 14 | end 15 | 16 | triangles = Enumerator.new do |yielder| 17 | i = 1 18 | loop do 19 | yielder.yield i * (i + 1) / 2 20 | i += 1 21 | end 22 | end 23 | 24 | puts triangles.detect { |t| t.divisors.count > 500 } 25 | -------------------------------------------------------------------------------- /012/triangle.rs: -------------------------------------------------------------------------------- 1 | fn num_divisors(n: u64) -> u64 { 2 | let mut result = 0; 3 | let max = (n as f64).sqrt() as u64; 4 | for i in 1..max + 1 { 5 | if n % i == 0 { 6 | if n / i == i { 7 | result += 1; 8 | } else { 9 | result += 2; 10 | } 11 | } 12 | } 13 | return result; 14 | } 15 | 16 | fn main() { 17 | let triangles = (1..).scan(0, |triangle, n| { 18 | *triangle += n; 19 | Some(*triangle) 20 | }); 21 | let first = triangles 22 | .skip_while(|&triangle| num_divisors(triangle) <= 500) 23 | .next() 24 | .unwrap(); 25 | println!("{}", first); 26 | } 27 | -------------------------------------------------------------------------------- /013/answer.txt: -------------------------------------------------------------------------------- 1 | 5537376230 2 | -------------------------------------------------------------------------------- /013/large-sum.hs: -------------------------------------------------------------------------------- 1 | main :: IO () 2 | main = do 3 | str <- readFile "/home/zach/code/euler/013/digits.txt" 4 | putStrLn $ take 10 $ show $ sum $ map read $ lines str 5 | -------------------------------------------------------------------------------- /013/sum.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let numbers = include_str!("digits.txt"); 3 | let sum: f64 = numbers 4 | .lines() 5 | .map(|line| line.parse::().unwrap()) 6 | .sum(); 7 | println!("{}", sum.to_string().chars().take(10).collect::()); 8 | } 9 | -------------------------------------------------------------------------------- /014/answer.txt: -------------------------------------------------------------------------------- 1 | 837799 2 | -------------------------------------------------------------------------------- /014/collatz.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut collatz: Vec = vec![0; 1000000]; 3 | collatz[1] = 1; 4 | let max = (2..collatz.len()) 5 | .max_by_key(|&i| { 6 | let mut j: usize = i; 7 | let mut len = 0; 8 | loop { 9 | if j < collatz.len() && collatz[j] != 0 { 10 | break; 11 | } 12 | len += 1; 13 | if j % 2 == 0 { 14 | j /= 2; 15 | } else { 16 | j = 3 * j + 1; 17 | } 18 | } 19 | len += collatz[j]; 20 | collatz[i] = len; 21 | len 22 | }) 23 | .unwrap(); 24 | println!("{}", max); 25 | } 26 | -------------------------------------------------------------------------------- /014/longest-chain.c.wip: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | long next_collatz(long n) { 4 | if (n % 2 == 0) { 5 | return n / 2; 6 | } else { 7 | return 3 * n + 1; 8 | } 9 | } 10 | 11 | long lencollatz(long start) { 12 | if (start < 1) { 13 | return 0; 14 | } else if (start == 1) { 15 | return 1; 16 | } 17 | long n = start; 18 | long length = 1; 19 | while (n != 1) { 20 | n = next_collatz(n); 21 | length++; 22 | } 23 | return length; 24 | } 25 | 26 | long main() { 27 | long max_l = 0; 28 | long max_i = 0; 29 | long i; 30 | for (i=1; i < 1000000; i++) { 31 | long l = lencollatz(i); 32 | if (l > max_l) { 33 | max_l = l; 34 | max_i = i; 35 | } 36 | } 37 | printf("%ld\n", max_i); 38 | return 0; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /014/longest-chain.clj.wip: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env clojure 2 | (defn collatz [start] 3 | (defn next-collatz [n] 4 | (if (even? n) 5 | (/ n 2) 6 | (+ (* 3 n) 1))) 7 | (def memo-collatz 8 | (memoize next-collatz)) 9 | (defn not-one? [n] 10 | (not (= n 1))) 11 | (concat (take-while not-one? (iterate next-collatz start)) [1])) 12 | 13 | (defn collatz-seqs [limit] 14 | (map collatz (range 1 limit))) 15 | 16 | (println (apply max-key count (collatz-seqs 100000))) 17 | -------------------------------------------------------------------------------- /014/longest-chain.hs: -------------------------------------------------------------------------------- 1 | import Data.Word 2 | import Data.Array 3 | 4 | memoCollatz :: Array Word Word 5 | memoCollatz = listArray (1, size) $ map collatz [1..size] 6 | where size = 1000000 7 | 8 | collatz :: Word -> Word 9 | collatz 1 = 1 10 | collatz n | inRange (bounds memoCollatz) next = 1 + memoCollatz ! next 11 | | otherwise = 1 + collatz next 12 | where next = case n of 13 | 1 -> 1 14 | n | even n -> n `div` 2 15 | | otherwise -> 3 * n + 1 16 | 17 | main = print $ snd $ maximum $ map (\n -> (collatz n, n)) [1..1000000] 18 | -------------------------------------------------------------------------------- /014/longest-chain.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | def next_collatz(n): 3 | if n % 2 == 0: 4 | return n / 2 5 | else: 6 | return 3*n + 1 7 | 8 | def collatz(start): 9 | if start < 1: 10 | raise ValueError("start must be greater than or equal to 1") 11 | elif start == 1: 12 | return [1] 13 | 14 | res = [start] 15 | done = False 16 | while not done: 17 | res += [next_collatz(res[-1])] 18 | if res[-1] == 1: done = True 19 | return res 20 | 21 | _collatz_cache = {} 22 | def lencollatz(start): 23 | if start < 1: 24 | raise ValueError("start must be greater than or equal to 1") 25 | elif start == 1: 26 | return 1 27 | 28 | n = start 29 | length = 1 30 | done = False 31 | while not done: 32 | n = next_collatz(n) 33 | try: 34 | length += _collatz_cache[n] 35 | done = True 36 | except: 37 | length += 1 38 | if n == 1: done = True 39 | _collatz_cache[start] = length 40 | return length 41 | 42 | max_len = 0 43 | max_i = None 44 | for i in range(1, 1000000): 45 | l = lencollatz(i) 46 | if l > max_len: 47 | max_len = l 48 | max_i = i 49 | print(max_i) 50 | -------------------------------------------------------------------------------- /014/longest-chain.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | max_l = 0 4 | max_i = 0 5 | 500001.step(1000000, 2).each do |i| 6 | l = 0 7 | j = i 8 | while j != 1 do 9 | if j.even? 10 | j /= 2 11 | else 12 | j = 3 * j + 1 13 | end 14 | l += 1 15 | end 16 | if l > max_l 17 | max_l = l 18 | max_i = i 19 | end 20 | end 21 | 22 | puts max_i 23 | -------------------------------------------------------------------------------- /014/question.markdown: -------------------------------------------------------------------------------- 1 | The following iterative sequence is defined for the set of positive integers: 2 | 3 | $$n \rightarrow 4 | \begin{cases} 5 | \tfrac{n}{2} & \text{if } n \text{ is even} \\ 6 | 3n+1 & \text{if } n \text{ is odd} 7 | \end{cases}$$ 8 | 9 | Using the rule above and starting with 13, we generate the following sequence: 10 | 11 | $$13, 40, 20, 10, 5, 16, 8, 4, 2, 1$$ 12 | 13 | It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 14 | terms. Although it has not been proved yet (Collatz Problem), it is thought that all 15 | starting numbers finish at 1. 16 | 17 | Which starting number, under one million, produces the longest chain? 18 | 19 | NOTE: Once the chain starts the terms are allowed to go above one million. 20 | -------------------------------------------------------------------------------- /015/answer.txt: -------------------------------------------------------------------------------- 1 | 137846528820 2 | -------------------------------------------------------------------------------- /015/binom.hs: -------------------------------------------------------------------------------- 1 | factorial :: Integer -> Integer 2 | factorial n = product [1..n] 3 | 4 | choose :: Integer -> Integer -> Integer 5 | choose n k = div (factorial n) $ factorial k * factorial (n - k) 6 | 7 | main :: IO () 8 | main = print $ choose 40 20 9 | -------------------------------------------------------------------------------- /015/binom.rs: -------------------------------------------------------------------------------- 1 | fn choose(n: u64, k: u64) -> u64 { 2 | (0..k).fold(1, |acc, i| acc * (n - i) / (i + 1)) 3 | } 4 | 5 | fn main() { 6 | println!("{}", choose(40, 20)); 7 | } 8 | -------------------------------------------------------------------------------- /015/commentary.markdown: -------------------------------------------------------------------------------- 1 | The grid can be expressed as [Pascal's Triangle](http://en.wikipedia.org/wiki/Pascal's_triangle): 2 | 3 | ``` 4 | 1 5 | 1 1 6 | 1 (2) 1 7 | 1 3 3 1 8 | 1 4 (6) 4 1 9 | 1 5 10 10 5 1 10 | 1 6 15 (20) 15 6 1 11 | ``` 12 | 13 | Note that the solution for a 1x1 grid is 2, a 2x2 grid is 6, and a 3x3 grid is 20. 14 | 15 | If we compare these solutions to Pascal's Triangle, we see that they correspond to 16 | the 1st element in the 2nd row, the 2nd element in the 4th row, and the 3rd element 17 | in the 6th row, respectively. (Note that Pascal's Triangle is zero-indexed.) 18 | 19 | The [binomial coefficient](http://en.wikipedia.org/wiki/Binomial_coefficient) 20 | $\binom {n} {k}$ can be used to determine the $k$th element in the 21 | $n$th row of Pascal's Triangle. Thus, we could express the aforementioned solutions as 22 | $\binom {2} {1}$, $\binom {4} {2}$, and $\binom {6} {3}$, respectively. 23 | 24 | Thus, a general solution for grids of size $x$ is 25 | 26 | $$routes = \binom {2x} {x}$$. 27 | -------------------------------------------------------------------------------- /015/grid-routes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from gmpy2 import comb 3 | print(comb(2 * 20,20)) 4 | -------------------------------------------------------------------------------- /015/pascal.clj.wip: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env clojure 2 | ; compute pascal's triangle 3 | (defn ** [x n] 4 | (. (. java.math.BigInteger (valueOf x)) (pow n))) 5 | 6 | (defn pascal [n k] 7 | (cond 8 | (= k n) 1 9 | (or (< n 0) (< k 0)) 0 10 | :else 11 | (+ 12 | (pascal (- n 1) (- k 1)) 13 | (pascal (- n 1) k)))) 14 | 15 | (defn pascal-row [n] 16 | (map #(pascal n %) (range (+ n 1)))) 17 | 18 | (defn pascal-triangle [num-rows] 19 | (map #(pascal-row %) (range num-rows))) 20 | 21 | (dorun (map println (pascal-triangle 10))) 22 | (println (pascal 5 3)) 23 | -------------------------------------------------------------------------------- /015/pascal.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | class Integer 4 | def choose(k) 5 | (self-k+1 .. self).inject(1, &:*) / (2 .. k).inject(1, &:*) 6 | end 7 | end 8 | 9 | puts 40.choose(20) 10 | -------------------------------------------------------------------------------- /015/question.html: -------------------------------------------------------------------------------- 1 |

2 | Starting in the top left corner of a 2x2 grid, there are 6 routes 3 | (without backtracking) to the bottom right corner. 4 |

5 | 6 |
7 | 8 |
9 | 10 |

11 | How many routes are there through a 20x20 grid? 12 |

13 | -------------------------------------------------------------------------------- /016/answer.txt: -------------------------------------------------------------------------------- 1 | 1366 2 | -------------------------------------------------------------------------------- /016/digits.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut decimal = vec![1]; 3 | for _ in 0..1000 { 4 | let mut carry = 0; 5 | for i in 0..decimal.len() { 6 | let mut digit = decimal[i]; 7 | digit = 2 * digit + carry; 8 | carry = digit / 10; 9 | decimal[i] = digit % 10; 10 | } 11 | if carry > 0 { 12 | decimal.push(carry); 13 | } 14 | } 15 | println!("{}", decimal.iter().sum::()); 16 | } 17 | -------------------------------------------------------------------------------- /016/question.html: -------------------------------------------------------------------------------- 1 |

2 | $2^{15} = 32768$ and the sum of its digits is $3 + 2 + 7 + 6 + 8 = 26$. 3 |

4 | 5 |

6 | What is the sum of the digits of the number $2^{1000}$? 7 |

8 | -------------------------------------------------------------------------------- /016/sum-exp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | print(sum(int(digit) for digit in str(2**1000))) 3 | -------------------------------------------------------------------------------- /016/sum-exp.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | puts (2**1000).to_s.each_char.inject(0) {|s,v| s+v.to_i} 3 | -------------------------------------------------------------------------------- /016/sumExp.hs: -------------------------------------------------------------------------------- 1 | sumDigits :: Integer -> Integer 2 | sumDigits n = sumDigits' n 0 3 | where sumDigits' 0 acc = acc 4 | sumDigits' n acc = sumDigits' (div n 10) (acc + (mod n 10)) 5 | 6 | main :: IO () 7 | main = print $ sumDigits $ 2^1000 8 | -------------------------------------------------------------------------------- /017/answer.txt: -------------------------------------------------------------------------------- 1 | 21124 2 | -------------------------------------------------------------------------------- /017/number-to-words.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'linguistics' # gem install linguistics 3 | Linguistics::use( :en ) 4 | puts (1..1000).map { |i| i.en.numwords.gsub(/[ -]/, '').length }.reduce(:+) 5 | -------------------------------------------------------------------------------- /017/question.html: -------------------------------------------------------------------------------- 1 |

2 | If the numbers 1 to 5 are written out in words: 3 | one, two, three, four, five, then there are 4 | $3 + 3 + 5 + 4 + 4 = 19$ letters used in total. 5 |

6 | 7 |

8 | If all the numbers from 1 to 1000 (one thousand) 9 | inclusive were written out in words, how many 10 | letters would be used? 11 |

12 | 13 |

14 | NOTE: Do not count spaces or hyphens. For example, 15 | 342 (three hundred and forty-two) contains 23 16 | letters and 115 (one hundred and fifteen) contains 17 | 20 letters. The use of "and" when writing out 18 | numbers is in compliance with British usage. 19 |

20 | -------------------------------------------------------------------------------- /018/answer.txt: -------------------------------------------------------------------------------- 1 | 1074 2 | -------------------------------------------------------------------------------- /018/max-route.hs: -------------------------------------------------------------------------------- 1 | parse :: String -> [[Integer]] 2 | parse = map (map read . words) . lines 3 | 4 | best :: [Integer] -> [Integer] 5 | best row = map maximum choices where 6 | choices = zipWith (\a b -> a : [b]) row (tail row) 7 | 8 | maxStep :: [Integer] -> [Integer] -> [Integer] 9 | maxStep current next = zipWith (+) next (best current) 10 | 11 | maxPath :: [[Integer]] -> Integer 12 | maxPath [[x]] = x 13 | maxPath (current:next:rest) = maxPath $ (maxStep current next) : rest 14 | 15 | main :: IO () 16 | main = do 17 | str <- readFile "/home/zach/code/euler/018/triangle.txt" 18 | print $ maxPath $ reverse $ parse str 19 | -------------------------------------------------------------------------------- /018/max-route.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | triangle_str = <> = triangle 6 | .lines() 7 | .map(|line| line.split(' ').map(|s| s.parse::().unwrap()).collect()) 8 | .collect(); 9 | for row in (0..(graph.len() - 1)).rev() { 10 | for i in 0..graph[row].len() { 11 | graph[row][i] += max(graph[row + 1][i], graph[row + 1][i + 1]); 12 | } 13 | } 14 | println!("{}", graph[0][0]); 15 | } 16 | -------------------------------------------------------------------------------- /018/question.html: -------------------------------------------------------------------------------- 1 |

2 | By starting at the top of the triangle below and moving to adjacent 3 | numbers on the row below, the maximum total from top to bottom is 23. 4 |

5 | 6 |
3
 7 | 7 4
 8 | 2 4 6
 9 | 8 5 9 3
10 | 
11 | 12 |

13 | That is, $3 + 7 + 4 + 9 = 23$. 14 |

15 | 16 |

17 | Find the maximum total from top to bottom of the triangle below: 18 |

19 | 20 |
75
21 | 95 64
22 | 17 47 82
23 | 18 35 87 10
24 | 20 04 82 47 65
25 | 19 01 23 75 03 34
26 | 88 02 77 73 07 63 67
27 | 99 65 04 28 06 16 70 92
28 | 41 41 26 56 83 40 80 70 33
29 | 41 48 72 33 47 32 37 16 94 29
30 | 53 71 44 65 25 43 91 52 97 51 14
31 | 70 11 33 28 77 73 17 78 39 68 17 57
32 | 91 71 52 38 17 14 91 43 58 50 27 29 48
33 | 63 66 04 68 89 53 67 30 73 16 69 87 40 31
34 | 04 62 98 27 23 09 70 98 73 93 38 53 60 04 23
35 | 
36 | 37 |

38 | NOTE: As there are only 16384 routes, it is possible to solve 39 | this problem by trying every route. However, Problem 67, is the same 40 | challenge with a triangle containing one-hundred rows; it cannot be 41 | solved by brute force, and requires a clever method! ;o) 42 |

43 | -------------------------------------------------------------------------------- /018/triangle.txt: -------------------------------------------------------------------------------- 1 | 75 2 | 95 64 3 | 17 47 82 4 | 18 35 87 10 5 | 20 04 82 47 65 6 | 19 01 23 75 03 34 7 | 88 02 77 73 07 63 67 8 | 99 65 04 28 06 16 70 92 9 | 41 41 26 56 83 40 80 70 33 10 | 41 48 72 33 47 32 37 16 94 29 11 | 53 71 44 65 25 43 91 52 97 51 14 12 | 70 11 33 28 77 73 17 78 39 68 17 57 13 | 91 71 52 38 17 14 91 43 58 50 27 29 48 14 | 63 66 04 68 89 53 67 30 73 16 69 87 40 31 15 | 04 62 98 27 23 09 70 98 73 93 38 53 60 04 23 16 | -------------------------------------------------------------------------------- /019/answer.txt: -------------------------------------------------------------------------------- 1 | 171 2 | -------------------------------------------------------------------------------- /019/calendar-module-first-sunday.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from calendar import monthrange; from itertools import product 3 | print(len([(year, month) for year, month in product(list(range(1901, 2001)), list(range(1, 13))) if monthrange(year, month)[0] == 6])) 4 | -------------------------------------------------------------------------------- /019/commentary.markdown: -------------------------------------------------------------------------------- 1 | The lesson of this exercise: know your modules! 2 | -------------------------------------------------------------------------------- /019/first-sunday.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'date' 3 | puts Date.new(1901,1,1).upto(Date.new(2000,12,31)).find_all { |d| d.mday == 1 && d.wday == 0 }.count 4 | -------------------------------------------------------------------------------- /019/question.markdown: -------------------------------------------------------------------------------- 1 | You are given the following information, 2 | but you may prefer to do some research for yourself. 3 | 4 | 1 Jan 1900 was a Monday. 5 | Thirty days has September, 6 | April, June and November. 7 | All the rest have thirty-one, 8 | Saving February alone, 9 | Which has twenty-eight, rain or shine. 10 | And on leap years, twenty-nine. 11 | A leap year occurs on any year evenly divisible by 4, 12 | but not on a century unless it is divisible by 400. 13 | 14 | How many Sundays fell on the first of the month during 15 | the twentieth century (1 Jan 1901 to 31 Dec 2000)? 16 | -------------------------------------------------------------------------------- /020/answer.txt: -------------------------------------------------------------------------------- 1 | 648 2 | -------------------------------------------------------------------------------- /020/factorial.clj: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env clojure 2 | (println (reduce + (map #(- (int %) 48) (str (reduce * (range BigInteger/ONE 100)))))) 3 | -------------------------------------------------------------------------------- /020/factorial.hs: -------------------------------------------------------------------------------- 1 | sumDigits :: Integer -> Integer 2 | sumDigits n = sumDigits' n 0 3 | where sumDigits' 0 acc = acc 4 | sumDigits' n acc = sumDigits' (div n 10) (acc + (mod n 10)) 5 | 6 | factorial :: Integer -> Integer 7 | factorial n = foldr (*) 1 [1..n] 8 | 9 | main = print $ sumDigits $ factorial 100 10 | -------------------------------------------------------------------------------- /020/factorial.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | puts 100.downto(1).inject(:*).to_s.each_char.inject(0) {|s,v|s+v.to_i} 3 | -------------------------------------------------------------------------------- /020/factorial_digits.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut decimal = [0; 200]; 3 | decimal[0] = 1; 4 | for n in 1..101 { 5 | let mut carry = 0; 6 | for i in 0..decimal.len() { 7 | let mut digit = decimal[i]; 8 | digit = n * digit + carry; 9 | carry = digit / 10; 10 | decimal[i] = digit % 10; 11 | } 12 | } 13 | println!("{}", decimal.iter().sum::()); 14 | } 15 | -------------------------------------------------------------------------------- /020/question.html: -------------------------------------------------------------------------------- 1 |

2 | $n!$ means $n \times (n - 1) \times ... \times 3 \times 2 \times 1$. 3 |

4 | 5 |

6 | Find the sum of the digits in the number $100!$. 7 |

8 | -------------------------------------------------------------------------------- /021/amicable.clj: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env clojure 2 | (defn divisors [n] 3 | (filter #(zero? (mod n %)) (range 1 (+ 1 (/ n 2))))) 4 | 5 | (defn d [n] 6 | (reduce + (divisors n))) 7 | 8 | (defn amicable? [a b] 9 | (and (not (= a b)) (= (d a) b) (= (d b) a))) 10 | 11 | (println (reduce + (filter #(amicable? % (d %)) (range 10000)))) 12 | -------------------------------------------------------------------------------- /021/amicable.hs: -------------------------------------------------------------------------------- 1 | divisors :: Integer -> [Integer] 2 | divisors n = [x | x <- [1..(div n 2)], n `mod` x == 0] 3 | 4 | d :: Integer -> Integer 5 | d = sum . divisors 6 | 7 | isAmicable :: Integer -> Bool 8 | isAmicable n = n /= x && d x == n where x = d n 9 | 10 | main :: IO () 11 | main = print $ sum $ filter isAmicable [1..10000] 12 | -------------------------------------------------------------------------------- /021/amicable.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'mathn' 3 | 4 | class Integer 5 | def divisors 6 | return [1] if self == 1 7 | primes, powers = self.prime_division.transpose 8 | exponents = powers.map{|i| (0..i).to_a} 9 | divisors = exponents.shift.product(*exponents).map do |powers| 10 | primes.zip(powers).map{|prime, power| prime ** power}.inject(:*) 11 | end 12 | divisors.sort.take divisors.length - 1 13 | end 14 | 15 | def amicable?(n=self.divisors.reduce(:+)) 16 | n != self && n.divisors.reduce(:+) == self 17 | end 18 | end 19 | 20 | puts (1..10000).find_all { |n| n.amicable? }.reduce(:+) 21 | -------------------------------------------------------------------------------- /021/amicable.rs: -------------------------------------------------------------------------------- 1 | fn sum_divisors(n: u64) -> u64 { 2 | let mut result = 0; 3 | let max = (n as f64).sqrt() as u64; 4 | for i in 2..max { 5 | if n % i == 0 { 6 | let x = n / i; 7 | if x == i { 8 | result += i; 9 | } else { 10 | result += i + x; 11 | } 12 | } 13 | } 14 | 1 + result 15 | } 16 | 17 | fn main() { 18 | let sum: u64 = (1..10000) 19 | .filter(|&n| { 20 | let x = sum_divisors(n); 21 | (n != x) && (sum_divisors(x) == n) 22 | }) 23 | .sum(); 24 | println!("{}", sum); 25 | } 26 | -------------------------------------------------------------------------------- /021/answer.txt: -------------------------------------------------------------------------------- 1 | 31626 2 | -------------------------------------------------------------------------------- /021/question.html: -------------------------------------------------------------------------------- 1 |

2 | Let $d(n)$ be defined as the sum of proper divisors of $n$ 3 | (numbers less than $n$ which divide evenly into $n$). 4 |

5 | 6 |

7 | If $d(a) = b$ and $d(b) = a$, where $a \neq b$, then $a$ and $b$ 8 | are an amicable pair and each of $a$ and $b$ are called amicable numbers. 9 |

10 | 11 |

12 | For example, the proper divisors of 220 are 1, 2, 4, 5, 10, 11, 13 | 20, 22, 44, 55 and 110; therefore $d(220) = 284$. The proper 14 | divisors of 284 are 1, 2, 4, 71 and 142; so $d(284) = 220$. 15 |

16 | 17 |

18 | Evaluate the sum of all the amicable numbers under 10000. 19 |

20 | -------------------------------------------------------------------------------- /022/answer.txt: -------------------------------------------------------------------------------- 1 | 871198282 2 | -------------------------------------------------------------------------------- /022/names.hs: -------------------------------------------------------------------------------- 1 | import Data.List (sort) 2 | 3 | parse :: String -> [String] 4 | parse = words . map replaceComma . filter notQuote where 5 | replaceComma ',' = ' ' 6 | replaceComma c = c 7 | notQuote = (/= '"') 8 | 9 | alphaIndex :: Char -> Int 10 | alphaIndex c = fromEnum c - 64 11 | 12 | alphaScore :: String -> Int 13 | alphaScore = sum . map alphaIndex 14 | 15 | totalScore :: [String] -> Int 16 | totalScore names = sum $ zipWith (*) (map alphaScore $ sort names) [1..] 17 | 18 | main :: IO () 19 | main = do 20 | str <- readFile "/home/zach/code/euler/022/names.txt" 21 | print $ totalScore $ parse str 22 | -------------------------------------------------------------------------------- /022/names.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | from string import ascii_uppercase 4 | 5 | def calculate_score(name, index): 6 | alpha_score = sum(ascii_uppercase.index(letter)+1 for letter in name) 7 | return index * alpha_score 8 | 9 | def main(): 10 | names_file = open(os.path.join(os.path.dirname(__file__), 'names.txt')) 11 | names_string = names_file.read() 12 | names = [name.strip('"') for name in names_string.split(',')] 13 | names.sort() 14 | print(sum(calculate_score(name, index+1) for index, name in enumerate(names))) 15 | names_file.close() 16 | 17 | if __name__ == "__main__": 18 | main() 19 | -------------------------------------------------------------------------------- /022/names.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | names = File.open(File.dirname(__FILE__) + '/names.txt').read.scan(/\w+/).sort 4 | puts names.map { |name| 5 | word_score = name.each_byte.map { |c| c - 64 }.reduce(:+) 6 | (names.index(name) + 1) * word_score 7 | }.reduce(:+) 8 | -------------------------------------------------------------------------------- /022/names.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut names: Vec<&str> = include_str!("names.txt").split(',').collect(); 3 | names.sort(); 4 | let sum: usize = names 5 | .iter() 6 | .enumerate() 7 | .map(|(i, name)| { 8 | let value: usize = name.chars() 9 | .skip(1) 10 | .take(name.len() - 2) 11 | .map(|c| 1 + (c as usize) - ('A' as usize)) 12 | .sum(); 13 | (i + 1) * value 14 | }) 15 | .sum(); 16 | println!("{}", sum); 17 | } 18 | -------------------------------------------------------------------------------- /022/question.markdown: -------------------------------------------------------------------------------- 1 | Using names.txt, 2 | a 46K text file containing over five-thousand first names, 3 | begin by sorting it into alphabetical order. Then working 4 | out the alphabetical value for each name, multiply this 5 | value by its alphabetical position in the list to obtain 6 | a name score. 7 | 8 | For example, when the list is sorted into alphabetical order, 9 | COLIN, which is worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th 10 | name in the list. So, COLIN would obtain a score of 11 | 938 * 53 = 49714. 12 | 13 | What is the total of all the name scores in the file? 14 | -------------------------------------------------------------------------------- /023/abundant.clj.wip: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env clojure 2 | (defn divisors [n] 3 | (filter #(= (rem n %) 0) (range 1 n))) 4 | 5 | (defn perfect? [n] 6 | (= (reduce + (divisors n)) n)) 7 | 8 | (defn abundant? [n] 9 | (> (reduce + (divisors n)) n)) 10 | 11 | (defn deficient? [n] 12 | (< (reduce + (divisors n)) n)) 13 | 14 | (println (filter abundant? (range 15000))) 15 | -------------------------------------------------------------------------------- /023/abundant.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'mathn' 3 | 4 | class Integer 5 | def divisors 6 | return [1] if self == 1 7 | primes, powers = self.prime_division.transpose 8 | exponents = powers.map{|i| (0..i).to_a} 9 | divisors = exponents.shift.product(*exponents).map do |powers| 10 | primes.zip(powers).map{|prime, power| prime ** power}.inject(:*) 11 | end 12 | divisors.take divisors.length - 1 13 | end 14 | 15 | def abundant? 16 | self.divisors.reduce(:+) > self 17 | end 18 | end 19 | 20 | abundants = (1..28213).select { |n| n.abundant? } 21 | i = 0 22 | sums = [] 23 | abundants.each do |x| 24 | abundants[i..abundants.length].each do |y| 25 | sum = x + y 26 | sums << sum unless sum > 28213 27 | end 28 | i += 1 29 | end 30 | sums.uniq! 31 | puts (1..28213).reject { |n| sums.include? n }.reduce(:+) 32 | -------------------------------------------------------------------------------- /023/abundant.rs: -------------------------------------------------------------------------------- 1 | fn sum_divisors(n: usize) -> usize { 2 | let mut result = 0; 3 | let max = 1 + (n as f64).sqrt() as usize; 4 | for i in 2..max { 5 | if n % i == 0 { 6 | let x = n / i; 7 | if x == i { 8 | result += i; 9 | } else { 10 | result += i + x; 11 | } 12 | } 13 | } 14 | 1 + result 15 | } 16 | 17 | fn main() { 18 | let max = 28123; 19 | let abundant: Vec = (2..max + 1).filter(|&n| sum_divisors(n) > n).collect(); 20 | let mut abundant_sums = vec![false; 2 * max + 1]; 21 | for i in 0..abundant.len() { 22 | for j in i..abundant.len() { 23 | abundant_sums[abundant[i] + abundant[j]] = true; 24 | } 25 | } 26 | let sum: usize = (1..max + 1).filter(|&i| !abundant_sums[i]).sum(); 27 | println!("{}", sum); 28 | } 29 | -------------------------------------------------------------------------------- /023/answer.txt: -------------------------------------------------------------------------------- 1 | 4179871 2 | -------------------------------------------------------------------------------- /023/question.markdown: -------------------------------------------------------------------------------- 1 | A perfect number is a number for which the sum of its proper divisors is 2 | exactly equal to the number. For example, the sum of the proper divisors 3 | of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect 4 | number. 5 | 6 | A number n is called deficient if the sum of its proper divisors is less 7 | than n and it is called abundant if this sum exceeds n. 8 | 9 | As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the 10 | smallest number that can be written as the sum of two abundant numbers 11 | is 24. By mathematical analysis, it can be shown that all integers 12 | greater than 28123 can be written as the sum of two abundant numbers. 13 | However, this upper limit cannot be reduced any further by analysis even 14 | though it is known that the greatest number that cannot be expressed as 15 | the sum of two abundant numbers is less than this limit. 16 | 17 | Find the sum of all the positive integers which cannot be written as the 18 | sum of two abundant numbers. 19 | -------------------------------------------------------------------------------- /024/answer.txt: -------------------------------------------------------------------------------- 1 | 2783915460 2 | -------------------------------------------------------------------------------- /024/permutations.hs: -------------------------------------------------------------------------------- 1 | import Data.List (sort, permutations) 2 | 3 | main :: IO () 4 | main = putStrLn $ (sort $ permutations ['0'..'9']) !! 999999 5 | -------------------------------------------------------------------------------- /024/permutations.js: -------------------------------------------------------------------------------- 1 | function permutate(n, array) { 2 | const al = array.length 3 | for (let i = 0; i < n - 1; i++) { 4 | let k, l 5 | for (let j = 0; j < al - 1; j++) { 6 | if (array[j] < array[j + 1]) { 7 | k = j 8 | } 9 | } 10 | for (let j = k; j < al; j++) { 11 | if (array[k] < array[j]) { 12 | l = j 13 | } 14 | } 15 | let tmp = array[k] 16 | array[k] = array[l] 17 | array[l] = tmp 18 | let begin = k + 1 19 | let end = al - 1 20 | while (begin < end) { 21 | tmp = array[begin] 22 | array[begin] = array[end] 23 | array[end] = tmp 24 | begin += 1 25 | end -= 1 26 | } 27 | } 28 | return array 29 | } 30 | console.log(permutate(1000000, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).join("")) 31 | -------------------------------------------------------------------------------- /024/permutations.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from itertools import islice, permutations 3 | print(''.join(next(islice(permutations(list(map(str, list(range(10))))), 999999, None)))) 4 | -------------------------------------------------------------------------------- /024/permutations.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | puts (0..9).to_a.permutation(10).to_a[999999].join 3 | -------------------------------------------------------------------------------- /024/permutations.rs: -------------------------------------------------------------------------------- 1 | fn permutate(sequence: &mut [T]) -> bool 2 | where 3 | T: Ord, 4 | { 5 | if sequence.len() < 2 { 6 | return false; 7 | } 8 | 9 | let mut i = sequence.len() - 1; 10 | while i > 0 && sequence[i - 1] >= sequence[i] { 11 | i -= 1; 12 | } 13 | 14 | if i == 0 { 15 | return false; 16 | } 17 | 18 | let mut j = sequence.len() - 1; 19 | while j >= i && sequence[j] <= sequence[i - 1] { 20 | j -= 1; 21 | } 22 | 23 | sequence.swap(j, i - 1); 24 | sequence[i..].reverse(); 25 | 26 | true 27 | } 28 | 29 | fn main() { 30 | let mut digits: Vec = "0123456789".chars().collect(); 31 | for _ in 1..1000000 { 32 | permutate(&mut digits); 33 | } 34 | println!("{}", digits.iter().collect::()); 35 | } 36 | -------------------------------------------------------------------------------- /024/question.html: -------------------------------------------------------------------------------- 1 |

2 | A permutation is an ordered arrangement of objects. 3 | For example, 3124 is one possible permutation of the 4 | digits 1, 2, 3 and 4. If all of the permutations are 5 | listed numerically or alphabetically, we call it 6 | lexicographic order. The lexicographic permutations 7 | of 0, 1 and 2 are: 8 |

9 | 10 | $$012, 021, 102, 120, 201, 210$$ 11 | 12 |

13 | What is the millionth lexicographic permutation of the 14 | digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9? 15 |

16 | -------------------------------------------------------------------------------- /025/answer.txt: -------------------------------------------------------------------------------- 1 | 4782 2 | -------------------------------------------------------------------------------- /025/fibonacci.clj: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env clojure 2 | (def fibs 3 | (lazy-cat [(BigInteger/ZERO) (BigInteger/ONE)] (map + fibs (rest fibs)))) 4 | 5 | (println (count (take-while #(< % (.pow (BigInteger/TEN) 999)) fibs))) 6 | -------------------------------------------------------------------------------- /025/fibonacci.hs: -------------------------------------------------------------------------------- 1 | fibs :: [Integer] 2 | fibs = 0 : 1 : zipWith (+) fibs (tail fibs) 3 | 4 | main :: IO () 5 | main = print $ head [i | i <- [1..], (==1000) . length . show $ fibs !! i] 6 | -------------------------------------------------------------------------------- /025/fibonacci.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | i = 1 3 | t1, t2 = 0, 1 4 | while t2.to_s.length < 1000 5 | t1, t2 = t2, t1 + t2 6 | i += 1 7 | end 8 | puts i 9 | -------------------------------------------------------------------------------- /025/fibonacci.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut a = vec![0]; 3 | let mut b = vec![1]; 4 | let mut n = 1; 5 | while b.len() < 1000 { 6 | let tmp = b.clone(); 7 | let mut carry = 0; 8 | for i in 0..b.len() { 9 | if i >= a.len() { 10 | a.push(0); 11 | } 12 | let mut digit = a[i]; 13 | digit = b[i] + digit + carry; 14 | carry = digit / 10; 15 | a[i] = digit % 10; 16 | } 17 | if carry > 0 { 18 | a.push(carry); 19 | } 20 | b = a; 21 | a = tmp; 22 | n += 1; 23 | } 24 | println!("{}", n); 25 | } 26 | -------------------------------------------------------------------------------- /025/question.markdown: -------------------------------------------------------------------------------- 1 | The Fibonacci sequence is defined by the recurrence relation: 2 | 3 | $$F_n = F_{n-1} + F_{n-2} \text{ where } F_1 = 1 \text{ and } F_2 = 1$$ 4 | 5 | Hence the first 12 terms will be: 6 | 7 | $$ 8 | \begin{aligned} 9 | F_1 &= 1 \\ 10 | F_2 &= 1 \\ 11 | F_3 &= 2 \\ 12 | F_4 &= 3 \\ 13 | F_5 &= 5 \\ 14 | F_6 &= 8 \\ 15 | F_7 &= 13 \\ 16 | F_8 &= 21 \\ 17 | F_9 &= 34 \\ 18 | F_{10} &= 55 \\ 19 | F_{11} &= 89 \\ 20 | F_{12} &= 144 21 | \end{aligned} 22 | $$ 23 | 24 | The 12th term, $F_{12}$, is the first term to contain three digits. 25 | 26 | What is the first term in the Fibonacci sequence to contain 1000 digits? 27 | -------------------------------------------------------------------------------- /026/answer.txt: -------------------------------------------------------------------------------- 1 | 983 2 | -------------------------------------------------------------------------------- /026/cycle.rs: -------------------------------------------------------------------------------- 1 | fn cycle_length(n: usize) -> usize { 2 | let mut remainder = 10; 3 | let mut seen = vec![0; 10 * n + 1]; 4 | for i in 0.. { 5 | if remainder == 0 { 6 | return 0; 7 | } else if seen[remainder] != 0 { 8 | return i - seen[remainder]; 9 | } 10 | seen[remainder] = i; 11 | remainder = 10 * (remainder % n); 12 | } 13 | 0 14 | } 15 | 16 | fn main() { 17 | let max: usize = (1..1000).max_by_key(|&n| cycle_length(n)).unwrap(); 18 | println!("{}", max); 19 | } 20 | -------------------------------------------------------------------------------- /026/decimal-cycle.hs: -------------------------------------------------------------------------------- 1 | import Data.List (maximumBy) 2 | import Data.Function (on) 3 | 4 | cycleLength :: Integer -> Integer 5 | cycleLength n | even n = 0 6 | | n `rem` 5 == 0 = 0 7 | | otherwise = head [p | p <- [1..], (10^p - 1) `rem` n == 0] 8 | 9 | main :: IO () 10 | main = print $ maximumBy (compare `on` cycleLength) [1,3..1000] 11 | -------------------------------------------------------------------------------- /026/decimal-cycle.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | puts (0..1000).map { |d| 3 | (1..d).detect(lambda{0}) { |t| (10**t % d) == 1 } 4 | }.each_with_index.max[1] 5 | -------------------------------------------------------------------------------- /026/question.markdown: -------------------------------------------------------------------------------- 1 | A unit fraction contains 1 in the numerator. The decimal 2 | representation of the unit fractions with denominators 3 | 2 to 10 are given: 4 | 5 | $$\begin{aligned} 6 | \frac{1}{2}&=0.5 \\\\ 7 | \frac{1}{3}&=0.\overline{3} \\\\ 8 | \frac{1}{4}&=0.25 \\\\ 9 | \frac{1}{5}&=0.2 \\\\ 10 | \frac{1}{6}&=0.1\overline{6} \\\\ 11 | \frac{1}{7}&=0.\overline{142857} \\\\ 12 | \frac{1}{8}&=0.125 \\\\ 13 | \frac{1}{9}&=0.\overline{1} \\\\ 14 | \frac{1}{10}&=0.1 15 | \end{aligned}$$ 16 | 17 | Where $0.1\overline{6}$ means $0.1666...$, and has a 1-digit recurring 18 | cycle. It can be seen that $\frac{1}{7}$ has a 6-digit recurring cycle. 19 | 20 | Find the value of $d < 1000$ for which $\frac{1}{d}$ contains the longest 21 | recurring cycle in its decimal fraction part. 22 | -------------------------------------------------------------------------------- /026/recurring-decimal.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | def recurring_cycle(n, d): 3 | # solve 10^s % d == 10^(s+t) % d 4 | # where t is length and s is start 5 | for t in range(1, d): 6 | if 1 == 10**t % d: 7 | return t 8 | return 0 9 | 10 | longest = max(recurring_cycle(1, i) for i in range(2,1001)) 11 | print([i for i in range(2,1001) if recurring_cycle(1, i) == longest][0]) 12 | -------------------------------------------------------------------------------- /027/answer.txt: -------------------------------------------------------------------------------- 1 | -59231 2 | -------------------------------------------------------------------------------- /027/quadratic-primes.hs: -------------------------------------------------------------------------------- 1 | import Data.Function (on) 2 | import Data.List (maximumBy) 3 | 4 | isPrime :: Int -> Bool 5 | isPrime n | n < 1 = False 6 | | otherwise = not $ or [n `rem` x == 0 | x <- [2..floor $ sqrt $ fromIntegral n]] 7 | 8 | coefficients :: [(Int, Int)] 9 | coefficients = [(a, b) | a <- [-999..999], b <- filter isPrime [0..999]] 10 | 11 | primesProduced :: (Int, Int) -> Int 12 | primesProduced (a, b) = length $ takeWhile isPrime [n^2 + a*n + b | n <- [0..]] 13 | 14 | main :: IO () 15 | main = print $ uncurry (*) $ maximumBy (compare `on` primesProduced) coefficients 16 | -------------------------------------------------------------------------------- /027/quadratic-primes.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'mathn' 3 | puts (-999..999).to_a.product((-999..999).to_a).map { |a, b| 4 | [(0..100).take_while { |n| (n**2 + a*n + b).prime? }.count, a * b] 5 | }.max[1] 6 | -------------------------------------------------------------------------------- /027/quadratic.rs: -------------------------------------------------------------------------------- 1 | fn is_prime(n: i64) -> bool { 2 | if n < 1 { 3 | return false; 4 | } 5 | let max = (n as f64).sqrt() as i64; 6 | for d in 2..max { 7 | if n % d == 0 { 8 | return false; 9 | } 10 | } 11 | true 12 | } 13 | 14 | fn main() { 15 | let mut best = (0, 0); 16 | let mut best_count = 0; 17 | let bs = (0..1000).filter(|&b| is_prime(b)).collect::>(); 18 | for a in -999..1000 { 19 | for &b in &bs { 20 | let count = (0..) 21 | .take_while(|n| is_prime(n * n + a * n + b)) 22 | .map(|_| 1) 23 | .sum::(); 24 | if count > best_count { 25 | best = (a, b); 26 | best_count = count; 27 | } 28 | } 29 | } 30 | println!("{}", best.0 * best.1); 31 | } 32 | -------------------------------------------------------------------------------- /027/question.markdown: -------------------------------------------------------------------------------- 1 | Euler published the remarkable quadratic formula: 2 | 3 | $$n^2 + n + 41$$ 4 | 5 | It turns out that the formula will produce 40 primes 6 | for the consecutive values n = 0 to 39. However, when 7 | n = 40, $40^2 + 40 + 41 = 40(40 + 1) + 41$ is divisible 8 | by 41, and certainly when n = 41, $41^2 + 41 + 41$ is 9 | clearly divisible by 41. 10 | 11 | Using computers, the incredible formula $n^2 - 79n + 1601$ 12 | was discovered, which produces 80 primes for the 13 | consecutive values n = 0 to 79. The product of the 14 | coefficients, 79 and 1601, is 126479. 15 | 16 | Considering quadratics of the form: 17 | 18 | $$n^2 + an + b, \text{ where } |a| \lt 1000 \text{ and } |b| \lt 1000$$ 19 | 20 | Find the product of the coefficients, a and b, for 21 | the quadratic expression that produces the maximum 22 | number of primes for consecutive values of n, 23 | starting with n = 0. 24 | -------------------------------------------------------------------------------- /028/answer.txt: -------------------------------------------------------------------------------- 1 | 669171001 2 | -------------------------------------------------------------------------------- /028/question.markdown: -------------------------------------------------------------------------------- 1 | Starting with the number 1 and moving to the 2 | right in a clockwise direction a 5 by 5 spiral 3 | is formed as follows: 4 | 5 | 21 22 23 24 25 6 | 20 7 8 9 10 7 | 19 6 1 2 11 8 | 18 5 4 3 12 9 | 17 16 15 14 13 10 | 11 | It can be verified that the sum of the numbers 12 | on the diagonals is 101. 13 | 14 | What is the sum of the numbers on the diagonals 15 | in a 1001 by 1001 spiral formed in the same way? 16 | -------------------------------------------------------------------------------- /028/spiral.hs: -------------------------------------------------------------------------------- 1 | main :: IO () 2 | main = print $ foldr (+) 1 [4*n^2 - 6*n + 6 | n <- [3,5..1001]] 3 | -------------------------------------------------------------------------------- /028/spiral.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | def sum_diagonals_of_spiral(size): 3 | n = 1 4 | step = 2 5 | total = 0 6 | since_last = 0 7 | while n <= size**2: 8 | total += n 9 | n += step 10 | since_last += 1 11 | if since_last == 4: 12 | step += 2 13 | since_last = 0 14 | return total 15 | 16 | print(sum_diagonals_of_spiral(1001)) 17 | -------------------------------------------------------------------------------- /028/spiral.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | i = 1 3 | sum = i 4 | step = 2 5 | until i >= 1001**2 6 | 4.times { sum += i += step } 7 | step += 2 8 | end 9 | puts sum 10 | -------------------------------------------------------------------------------- /028/spiral.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let sum = (1..501) 3 | .map(|i| { 4 | let n = 2 * i + 1; 5 | 4 * n * n - 6 * n + 6 6 | }) 7 | .sum::() + 1; 8 | println!("{}", sum); 9 | } 10 | -------------------------------------------------------------------------------- /029/answer.txt: -------------------------------------------------------------------------------- 1 | 9183 2 | -------------------------------------------------------------------------------- /029/exponent-combinations.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import itertools 3 | print(len(set(a**b for a,b in itertools.product(list(range(2,101)), repeat=2)))) 4 | -------------------------------------------------------------------------------- /029/exponent-combinations.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | puts (2..100).to_a.product((2..100).to_a).map { |a,n| a**n }.uniq.count 3 | -------------------------------------------------------------------------------- /029/exponentComb.hs: -------------------------------------------------------------------------------- 1 | import Data.List (nub) 2 | 3 | main :: IO () 4 | main = print $ length $ nub [a^n | a <- [2..100], n <- [2..100]] 5 | -------------------------------------------------------------------------------- /029/exponents.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashSet; 2 | 3 | fn main() { 4 | let mut seen = HashSet::new(); 5 | for a in 2..101 { 6 | for b in 2..101 { 7 | let term = (a as f64).powf(b as f64); 8 | let bits: u64 = unsafe { std::mem::transmute(term) }; 9 | seen.insert(bits); 10 | } 11 | } 12 | println!("{}", seen.len()); 13 | } 14 | -------------------------------------------------------------------------------- /029/question.markdown: -------------------------------------------------------------------------------- 1 | Consider all integer combinations of $a^b$ for $2 \leq a \leq 5$ and $2 \leq b \leq 5$: 2 | 3 | $$\begin{aligned} 4 | & 2^2 = 4\text{, } 2^3 = 8\text{, } 2^4 = 16\text{, } 2^5 = 32 \\ 5 | & 3^2 = 9\text{, } 3^3 = 27\text{, } 3^4 = 81\text{, } 3^5 = 243 \\ 6 | & 4^2 = 16\text{, } 4^3 = 64\text{, } 4^4 = 256\text{, } 4^5 = 1024 \\ 7 | & 5^2 = 25\text{, } 5^3 = 125\text{, } 5^4 = 625\text{, } 5^5 = 3125 8 | \end{aligned}$$ 9 | 10 | If they are then placed in numerical order, with any repeats removed, we 11 | get the following sequence of 15 distinct terms: 12 | 13 | $$4\text{, } 8\text{, } 9\text{, } 16\text{, } 25\text{, } 27\text{, } 32\text{, } 64\text{, } 81\text{, } 125\text{, } 243\text{, } 256\text{, } 625\text{, } 1024\text{, } 3125$$ 14 | 15 | How many distinct terms are in the sequence generated by $a^b$ for 16 | $2 \leq a \leq 100$ and $2 \leq b \leq 100$? 17 | -------------------------------------------------------------------------------- /030/answer.txt: -------------------------------------------------------------------------------- 1 | 443839 2 | -------------------------------------------------------------------------------- /030/fifth-powers.clj: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env clojure 2 | (defn raise [x n] 3 | (. (. java.math.BigInteger (valueOf x)) (pow n))) 4 | 5 | (defn digits [number] 6 | (map #(- (int %) 48) (str number))) 7 | 8 | (defn can-be-written-as-sum-of-fifths? [number] 9 | (and (not (= number 1)) (= (apply + (map #(raise % 5) (digits number))) number))) 10 | 11 | (println (reduce + (filter can-be-written-as-sum-of-fifths? (range 500000)))) 12 | -------------------------------------------------------------------------------- /030/question.markdown: -------------------------------------------------------------------------------- 1 | Surprisingly there are only three numbers that can be 2 | written as the sum of fourth powers of their digits: 3 | 4 | $$\begin{aligned} 5 | 1634&=1^4 + 6^4 + 3^4 + 4^4 \\ 6 | 8208&=8^4 + 2^4 + 0^4 + 8^4 \\ 7 | 9474&=9^4 + 4^4 + 7^4 + 4^4 8 | \end{aligned}$$ 9 | 10 | As $1=1^4$ is not a sum it is not included. 11 | 12 | The sum of these numbers is $1634+8208+9474=19316$. 13 | 14 | Find the sum of all the numbers that can be written as 15 | the sum of fifth powers of their digits. 16 | -------------------------------------------------------------------------------- /030/sum-of-fifths.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | puts (2..500000).select { |i| 3 | i == i.to_s.each_char.map { |d| d.to_i**5 }.reduce(:+) 4 | }.reduce(:+) 5 | -------------------------------------------------------------------------------- /030/sumFifths.hs: -------------------------------------------------------------------------------- 1 | digits :: Integer -> [Integer] 2 | digits n = digits' n [] 3 | where digits' 0 acc = acc 4 | digits' n acc = digits' (div n 10) (mod n 10 : acc) 5 | 6 | main = print $ sum [n | n <- [2..500000], sum (map (^5) (digits n)) == n] 7 | -------------------------------------------------------------------------------- /031/answer.txt: -------------------------------------------------------------------------------- 1 | 73682 2 | -------------------------------------------------------------------------------- /031/currency.hs: -------------------------------------------------------------------------------- 1 | main = print $ length [1 | a <- [200,0], 2 | b <- [a,a-100..0], 3 | c <- [b,b-50..0], 4 | d <- [c,c-20..0], 5 | e <- [d,d-10..0], 6 | f <- [e,e-5..0], 7 | g <- [f,f-2..0]] 8 | -------------------------------------------------------------------------------- /031/currency.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | def ways_to_change(target, coins): 3 | if target == 0 or len(coins) == 1: 4 | return 1 5 | else: 6 | coins = sorted(coins) 7 | largest = coins[-1] 8 | uses = target // largest 9 | total = 0 10 | for i in range(uses + 1): 11 | total += ways_to_change(target - largest * i, coins[:-1]) 12 | return total 13 | 14 | def main(): 15 | print(ways_to_change(200, [1, 2, 5, 10, 20, 50, 100, 200])) 16 | 17 | if __name__ == "__main__": 18 | main() 19 | -------------------------------------------------------------------------------- /031/currency.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | count = 0 3 | 200.step(0, -200) do |a| 4 | a.step(0, -100) do |b| 5 | b.step(0, -50) do |c| 6 | c.step(0, -20) do |d| 7 | d.step(0, -10) do |e| 8 | e.step(0, -5) do |f| 9 | f.step(0, -2) do 10 | count += 1 11 | end 12 | end 13 | end 14 | end 15 | end 16 | end 17 | end 18 | puts count 19 | -------------------------------------------------------------------------------- /031/question.md: -------------------------------------------------------------------------------- 1 | In England the currency is made up of pounds, £, and pence, p, and there are eight coins in general circulation: 2 | 3 | 1p, 2p, 5p, 10p, 20p, 50p, £1 (100p) and £2 (200p) 4 | 5 | It is possible to make £2 in the following way: 6 | 7 | 1 × £1 + 1 × 50p + 2 × 20p + 1 × 5p + 1 × 2p + 3 × 1p 8 | 9 | How many different ways can £2 be made using any number of coins? 10 | -------------------------------------------------------------------------------- /032/answer.txt: -------------------------------------------------------------------------------- 1 | 45228 2 | -------------------------------------------------------------------------------- /032/pandigital-products.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | def is_pandigital(*args, **kwargs): 3 | num = sorted(''.join(str(arg) for arg in args)) 4 | 5 | try: 6 | if kwargs['length'] and len(num) != kwargs['length']: 7 | return False 8 | except KeyError: 9 | pass 10 | 11 | for i in range(len(num)): 12 | if str(i+1) != str(num[i]): 13 | return False 14 | return True 15 | 16 | def main(): 17 | pandigitals = set() 18 | total = 0 19 | for multiplicand in range(1, 5000): 20 | for multiplier in range(1, 100): 21 | product = multiplicand * multiplier 22 | if is_pandigital(multiplicand, multiplier, product, length=9): 23 | pandigitals.add(product) 24 | print(sum(pandigitals)) 25 | 26 | if __name__ == "__main__": 27 | main() 28 | -------------------------------------------------------------------------------- /032/pandigital.hs: -------------------------------------------------------------------------------- 1 | import Data.List (nub, sort) 2 | 3 | candidates :: [(String, Integer)] 4 | candidates = [(concatMap show [a, b, a*b], a*b) | a <- [1..2000], b <- [1..50]] 5 | 6 | pandigital :: String -> Bool 7 | pandigital = (== "123456789") . sort 8 | 9 | main :: IO () 10 | main = print $ sum $ nub [p | (digits, p) <- candidates, pandigital digits] 11 | -------------------------------------------------------------------------------- /032/pandigital.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | puts (1..4999).flat_map { |a| 3 | (1..99).map do |b| 4 | [a.to_s + b.to_s + (a*b).to_s, a*b] 5 | end 6 | }.select { |p| 7 | p[0].length == 9 && p[0].each_char.sort.join == "123456789" 8 | }.map { |p| p[1] }.uniq.reduce(:+) 9 | -------------------------------------------------------------------------------- /032/question.markdown: -------------------------------------------------------------------------------- 1 | We shall say that an n-digit number is pandigital if 2 | it makes use of all the digits 1 to n exactly once; 3 | for example, the 5-digit number, 15234, is 1 through 4 | 5 pandigital. 5 | 6 | The product 7254 is unusual, as the identity, 7 | $39 \times 186 = 7254$, containing multiplicand, multiplier, 8 | and product is 1 through 9 pandigital. 9 | 10 | Find the sum of all products whose 11 | multiplicand/multiplier/product identity can be written 12 | as a 1 through 9 pandigital. 13 | 14 | HINT: Some products can be obtained in more than one 15 | way so be sure to only include it once in your sum. 16 | -------------------------------------------------------------------------------- /033/answer.txt: -------------------------------------------------------------------------------- 1 | 100 2 | -------------------------------------------------------------------------------- /033/curious-fractions.hs: -------------------------------------------------------------------------------- 1 | import Data.Ratio (denominator) 2 | 3 | fraction :: Int -> Int -> Rational 4 | fraction n d = fromIntegral n / fromIntegral d 5 | 6 | curious :: Int -> Int -> Bool 7 | curious n d | f > 1 = False 8 | | d1 == 0 || d2 == 0 = False 9 | | n == d = False 10 | | n2 /= d1 = False 11 | | otherwise = fraction n1 d2 == f 12 | where f = fraction n d 13 | (n1, n2) = quotRem n 10 14 | (d1, d2) = quotRem d 10 15 | 16 | main :: IO () 17 | main = print $ denominator $ product [fraction n d | n <- [10..99], d <- [10..99], curious n d] 18 | -------------------------------------------------------------------------------- /033/curious-fractions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from fractions import * 3 | from itertools import * 4 | from functools import reduce 5 | 6 | def is_curious(n, d): 7 | f = Fraction(n, d) 8 | if f >= 1: 9 | return False 10 | n_digits = [int(digit) for digit in str(n)] 11 | d_digits = [int(digit) for digit in str(d)] 12 | 13 | if n_digits[1] == d_digits[0]: 14 | try: 15 | if Fraction(n_digits[0], d_digits[1]) == f: 16 | return True 17 | except: 18 | pass 19 | return False 20 | def main(): 21 | fractions = product(list(range(10, 100)), list(range(10, 100))) 22 | print(reduce(lambda a, b: a * b, (Fraction(*f) for f in fractions if is_curious(*f))).denominator) 23 | 24 | if __name__ == "__main__": 25 | main() 26 | -------------------------------------------------------------------------------- /033/curious-fractions.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | puts ('10'..'99').to_a.product(('10'..'99').to_a).select { |num, den| 3 | (num[0].to_f / den[1].to_f) == (num.to_f / den.to_f) && num[1] == den[0] && num[1] != den[1] 4 | }.uniq.map { |num, den| [num.to_i, den.to_i] }.reduce([1, 1]) { |p, v| 5 | f = [p[0] * v[0], p[1] * v[1]] 6 | [f[0] / f[0].gcd(f[1]), f[1] / f[0].gcd(f[1])] 7 | }[1] 8 | -------------------------------------------------------------------------------- /033/question.markdown: -------------------------------------------------------------------------------- 1 | The fraction $\frac{49}{98}$ is a curious fraction, as an inexperienced 2 | mathematician in attempting to simplify it may incorrectly 3 | believe that $\frac{49}{98} = \frac{4}{8}$, which is correct, is obtained by 4 | cancelling the 9s. 5 | 6 | We shall consider fractions like, $\frac{30}{50} = \frac{3}{5}$, to be trivial 7 | examples. 8 | 9 | There are exactly four non-trivial examples of this type of 10 | fraction, less than one in value, and containing two digits 11 | in the numerator and denominator. 12 | 13 | If the product of these four fractions is given in its lowest 14 | common terms, find the value of the denominator. 15 | -------------------------------------------------------------------------------- /034/answer.txt: -------------------------------------------------------------------------------- 1 | 40730 2 | -------------------------------------------------------------------------------- /034/curious.clj: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env clojure 2 | (defn factorial [n] 3 | (if (or (= n 1) (= n 0)) 4 | 1 5 | (* n (factorial (- n 1))))) 6 | 7 | (defn digits [number] 8 | (map #(- (int %) 48) (str number))) 9 | 10 | (defn curious? [number] 11 | (and (= (apply + (map factorial (digits number))) number) 12 | (> (count (digits number)) 1))) 13 | 14 | (println (reduce + (filter curious? (range 50000)))) 15 | -------------------------------------------------------------------------------- /034/curious.hs: -------------------------------------------------------------------------------- 1 | factorial :: Int -> Int 2 | factorial n = product [1..n] 3 | 4 | digits :: Int -> [Int] 5 | digits 0 = [] 6 | digits n = r : digits q 7 | where (q, r) = quotRem n 10 8 | 9 | curious :: Int -> Bool 10 | curious n = n == sum (map factorial (digits n)) 11 | 12 | main :: IO () 13 | main = print $ sum $ filter curious [10..50000] 14 | -------------------------------------------------------------------------------- /034/curious.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | puts (0..50000).select { |i| 3 | i.to_s.length > 1 && i == i.to_s.each_char.map { |d| (1..d.to_i).reduce(1, :*) }.reduce(:+) 4 | }.reduce(:+) 5 | -------------------------------------------------------------------------------- /034/curious.scm: -------------------------------------------------------------------------------- 1 | (define (factorial n) 2 | (apply * (iota n 1))) 3 | 4 | (define (digits n) 5 | (if (zero? n) 6 | '() 7 | (cons (remainder n 10) (digits (quotient n 10))))) 8 | 9 | (define (curious? n) 10 | (and (= (apply + (map factorial (digits n))) n) 11 | (> (length (digits n)) 1))) 12 | 13 | (display (apply + (filter curious? (iota 50000)))) 14 | (newline) 15 | -------------------------------------------------------------------------------- /034/question.markdown: -------------------------------------------------------------------------------- 1 | 145 is a curious number, as $1! + 4! + 5! = 1 + 24 + 120 = 145$. 2 | 3 | Find the sum of all numbers which are equal to the sum of the factorial of their digits. 4 | 5 | Note: as $1! = 1$ and $2! = 2$ are not sums they are not included. 6 | -------------------------------------------------------------------------------- /035/answer.txt: -------------------------------------------------------------------------------- 1 | 55 2 | -------------------------------------------------------------------------------- /035/circular-primes.clj.wip: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env clojure 2 | 3 | (defn digits [number] 4 | (map #(- (int %) 48) (str number))) 5 | 6 | (defn prime-factors-of [num] 7 | "Returns a sorted list of prime factors of num, including multiplicity." 8 | (let [q (Math/sqrt num) 9 | factor? (fn [nom den] (zero? (rem nom den)))] 10 | (loop [n num 11 | d 2 12 | r []] 13 | (cond 14 | (> d q) (concat r [n]) 15 | (= n d) (concat r [n]) 16 | (factor? n d) (recur (/ n d) d (conj r d)) 17 | true (recur n (inc d) r))))) 18 | 19 | (defn num-divisors-fast [num] 20 | (let [freqs (reduce #(assoc %1 %2 (inc (get %1 %2 0))) 21 | {} (prime-factors-of num))] 22 | (reduce #(* %1 (inc %2)) 1 (vals freqs)))) 23 | 24 | (defn prime? [n] 25 | (and 26 | (not (or (= n 1) (= n 0))) 27 | (= (num-divisors-fast n) 2))) 28 | 29 | (defn circular-prime? [n] 30 | (every? prime? (map #(Integer/parseInt (join %)) (rotations (digits n))))) 31 | 32 | (println (count (filter circular-prime? (range 1000000)))) 33 | -------------------------------------------------------------------------------- /035/circular-primes.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'mathn' 3 | puts (1..1000000).select { |i| 4 | (1..i.to_s.length).all? { |j| 5 | i.to_s.split('').rotate(j).join('').to_i.prime? 6 | } 7 | }.count 8 | -------------------------------------------------------------------------------- /035/question.markdown: -------------------------------------------------------------------------------- 1 | The number, 197, is called a circular prime because all rotations of the digits: 197, 971, and 719, are themselves prime. 2 | 3 | There are thirteen such primes below 100: 2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, and 97. 4 | 5 | How many circular primes are there below one million? 6 | -------------------------------------------------------------------------------- /036/answer.txt: -------------------------------------------------------------------------------- 1 | 872187 2 | -------------------------------------------------------------------------------- /036/binary-palindrome.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | class String 3 | def palindrome? 4 | self == self.reverse 5 | end 6 | end 7 | 8 | puts (1..1000000).select { |i| i.to_s.palindrome? && i.to_s(2).palindrome? }.reduce(:+) 9 | -------------------------------------------------------------------------------- /036/double-palindrome.hs: -------------------------------------------------------------------------------- 1 | palindrome :: Eq a => [a] -> Bool 2 | palindrome s = s == reverse s 3 | 4 | digits :: Int -> Int -> [Int] 5 | digits _ 0 = [] 6 | digits base n = r : digits base q 7 | where (q, r) = quotRem n base 8 | 9 | main :: IO () 10 | main = print $ sum [n | n <- [1..1000000], all palindrome [digits 10 n, digits 2 n]] 11 | -------------------------------------------------------------------------------- /036/palindromic-bases.clj: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env clojure 2 | (defn reversed [string] 3 | (apply str (reverse string))) 4 | 5 | (defn palindrome? [string] 6 | (= string (reversed string))) 7 | 8 | (defn palindrome-in-decimal-and-binary? [n] 9 | (and (palindrome? (Integer/toString n 2)) 10 | (palindrome? (Integer/toString n)))) 11 | 12 | (println (reduce + (filter palindrome-in-decimal-and-binary? (range 1 1000000)))) 13 | -------------------------------------------------------------------------------- /036/question.html: -------------------------------------------------------------------------------- 1 |

2 | The decimal number, $585 = 1001001001_2$ (binary), is palindromic in both bases. 3 |

4 | 5 |

6 | Find the sum of all numbers, less than one million, which are palindromic in base 10 and base 2. 7 |

8 | 9 |

10 | (Please note that the palindromic number, in either base, may not include leading zeros.) 11 |

12 | -------------------------------------------------------------------------------- /037/answer.txt: -------------------------------------------------------------------------------- 1 | 748317 2 | -------------------------------------------------------------------------------- /037/question.markdown: -------------------------------------------------------------------------------- 1 | The number 3797 has an interesting property. Being prime itself, it is possible 2 | to continuously remove digits from left to right, and remain prime at each 3 | stage: 3797, 797, 97, and 7. Similarly we can work from right to left: 3797, 4 | 379, 37, and 3. 5 | 6 | Find the sum of the only eleven primes that are both truncatable from left to 7 | right and right to left. 8 | 9 | NOTE: 2, 3, 5, and 7 are not considered to be truncatable primes. 10 | 11 | -------------------------------------------------------------------------------- /037/truncatable-primes.hs: -------------------------------------------------------------------------------- 1 | isPrime :: Int -> Bool 2 | isPrime n | n <= 1 = False 3 | | otherwise = not $ or [n `rem` x == 0 | x <- [2..floor $ sqrt $ fromIntegral n]] 4 | 5 | expand :: [Int] -> [Int] 6 | expand ns = [p | n <- ns, k <- [1, 3, 7, 9], let p = 10*n + k, isPrime p] 7 | 8 | candidates :: [Int] 9 | candidates = dropWhile (< 10) $ concat $ takeWhile (not . null) (iterate expand [2, 3, 5, 7]) 10 | 11 | leftTruncatable :: Int -> Bool 12 | leftTruncatable n = all isPrime $ takeWhile (< n) [n `rem` 10^x | x <- [1..]] 13 | 14 | main :: IO () 15 | main = print $ sum $ filter leftTruncatable candidates 16 | -------------------------------------------------------------------------------- /037/truncatable-primes.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'mathn' 3 | puts (10..1000000).select { |i| 4 | (0..i.to_s.length-1).all? { |j| 5 | i.to_s[0..j].to_i.prime? && i.to_s[j..-1].to_i.prime? 6 | } 7 | }.reduce(:+) 8 | -------------------------------------------------------------------------------- /038/answer.txt: -------------------------------------------------------------------------------- 1 | 932718654 2 | -------------------------------------------------------------------------------- /038/pandigital-concatenation.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | def is_pandigital(*args, **kwargs): 4 | num = sorted(''.join(str(arg) for arg in args)) 5 | 6 | try: 7 | if kwargs['length'] and len(num) != kwargs['length']: 8 | return False 9 | except KeyError: 10 | pass 11 | 12 | for i in range(len(num)): 13 | if str(i+1) != str(num[i]): 14 | return False 15 | return True 16 | 17 | def concatenated_product(number, n): 18 | try: 19 | return int(''.join(str(number * i) for i in range(1,n+1))) 20 | except ValueError: 21 | print(number, n) 22 | 23 | def main(): 24 | print(max(concatenated_product(i, n) for i in range(10000) for n in range(1, 10) if is_pandigital(concatenated_product(i, n)))) 25 | 26 | if __name__ == "__main__": 27 | main() 28 | -------------------------------------------------------------------------------- /038/pandigital-concatenation.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | p (1..9999).flat_map { |i| 3 | (1..9).map { |j| 4 | (1..j).map { |k| 5 | i * k 6 | }.reduce('') { |s,v| s + v.to_s } 7 | } 8 | }.select { |s| 9 | s.length == 9 && s.split('').sort.join('') == '123456789' 10 | }.map { |s| s.to_i }.max 11 | 12 | -------------------------------------------------------------------------------- /038/pandigital-multiples.hs: -------------------------------------------------------------------------------- 1 | import Data.List (sort) 2 | 3 | pandigital :: String -> Bool 4 | pandigital = (== "123456789") . sort 5 | 6 | multiples :: Int -> [String] 7 | multiples x = takeWhile ((== 9) . length) $ dropWhile ((< 9) . length) $ scanl (\acc n -> acc ++ show (x * n)) (show x) [2..] 8 | 9 | main :: IO () 10 | main = putStrLn $ maximum $ filter pandigital $ concatMap multiples [1..10000] 11 | -------------------------------------------------------------------------------- /038/question.markdown: -------------------------------------------------------------------------------- 1 | Take the number 192 and multiply it by each of 1, 2, and 3: 2 | 3 | $$\begin{aligned} 4 | 192 \times 1 & = 192 \\ 5 | 192 \times 2 & = 384 \\ 6 | 192 \times 3 & = 576 7 | \end{aligned}$$ 8 | 9 | By concatenating each product we get the 1 to 9 pandigital, 192384576. 10 | We will call 192384576 the concatenated product of 192 and (1,2,3). 11 | 12 | The same can be achieved by starting with 9 and multiplying by 1, 2, 3, 13 | 4, and 5, giving the pandigital, 918273645, which is the concatenated 14 | product of 9 and (1,2,3,4,5). 15 | 16 | What is the largest 1 to 9 pandigital 9-digit number that can be formed 17 | as the concatenated product of an integer with $1,2,...,n$ where 18 | $n \gt 1$? 19 | -------------------------------------------------------------------------------- /039/answer.txt: -------------------------------------------------------------------------------- 1 | 840 2 | -------------------------------------------------------------------------------- /039/question.html: -------------------------------------------------------------------------------- 1 |

2 | If $p$ is the perimeter of a right angle triangle with integral length sides, $\{a,b,c\}$, there are exactly three solutions for $p = 120$. 3 |

4 | 5 | $$\{20,48,52\}, \{24,45,51\}, \{30,40,50\}$$ 6 | 7 |

8 | For which value of $p \leq 1000$, is the number of solutions maximised? 9 |

10 | -------------------------------------------------------------------------------- /039/right-triangles.hs: -------------------------------------------------------------------------------- 1 | import Data.Function (on) 2 | import Data.List (maximumBy) 3 | 4 | solutions :: Int -> [(Int, Int, Int)] 5 | solutions p = [(a, b, c) | a <- [1..p `quot` 4], 6 | let b = (p * (p - 2*a)) `quot` (2 * (p - a)), 7 | let c = floor $ sqrt $ fromIntegral (a^2 + b^2), 8 | a + b + c == p] 9 | 10 | main :: IO () 11 | main = print $ maximumBy (compare `on` (length . solutions)) [2,4..1000] 12 | -------------------------------------------------------------------------------- /039/triangle-solve.clj.wip: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env clojure 2 | ; If p is the perimeter of a right angle triangle with 3 | ; integral length sides, {a,b,c}, there are exactly three 4 | ; solutions for p = 120. 5 | ; 6 | ; {20,48,52}, {24,45,51}, {30,40,50} 7 | ; 8 | ; For which value of p < 1000, is the number of solutions 9 | ; maximised? 10 | (defn square [n] 11 | (* n n)) 12 | 13 | (defn triple? [a b c] 14 | (and 15 | (and (> a 0) (> b 0) (> c 0)) 16 | (and (< a b) (< b c)) 17 | (= (+ (square a) (square b)) (square c)))) 18 | 19 | (defn solutions [limit p] 20 | (for [a (range 1 (inc limit)) 21 | b (range a (inc limit)) 22 | c (range b (inc limit)) 23 | :when (and 24 | (= (+ a b c) p) 25 | (triple? a b c))] 26 | (list a b c))) 27 | 28 | (def s (map #(solutions 1000 %) (range 1 100))) 29 | (println s) 30 | -------------------------------------------------------------------------------- /039/triangle-solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from collections import defaultdict 3 | 4 | def calculate_solutions(limit): 5 | res = defaultdict(list) 6 | for a in range(1, limit+1): 7 | for b in range(a, limit+1): 8 | for c in range(b, limit+1): 9 | if a**2 + b**2 == c**2: 10 | res[a+b+c].append((a,b,c)) 11 | return res 12 | 13 | def main(): 14 | solutions = calculate_solutions(500) 15 | most = max(len(s) for s in list(solutions.values())) 16 | for p, s in sorted(solutions.items()): 17 | if len(s) == most: 18 | print(p) 19 | 20 | if __name__ == "__main__": 21 | main() 22 | -------------------------------------------------------------------------------- /039/triangle-solve.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | solutions = {} 3 | (1..500).each do |a| 4 | (a..500).each do |b| 5 | (b..500).each do |c| 6 | if a**2 + b**2 == c**2 7 | solutions[a+b+c] ||= 0 8 | solutions[a+b+c] += 1 9 | end 10 | end 11 | end 12 | end 13 | puts solutions.max { |a,b| a[1] <=> b[1] }[0] 14 | -------------------------------------------------------------------------------- /040/answer.txt: -------------------------------------------------------------------------------- 1 | 210 2 | -------------------------------------------------------------------------------- /040/champernowne.hs: -------------------------------------------------------------------------------- 1 | champernowne :: String 2 | champernowne = foldr (\x acc -> (show x) ++ acc) "" [1..] 3 | 4 | main :: IO () 5 | main = print $ product [read [champernowne !! (n - 1)] | n <- [10^x | x <- [0..6]]] 6 | -------------------------------------------------------------------------------- /040/irrational-part.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | d = [int(digit) for digit in ''.join((str(digit) for digit in range(1, 10000001)))] 3 | print(d[0] * d[9] * d[99] * d[999] * d[9999] * d[99999] * d[999999]) 4 | -------------------------------------------------------------------------------- /040/irrational-part.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | s = ('1'..'1000000').to_a.join '' 3 | puts (0..6).map { |i| 4 | s[(10**i)-1].to_i 5 | }.reduce(1, :*) 6 | -------------------------------------------------------------------------------- /040/question.html: -------------------------------------------------------------------------------- 1 |

2 | An irrational decimal fraction is created by concatenating the positive integers: 3 |

4 | 5 | $$0.123456789101112131415161718192021...$$ 6 | 7 |

8 | It can be seen that the 12th digit of the fractional part is 1. 9 |

10 | 11 |

12 | If $d_n$ represents the nth digit of the fractional part, find the value of the following expression. 13 |

14 | 15 | $$d_1 \times d_{10} \times d_{100} \times d_{1000} \times d_{10000} \times d_{100000} \times d_{1000000}$$ 16 | -------------------------------------------------------------------------------- /041/answer.txt: -------------------------------------------------------------------------------- 1 | 7652413 2 | -------------------------------------------------------------------------------- /041/pandigital-prime.hs: -------------------------------------------------------------------------------- 1 | import Data.List (permutations) 2 | 3 | isPrime :: Int -> Bool 4 | isPrime n | n <= 1 = False 5 | | otherwise = not $ or [n `rem` x == 0 | x <- [2..floor $ sqrt $ fromIntegral n]] 6 | 7 | candidates :: [Int] 8 | candidates = filter isPrime $ concatMap (\n -> map (read . concatMap show) $ permutations [1..n]) [1..7] 9 | 10 | main :: IO () 11 | main = print $ maximum candidates 12 | -------------------------------------------------------------------------------- /041/pandigital-prime.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'mathn' 3 | puts (1..9).flat_map { |n| 4 | ('1'..n.to_s).to_a.permutation.map { |p| 5 | p.join('').to_i 6 | }.select { |i| i.prime? } 7 | }.max 8 | -------------------------------------------------------------------------------- /041/question.markdown: -------------------------------------------------------------------------------- 1 | We shall say that an n-digit number is pandigital if it makes use of all the 2 | digits 1 to n exactly once. For example, 2143 is a 4-digit pandigital and is 3 | also prime. 4 | 5 | What is the largest n-digit pandigital prime that exists? 6 | -------------------------------------------------------------------------------- /042/answer.txt: -------------------------------------------------------------------------------- 1 | 162 2 | -------------------------------------------------------------------------------- /042/question.html: -------------------------------------------------------------------------------- 1 |

2 | The $n^{th}$ term of the sequence of triangle numbers is given by, $t_n = \frac{1}{2}n(n+1)$; so the first ten triangle numbers are:

3 | 4 | $$1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...$$ 5 | 6 |

By converting each letter in a word to a number corresponding to its alphabetical position and adding these values we form a word value. For example, the word value for SKY is $19 + 11 + 25 = 55 = t_{10}$. If the word value is a triangle number then we shall call the word a triangle word.

7 | 8 |

Using words.txt (right click and 'Save Link/Target As...'), a 16K text file containing nearly two-thousand common English words, how many are triangle words?

9 | 10 | -------------------------------------------------------------------------------- /042/triangle-words.hs: -------------------------------------------------------------------------------- 1 | parse :: String -> [String] 2 | parse = words . map replaceComma . filter notQuote where 3 | replaceComma ',' = ' ' 4 | replaceComma c = c 5 | notQuote = (/= '"') 6 | 7 | alphaIndex :: Char -> Int 8 | alphaIndex c = fromEnum c - 64 9 | 10 | alphaScore :: String -> Int 11 | alphaScore = sum . map alphaIndex 12 | 13 | triangle :: String -> Bool 14 | triangle str = floor t == ceiling t 15 | where s = alphaScore str 16 | t = (sqrt (fromIntegral (1 + 8*s)) - 1) / 2 17 | 18 | main :: IO () 19 | main = do 20 | str <- readFile "/home/zach/code/euler/042/words.txt" 21 | print $ length $ filter triangle $ parse str 22 | -------------------------------------------------------------------------------- /042/triangle-words.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | from string import ascii_uppercase 4 | 5 | def letter_value(letter): 6 | return ascii_uppercase.index(letter.upper())+1 7 | 8 | def word_value(word): 9 | return sum(letter_value(letter) for letter in word) 10 | 11 | def triangle(n): 12 | return int((0.5) * n * (n+1)) 13 | 14 | def main(): 15 | triangle_numbers = [triangle(n) for n in range(1, 100)] 16 | words = [word.strip('"') for word in open(os.path.join(os.path.dirname(__file__), 'words.txt')).read().split(',')] 17 | total = 0 18 | for word in words: 19 | if word_value(word) in triangle_numbers: 20 | total += 1 21 | print(total) 22 | 23 | if __name__ == "__main__": 24 | main() 25 | 26 | -------------------------------------------------------------------------------- /042/triangle-words.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | triangles = (1..1000).map { |n| (n*(n+1))/2 }.to_a 3 | puts File.read(File.dirname(__FILE__) + '/words.txt').scan(/\w+/).select { |word| 4 | triangles.include? word.each_byte.reduce(0) {|s,v| s+(v-64) } 5 | }.count 6 | 7 | -------------------------------------------------------------------------------- /043/answer.txt: -------------------------------------------------------------------------------- 1 | 16695334890 2 | -------------------------------------------------------------------------------- /043/pandigital-substrings.hs: -------------------------------------------------------------------------------- 1 | import Data.List (nub) 2 | 3 | expand :: Int -> String -> [String] 4 | expand x "" = [s | n <- [100..999], n `rem` x == 0, let s = show n, s == nub s] 5 | expand x s = [c:s | c <- ['0'..'9'], c `notElem` s, (read (c:take 2 s)) `rem` x == 0] 6 | 7 | candidates :: [String] 8 | candidates = inner [17, 13, 11, 7, 5, 3, 2, 1] [""] where 9 | inner [] acc = acc 10 | inner (x:xs) acc = inner xs $ concatMap (expand x) acc 11 | 12 | main :: IO () 13 | main = print $ sum $ map read candidates 14 | -------------------------------------------------------------------------------- /043/pandigital-substrings.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from itertools import * 3 | 4 | def has_property(digits): 5 | primes = [1,2,3,5,7,11,13,17] 6 | for i in range(1, len(digits)-2): 7 | if not int(''.join(digits[i:i+3])) % primes[i] == 0: 8 | return False 9 | return True 10 | 11 | def convert_list_to_int(l): 12 | return int(''.join(str(i) for i in l)) 13 | 14 | def main(): 15 | pandigitals = permutations((str(i) for i in range(10))) 16 | print(sum(convert_list_to_int(p) for p in pandigitals if has_property(p))) 17 | 18 | if __name__ == "__main__": 19 | main() 20 | -------------------------------------------------------------------------------- /043/pandigital-substrings.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | primes = [1,2,3,5,7,11,13,17] 3 | puts ('0'..'9').to_a.permutation.select { |digits| 4 | (1..7).all? { |i| 5 | digits[i..i+2].join('').to_i % primes[i] == 0 6 | } 7 | }.map { |digits| digits.join('').to_i }.reduce(:+) 8 | -------------------------------------------------------------------------------- /043/question.markdown: -------------------------------------------------------------------------------- 1 | The number, 1406357289, is a 0 to 9 pandigital number because it is made 2 | up of each of the digits 0 to 9 in some order, but it also has a rather 3 | interesting sub-string divisibility property. 4 | 5 | Let $d_1$ be the $1^{st}$ digit, $d_2$ be the $2^{nd}$ digit, and so on. 6 | In this way, we note the following: 7 | 8 | $$\begin{aligned} 9 | d_2d_3d_4 & =406 \text{ is divisible by 2} \\ 10 | d_3d_4d_5 & =063 \text{ is divisible by 3} \\ 11 | d_4d_5d_6 & =635 \text{ is divisible by 5} \\ 12 | d_5d_6d_7 & =357 \text{ is divisible by 7} \\ 13 | d_6d_7d_8 & =572 \text{ is divisible by 11} \\ 14 | d_7d_8d_9 & =728 \text{ is divisible by 13} \\ 15 | d_8d_9d_{10} & =289 \text{ is divisible by 17} 16 | \end{aligned}$$ 17 | 18 | Find the sum of all 0 to 9 pandigital numbers with this property. 19 | -------------------------------------------------------------------------------- /044/answer.txt: -------------------------------------------------------------------------------- 1 | 5482660 2 | -------------------------------------------------------------------------------- /044/pentagonal-nums.hs: -------------------------------------------------------------------------------- 1 | import qualified Data.Set as Set 2 | 3 | pentagonals :: [Int] 4 | pentagonals = [(n*(3*n - 1)) `quot` 2 | n <- [1..3000]] 5 | 6 | isPentagonal :: Int -> Bool 7 | isPentagonal n = Set.member n (Set.fromList pentagonals) 8 | 9 | candidates :: [Int] 10 | candidates = [j - k | j <- pentagonals, k <- takeWhile (< j) pentagonals, 11 | isPentagonal (j - k), isPentagonal (j + k)] 12 | 13 | main :: IO () 14 | main = print $ head candidates 15 | -------------------------------------------------------------------------------- /044/pentagonal-nums.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from itertools import * 3 | from math import * 4 | from operator import * 5 | 6 | def pentagonal(n): 7 | return n*(3*n-1)//2 8 | 9 | def main(): 10 | pentagonals = set(pentagonal(n) for n in range(1, 3000)) 11 | c = combinations(pentagonals, 2) 12 | for p in c: 13 | if add(*p) in pentagonals and abs(sub(*p)) in pentagonals: 14 | print(abs(sub(*p))) 15 | 16 | if __name__ == "__main__": 17 | main() 18 | -------------------------------------------------------------------------------- /044/pentagonal-nums.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'set' 3 | pentagonals = (1..3000).map { |n| n*(3*n-1)/2 }.to_set 4 | puts pentagonals.to_a.combination(2).select { |a,b| 5 | pentagonals.include?(a+b) && pentagonals.include?((a-b).abs) 6 | }.map { |a,b| (a-b).abs }.min 7 | -------------------------------------------------------------------------------- /044/question.html: -------------------------------------------------------------------------------- 1 |

2 | Pentagonal numbers are generated by the formula, $P_n=\frac{n(3n-1)}{2}$. The first ten pentagonal numbers are: 3 |

4 | 5 | $$1, 5, 12, 22, 35, 51, 70, 92, 117, 145, ...$$ 6 | 7 |

8 | It can be seen that $P_4 + P_7 = 22 + 70 = 92 = P_8$. However, their difference, $70 - 22 = 48$, is not pentagonal. 9 |

10 | 11 |

12 | Find the pair of pentagonal numbers, $P_j$ and $P_k$, for which their sum and difference is pentagonal and $D = |P_k - P_j|$ is minimised; what is the value of $D$? 13 |

14 | -------------------------------------------------------------------------------- /045/answer.txt: -------------------------------------------------------------------------------- 1 | 1533776805 2 | -------------------------------------------------------------------------------- /045/question.markdown: -------------------------------------------------------------------------------- 1 | Triangle, pentagonal, and hexagonal numbers are generated by the 2 | following formulae: 3 | 4 | $$\begin{aligned} 5 | \text{Triangle} & T_n=\frac{n(n+1)}{2} & 1, 3, 6, 10, 15, ... \\ 6 | \text{Pentagonal} & P_n=\frac{n(3n-1)}{2} & 1, 5, 12, 22, 35, ... \\ 7 | \text{Hexagonal} & H_n=n(2n-1) & 1, 6, 15, 28, 45, ... 8 | \end{aligned}$$ 9 | 10 | It can be verified that $T_{285} = P_{165} = H_{143} = 40755$. 11 | 12 | Find the next triangle number that is also pentagonal and hexagonal. 13 | -------------------------------------------------------------------------------- /045/tri-pen-hex.hs: -------------------------------------------------------------------------------- 1 | import qualified Data.Set as Set 2 | 3 | triangles :: [Int] 4 | triangles = [(n*(n + 1)) `quot` 2 | n <- [1..]] 5 | 6 | pentagonals :: [Int] 7 | pentagonals = [(n*(3*n - 1)) `quot` 2 | n <- [1..100000]] 8 | 9 | hexagonals :: [Int] 10 | hexagonals = [n*(2*n - 1) | n <- [1..100000]] 11 | 12 | candidates :: [Int] 13 | candidates = dropWhile (<= 40755) [t | t <- triangles, isPentagonal t, isHexagonal t] 14 | where isPentagonal = (`Set.member` Set.fromList pentagonals) 15 | isHexagonal = (`Set.member` Set.fromList hexagonals) 16 | 17 | main :: IO () 18 | main = print $ head candidates 19 | -------------------------------------------------------------------------------- /045/tri-pen-hex.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | def triangle(n): 3 | return n*(n+1)//2 4 | 5 | def pentagonal(n): 6 | return n*(3*n-1)//2 7 | 8 | def hexagonal(n): 9 | return n*(2*n-1) 10 | 11 | def main(): 12 | p = set(pentagonal(n) for n in range(100000)) 13 | h = set(hexagonal(n) for n in range(100000)) 14 | for n in range(100000): 15 | t = triangle(n) 16 | if t in p and t in h and t > 40755: 17 | print(t) 18 | 19 | if __name__ == "__main__": 20 | main() 21 | -------------------------------------------------------------------------------- /045/tri-pen-hex.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'set' 3 | p = (1..100000).map { |n| n*(3*n-1)/2 }.to_set 4 | h = (1..100000).map { |n| n*(2*n-1) }.to_set 5 | puts (286..100000).map { |n| n*(n+1)/2 }.detect { |t| 6 | p.include?(t) and h.include?(t) 7 | } 8 | -------------------------------------------------------------------------------- /046/answer.txt: -------------------------------------------------------------------------------- 1 | 5777 2 | -------------------------------------------------------------------------------- /046/composite-prime.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from itertools import product 3 | 4 | def sieve(n): 5 | numbers = list(range(2, n+1)) 6 | p = 2 7 | j = 0 8 | done = False 9 | while not done: 10 | for i, n in enumerate(numbers): 11 | if n % p == 0 and n!=p: 12 | numbers.pop(i) 13 | j += 1 14 | p = numbers[j] 15 | if p**2 > n: 16 | done = True 17 | return numbers 18 | 19 | def main(): 20 | primes = sieve(10000) 21 | composites = set(n for n in range(2,10000) if n not in primes) 22 | twicesquares = set(2*(n**2) for n in range(100)) 23 | 24 | sums = set(sum(c) for c in product(primes, twicesquares)) 25 | print(min(n for n in composites if n not in sums and n % 2 != 0)) 26 | 27 | if __name__ == "__main__": 28 | main() 29 | -------------------------------------------------------------------------------- /046/composite-prime.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'set' 3 | require 'mathn' 4 | primes = (2..10000).select { |n| n.prime? }.to_set 5 | composites = (2..10000).reject { |n| n.prime? }.to_set 6 | twicesquares = (0..100).map { |n| 2*(n**2) }.to_set 7 | sums = primes.to_a.product(twicesquares.to_a).map { |a,b| a+b }.to_set 8 | puts composites.select { |n| !sums.include?(n) and n.odd? }.min 9 | -------------------------------------------------------------------------------- /046/goldbach.hs: -------------------------------------------------------------------------------- 1 | isPrime :: Integer -> Bool 2 | isPrime n | n < 1 = False 3 | | otherwise = not $ or [n `rem` x == 0 | x <- [2..floor $ sqrt $ fromIntegral n]] 4 | 5 | isSum :: Integer -> Bool 6 | isSum n = any isPrime [n - 2*s^2 | s <- [0..floor $ sqrt $ fromInteger n]] 7 | 8 | candidates :: [Integer] 9 | candidates = [n | n <- [1,3..], not (isPrime n), not (isSum n)] 10 | 11 | main :: IO () 12 | main = print $ head candidates 13 | -------------------------------------------------------------------------------- /046/question.markdown: -------------------------------------------------------------------------------- 1 | It was proposed by Christian Goldbach that every odd composite number 2 | can be written as the sum of a prime and twice a square. 3 | 4 | $$\begin{aligned} 5 | 9 & = 7 + 2\times1^2 \\ 6 | 15 & = 7 + 2\times2^2 \\ 7 | 21 & = 3 + 2\times3^2 \\ 8 | 25 & = 7 + 2\times3^2 \\ 9 | 27 & = 19 + 2\times2^2 \\ 10 | 33 & = 31 + 2\times1^2 11 | \end{aligned}$$ 12 | 13 | It turns out that the conjecture was false. 14 | 15 | What is the smallest odd composite that cannot be written as the sum of 16 | a prime and twice a square? 17 | -------------------------------------------------------------------------------- /047/answer.txt: -------------------------------------------------------------------------------- 1 | 134043 2 | -------------------------------------------------------------------------------- /047/consecutive-factors.hs: -------------------------------------------------------------------------------- 1 | import Data.List (nub) 2 | 3 | primes :: [Int] 4 | primes = 2 : sieve primes [3,5..] where 5 | sieve (p:ps) xs = h ++ sieve ps [x | x <- t, rem x p /= 0] 6 | where (h, t) = span (< p*p) xs 7 | 8 | factorize :: Int -> [Int] 9 | factorize n = primeFactors n primes where 10 | primeFactors 1 _ = [] 11 | primeFactors _ [] = [] 12 | primeFactors m (p:ps) | m < p * p = [m] 13 | | r == 0 = p : primeFactors q (p:ps) 14 | | otherwise = primeFactors m ps 15 | where (q, r) = quotRem m p 16 | 17 | uniqueFactors :: Int -> Int 18 | uniqueFactors = length . nub . factorize 19 | 20 | chunks :: Int -> [a] -> [[a]] 21 | chunks n l | length chunk < n = [] 22 | | otherwise = chunk : chunks n (tail l) 23 | where chunk = take n l 24 | 25 | candidates :: [[Int]] 26 | candidates = [cons | cons <- chunks 4 [1..], all ((== 4) . uniqueFactors) cons] 27 | 28 | main :: IO () 29 | main = print $ head $ head candidates 30 | -------------------------------------------------------------------------------- /047/consecutive-factors.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import math 3 | 4 | def factorize(n): 5 | if n < 1: 6 | raise ValueError('fact() argument should be >= 1') 7 | if n == 1: 8 | return [] # special case 9 | res = [] 10 | # iterate over all even numbers first. 11 | while n % 2 == 0: 12 | res.append(2) 13 | n //= 2 14 | # try odd numbers up to sqrt(n) 15 | limit = math.sqrt(n+1) 16 | i = 3 17 | while i <= limit: 18 | if n % i == 0: 19 | res.append(i) 20 | n //= i 21 | limit = math.sqrt(n+i) 22 | else: 23 | i += 2 24 | if n != 1: 25 | res.append(n) 26 | return res 27 | 28 | def distinct_prime_factors(n): 29 | return set(factorize(n)) 30 | 31 | def main(): 32 | chain = [] 33 | search = 4 34 | for n in range(1, 1000000): 35 | if len(distinct_prime_factors(n)) == search: 36 | chain.append(n) 37 | print(next(chain[i:i+search] for i, n in enumerate(chain) if chain[i:i+search] == list(range(n, n+search)))[0]) 38 | 39 | if __name__ == "__main__": main() 40 | -------------------------------------------------------------------------------- /047/consecutive-factors.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'mathn' 3 | puts (1..1000000).each_cons(4).detect { |nums| 4 | nums.all? { |n| n.prime_division.length == 4 } 5 | }[0] 6 | -------------------------------------------------------------------------------- /047/question.markdown: -------------------------------------------------------------------------------- 1 | The first two consecutive numbers to have two distinct prime factors 2 | are: 3 | 4 | $$\begin{aligned} 5 | 14 & = 2 \times 7 \\ 6 | 15 & = 3 \times 5 7 | \end{aligned}$$ 8 | 9 | The first three consecutive numbers to have three distinct prime factors 10 | are: 11 | 12 | $$\begin{aligned} 13 | 644 & = 2^2 \times 7 \times 23 \\ 14 | 645 & = 3 \times 5 \times 43 \\ 15 | 646 & = 2 \times 17 \times 19 16 | \end{aligned}$$ 17 | 18 | Find the first four consecutive integers to have four distinct primes 19 | factors. What is the first of these numbers? 20 | -------------------------------------------------------------------------------- /048/answer.txt: -------------------------------------------------------------------------------- 1 | 9110846700 2 | -------------------------------------------------------------------------------- /048/power-series.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | puts (1..1000).reduce(0) { |s,n| s + n**n }.to_s[-10..-1] 3 | -------------------------------------------------------------------------------- /048/question.html: -------------------------------------------------------------------------------- 1 |

2 | The series, $1^1 + 2^2 + 3^3 + ... + 10^{10} = 10405071317$. 3 |

4 | 5 |

6 | Find the last ten digits of the series, $1^1 + 2^2 + 3^3 + ... + 1000^{1000}$. 7 |

8 | -------------------------------------------------------------------------------- /048/raise-to-itself.clj: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env clojure 2 | (defn raise [x n] 3 | (. (. java.math.BigInteger (valueOf x)) (pow n))) 4 | 5 | (defn raise-to-itself [number] 6 | (raise number number)) 7 | 8 | (defn digits [n] 9 | (map #(- (int %) 48) (str n))) 10 | 11 | (def result (reduce + (map raise-to-itself (range 1 1001)))) 12 | (println (apply str (reverse (take 10 (reverse (digits result)))))) 13 | -------------------------------------------------------------------------------- /048/self-powers.hs: -------------------------------------------------------------------------------- 1 | lastN :: Int -> [a] -> [a] 2 | lastN n xs = foldl (const . drop 1) xs (drop n xs) 3 | 4 | main :: IO () 5 | main = putStrLn $ lastN 10 $ show $ sum [x^x | x <- [1..1000]] 6 | -------------------------------------------------------------------------------- /049/answer.txt: -------------------------------------------------------------------------------- 1 | 296962999629 2 | -------------------------------------------------------------------------------- /049/prime-permutations.hs: -------------------------------------------------------------------------------- 1 | import Data.List (sort) 2 | 3 | primes :: [Int] 4 | primes = 2 : sieve primes [3,5..] where 5 | sieve (p:ps) xs = h ++ sieve ps [x | x <- t, rem x p /= 0] 6 | where (h, t) = span (< p*p) xs 7 | 8 | isPrime :: Int -> Bool 9 | isPrime n | n < 1 = False 10 | | otherwise = not $ or [n `rem` x == 0 | x <- [2..floor $ sqrt $ fromIntegral n]] 11 | 12 | candidates :: [[Int]] 13 | candidates = tail [ps | p <- dropWhile (< 1000) primes, 14 | let ps = [p, p + 3330, p + 6660], 15 | all isPrime ps, 16 | let sorted = map (sort . show) ps, 17 | all (== head sorted) sorted] 18 | 19 | main :: IO () 20 | main = putStrLn $ concatMap show $ head candidates 21 | -------------------------------------------------------------------------------- /049/prime-sequence.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'mathn' 3 | primes = (1488..9999).select { |n| n.prime? } 4 | primes.each do |a| 5 | primes.select { |b| b > a }.each do |b| 6 | primes.select { |c| c > b }.each do |c| 7 | if c-b == b-a && 8 | a.to_s.split('').sort == b.to_s.split('').sort && 9 | b.to_s.split('').sort == c.to_s.split('').sort && 10 | c.to_s.split('').sort == a.to_s.split('').sort 11 | puts a.to_s + b.to_s + c.to_s; exit 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /049/question.markdown: -------------------------------------------------------------------------------- 1 | The arithmetic sequence, 1487, 4817, 8147, in which each of the terms increases by 3330, is unusual in two ways: (i) each of the three terms are prime, and, (ii) each of the 4-digit numbers are permutations of one another. 2 | 3 | There are no arithmetic sequences made up of three 1-, 2-, or 3-digit primes, exhibiting this property, but there is one other 4-digit increasing sequence. 4 | 5 | What 12-digit number do you form by concatenating the three terms in this sequence? 6 | 7 | -------------------------------------------------------------------------------- /050/answer.txt: -------------------------------------------------------------------------------- 1 | 997651 2 | -------------------------------------------------------------------------------- /050/consecutive-prime-sum.hs: -------------------------------------------------------------------------------- 1 | import Data.Function (on) 2 | import Data.List (maximumBy) 3 | 4 | primes :: [Int] 5 | primes = 2 : sieve primes [3,5..] where 6 | sieve (p:ps) xs = h ++ sieve ps [x | x <- t, rem x p /= 0] 7 | where (h, t) = span (< p*p) xs 8 | 9 | isPrime :: Int -> Bool 10 | isPrime n | n < 1 = False 11 | | otherwise = not $ or [n `rem` x == 0 | x <- [2..floor $ sqrt $ fromIntegral n]] 12 | 13 | consecutive :: Int -> [Int] 14 | consecutive p = dropWhile (not . isPrime) $ reverse sums where 15 | sums = takeWhile (< 1000000) $ scanl1 (+) $ dropWhile (< p) primes 16 | 17 | main :: IO () 18 | main = print $ head $ maximumBy (compare `on` length) $ map consecutive $ take 10 primes 19 | -------------------------------------------------------------------------------- /050/consecutive-prime-sum.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'mathn' 3 | primes = Prime.each(10000).to_a 4 | longest = [] 5 | primes[0..10].each_with_index { |p, i| 6 | j = i 7 | begin 8 | j += 1 9 | cons = primes[i..j] 10 | sum = cons.reduce(:+) 11 | if sum.prime? && cons.length > longest.length 12 | longest = cons 13 | end 14 | end while sum < 1000000 15 | } 16 | puts longest.reduce(:+) 17 | -------------------------------------------------------------------------------- /050/question.html: -------------------------------------------------------------------------------- 1 |

2 | The prime 41, can be written as the sum of six consecutive primes: 3 |

4 | 5 | $$41 = 2 + 3 + 5 + 7 + 11 + 13$$ 6 | 7 |

8 | This is the longest sum of consecutive primes that adds to a prime below one-hundred. 9 |

10 | 11 |

12 | The longest sum of consecutive primes below one-thousand that adds to a prime, contains 21 terms, and is equal to 953. 13 |

14 | 15 |

16 | Which prime, below one-million, can be written as the sum of the most consecutive primes? 17 |

18 | -------------------------------------------------------------------------------- /051/answer.txt: -------------------------------------------------------------------------------- 1 | 121313 2 | -------------------------------------------------------------------------------- /051/prime-replacement.hs: -------------------------------------------------------------------------------- 1 | import Data.List (sort, group) 2 | 3 | primes :: [Int] 4 | primes = 2 : sieve primes [3,5..] where 5 | sieve (p:ps) xs = h ++ sieve ps [x | x <- t, rem x p /= 0] 6 | where (h, t) = span (< p*p) xs 7 | 8 | isPrime :: Int -> Bool 9 | isPrime n | n < 1 = False 10 | | otherwise = not $ or [n `rem` x == 0 | x <- [2..floor $ sqrt $ fromIntegral n]] 11 | 12 | groupFrequency :: Ord a => [a] -> [(Int, a)] 13 | groupFrequency xs = reverse $ sort [(length cs, head cs) | cs <- group $ sort xs] 14 | 15 | candidates :: [(Char, String)] 16 | candidates = [(snd $ head g, s) | p <- primes, 17 | let s = show p, 18 | let g = groupFrequency s, 19 | any ((== 3) . fst) g] 20 | 21 | replace :: Eq a => a -> a -> [a] -> [a] 22 | replace old new = foldr (\x acc -> (if x == old then new else x) : acc) [] 23 | 24 | expand :: (Char, String) -> [String] 25 | expand (d, ds) = [new | n <- ['1'..'9'], let new = replace d n ds, isPrime (read new)] 26 | 27 | main :: IO () 28 | main = putStrLn $ snd . head $ filter ((== 8) . length . expand) candidates 29 | -------------------------------------------------------------------------------- /051/question.markdown: -------------------------------------------------------------------------------- 1 | By replacing the 1st digit of *3, it turns out that six of the nine possible 2 | values: 13, 23, 43, 53, 73, and 83, are all prime. 3 | 4 | By replacing the 3rd and 4th digits of 56**3 with the same digit, this 5-digit 5 | number is the first example having seven primes among the ten generated 6 | numbers, yielding the family: 56003, 56113, 56333, 56443, 56663, 56773, and 7 | 56993. Consequently 56003, being the first member of this family, is the 8 | smallest prime with this property. 9 | 10 | Find the smallest prime which, by replacing part of the number (not necessarily 11 | adjacent digits) with the same digit, is part of an eight prime value family. 12 | -------------------------------------------------------------------------------- /052/answer.txt: -------------------------------------------------------------------------------- 1 | 142857 2 | -------------------------------------------------------------------------------- /052/permuted-multiples.hs: -------------------------------------------------------------------------------- 1 | import Data.List (sort) 2 | 3 | main :: IO () 4 | main = print $ head [n | n <- [1..], all ((== (sort . show) n) . (sort . show) . (n*)) [1..6]] 5 | -------------------------------------------------------------------------------- /052/question.markdown: -------------------------------------------------------------------------------- 1 | It can be seen that the number, 125874, and its double, 251748, contain exactly the same digits, but in a different order. 2 | 3 | Find the smallest positive integer, x, such that 2x, 3x, 4x, 5x, and 6x, contain the same digits. 4 | 5 | -------------------------------------------------------------------------------- /052/same-digits.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | def get_digits(n): 4 | return sorted(str(n)) 5 | 6 | def same_digits(n, iterations=2): 7 | digits = get_digits(n) 8 | for i in range(1, iterations): 9 | if not digits == get_digits(n+(i*n)): 10 | return False 11 | return True 12 | 13 | def main(): 14 | n = 0 15 | found = False 16 | while not found: 17 | n += 1 18 | if same_digits(n,6): 19 | found = True 20 | print(n) 21 | 22 | if __name__ == "__main__": 23 | main() 24 | -------------------------------------------------------------------------------- /053/answer.txt: -------------------------------------------------------------------------------- 1 | 4075 2 | -------------------------------------------------------------------------------- /053/combinatoric-selections.hs: -------------------------------------------------------------------------------- 1 | choose :: Integer -> Integer -> Integer 2 | choose _ 0 = 1 3 | choose 0 _ = 0 4 | choose n r = choose (n-1) (r-1) * n `div` r 5 | 6 | main :: IO () 7 | main = print $ length $ filter (> 1000000) [n `choose` r | n <- [1..100], r <- [1..n]] 8 | -------------------------------------------------------------------------------- /053/large-combos.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from gmpy2 import comb 3 | count = 0 4 | for n in range(1, 101): 5 | for r in range(1, n): 6 | c = comb(n,r) 7 | if c > 1000000: 8 | count += 1 9 | print(count) 10 | -------------------------------------------------------------------------------- /053/question.html: -------------------------------------------------------------------------------- 1 |

2 | There are exactly ten ways of selecting three from five, 12345: 3 |

4 | 5 | $$123, 124, 125, 134, 135, 145, 234, 235, 245, \text{ and } 345$$ 6 | 7 |

8 | In combinatorics, we use the notation, $^5C_3 = 10$. 9 |

10 | 11 |

12 | In general, 13 |

14 | 15 | $$^nC_r = \frac{n!}{r!(n-r)!}, \text{ where } r \leq n, n! = n\times(n-1)\times...\times3\times2\times1, \text{ and } 0! = 1.$$ 16 | 17 |

18 | It is not until $n = 23$, that a value exceeds one-million: $^{23}C_{10} = 1144066$. 19 |

20 | 21 |

22 | How many, not necessarily distinct, values of $^nC_r$, for $1 \leq n \leq 100$, are greater than one-million? 23 |

24 | 25 | -------------------------------------------------------------------------------- /054/answer.txt: -------------------------------------------------------------------------------- 1 | 376 2 | -------------------------------------------------------------------------------- /055/answer.txt: -------------------------------------------------------------------------------- 1 | 249 2 | -------------------------------------------------------------------------------- /055/lychrel.hs: -------------------------------------------------------------------------------- 1 | palindrome :: String -> Bool 2 | palindrome s = s == reverse s 3 | 4 | lychrel :: Int -> Bool 5 | lychrel n = not $ any palindrome $ take 50 $ tail (iterate (\x -> show $ (read x) + (read $ reverse x)) (show n)) 6 | 7 | main :: IO () 8 | main = print $ length $ filter lychrel [1..10000] 9 | -------------------------------------------------------------------------------- /055/lychrel.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | def is_palindrome(s): 4 | return s == ''.join(reversed(s)) 5 | 6 | def is_lychrel(n): 7 | s = str(n) 8 | i = 0 9 | done = False 10 | while not done: 11 | if i > 50: 12 | return True 13 | s = str(int(s) + int(''.join(reversed(s)))) 14 | i += 1 15 | if is_palindrome(s): 16 | done = True 17 | return False 18 | 19 | def main(): 20 | count = 0 21 | for n in range(10000): 22 | if is_lychrel(n): 23 | count += 1 24 | print(count) 25 | 26 | if __name__ == "__main__": 27 | main() 28 | -------------------------------------------------------------------------------- /056/answer.txt: -------------------------------------------------------------------------------- 1 | 972 2 | -------------------------------------------------------------------------------- /056/digit-sum.hs: -------------------------------------------------------------------------------- 1 | digits :: Integer -> [Integer] 2 | digits 0 = [] 3 | digits n = r : digits q 4 | where (q, r) = quotRem n 10 5 | 6 | main :: IO () 7 | main = print $ maximum [sum $ digits $ a^b | a <- [1..99], b <- [1..99]] 8 | -------------------------------------------------------------------------------- /056/digital-sum.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from itertools import * 3 | 4 | def get_digits(n): 5 | return [int(digit) for digit in str(n)] 6 | 7 | def main(): 8 | largest = 0 9 | for a, b in product(list(range(1, 100)), list(range(1, 100))): 10 | s = sum(get_digits(a ** b)) 11 | if s > largest: 12 | largest = s 13 | print(largest) 14 | 15 | if __name__ == "__main__": 16 | main() 17 | -------------------------------------------------------------------------------- /056/question.markdown: -------------------------------------------------------------------------------- 1 | A googol ($10^{100}$) is a massive number: one followed by one-hundred 2 | zeros; $100^{100}$ is almost unimaginably large: one followed by 3 | two-hundred zeros. Despite their size, the sum of the digits in each 4 | number is only 1. 5 | 6 | Considering natural numbers of the form, $ab$, where $a, b < 100$, what 7 | is the maximum digital sum? 8 | -------------------------------------------------------------------------------- /057/answer.txt: -------------------------------------------------------------------------------- 1 | 153 2 | -------------------------------------------------------------------------------- /057/question.markdown: -------------------------------------------------------------------------------- 1 | It is possible to show that the square root of two can be expressed as 2 | an infinite continued fraction. 3 | 4 | $$\sqrt{2} = 1 + \dfrac{1}{2 + \dfrac{1}{2 + \dfrac{1}{2 + ...}}} = 1.414213...$$ 5 | 6 | By expanding this for the first four iterations, we get: 7 | 8 | $$\begin{aligned} 9 | 1 + \frac{1}{2} & = \frac{3}{2} = 1.5 \\ 10 | 1 + \dfrac{1}{2 + \dfrac{1}{2}} & = \frac{7}{5} = 1.4 \\ 11 | 1 + \dfrac{1}{2 + \dfrac{1}{2 + \dfrac{1}{2}}} & = \frac{17}{12} = 1.41666... \\ 12 | 1 + \dfrac{1}{2 + \dfrac{1}{2 + \dfrac{1}{2 + \dfrac{1}{2}}}} & = \frac{41}{29} = 1.41379... 13 | \end{aligned}$$ 14 | 15 | The next three expansions are $\frac{99}{70}$, $\frac{239}{169}$, and 16 | $\frac{577}{408}$, but the eighth expansion, $\frac{1393}{985}$, is the 17 | first example where the number of digits in the numerator exceeds the 18 | number of digits in the denominator. 19 | 20 | In the first one-thousand expansions, how many fractions contain a 21 | numerator with more digits than denominator? 22 | -------------------------------------------------------------------------------- /057/root-two.hs: -------------------------------------------------------------------------------- 1 | expansion :: [(Integer, Integer)] 2 | expansion = iterate (\(n, d) -> (d, n + 2*d)) (1, 2) 3 | 4 | main :: IO () 5 | main = print $ length [(n, d) | (n, d) <- take 1000 expansion, length (show (n + d)) > length (show d)] 6 | -------------------------------------------------------------------------------- /057/root-two.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import fractions 3 | 4 | def root_two(iterations): 5 | d = fractions.Fraction(1/2) 6 | for i in range(iterations): 7 | d = fractions.Fraction(1/(2+d)) 8 | yield 1 + d 9 | 10 | def main(): 11 | print(len([f for f in root_two(1000) if len(str(f.numerator)) > len(str(f.denominator))])) 12 | 13 | if __name__ == "__main__": 14 | main() 15 | -------------------------------------------------------------------------------- /058/answer.txt: -------------------------------------------------------------------------------- 1 | 26241 2 | -------------------------------------------------------------------------------- /058/question.html: -------------------------------------------------------------------------------- 1 |

Starting with 1 and spiralling anticlockwise in the following way, a square spiral with side length 7 is formed.

2 | 3 |
37 36 35 34 33 32 31
 4 | 38 17 16 15 14 13 30
 5 | 39 18  5  4  3 12 29
 6 | 40 19  6  1  2 11 28
 7 | 41 20  7  8  9 10 27
 8 | 42 21 22 23 24 25 26
 9 | 43 44 45 46 47 48 49
10 | 
11 | 12 |

It is interesting to note that the odd squares lie along the bottom right diagonal, but what is more interesting is that 8 out of the 13 numbers lying along both diagonals are prime; that is, a ratio of $\frac{8}{13} \approx 62\%$.

13 | 14 |

If one complete new layer is wrapped around the spiral above, a square spiral with side length 9 will be formed. If this process is continued, what is the side length of the square spiral for which the ratio of primes along both diagonals first falls below 10%?

15 | -------------------------------------------------------------------------------- /058/spiral-primes.hs: -------------------------------------------------------------------------------- 1 | isPrime :: Int -> Bool 2 | isPrime n | n < 1 = False 3 | | otherwise = not $ or [n `rem` x == 0 | x <- [2..floor $ sqrt $ fromIntegral n]] 4 | 5 | primeCorners :: Int -> Int 6 | primeCorners n = sum [1 | x <- [1..3], isPrime $ n^2 - x*(n - 1)] 7 | 8 | expansion :: [(Int, Int)] 9 | expansion = scanl (\(p, t) x -> (p + primeCorners x, t + 4)) (0, 1) [3,5..] 10 | 11 | main :: IO () 12 | main = print $ 3 + 2 * (length $ takeWhile id $ tail [10*p >= t | (p, t) <- expansion]) 13 | -------------------------------------------------------------------------------- /059/answer.txt: -------------------------------------------------------------------------------- 1 | 107359 2 | -------------------------------------------------------------------------------- /060/answer.txt: -------------------------------------------------------------------------------- 1 | 26033 2 | -------------------------------------------------------------------------------- /060/concatenate-primes.py.wip: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from itertools import * 3 | from bisect import bisect_left 4 | 5 | def primes(n): 6 | if n==2: return [2] 7 | elif n<2: return [] 8 | s=range(3,n+1,2) 9 | mroot = n ** 0.5 10 | half=(n+1)/2-1 11 | i=0 12 | m=3 13 | while m <= mroot: 14 | if s[i]: 15 | j=(m*m-3)/2 16 | s[j]=0 17 | while j Bool 7 | isPrime n | n < 1 = False 8 | | otherwise = not $ or [n `rem` x == 0 | x <- [2..floor $ sqrt $ fromIntegral n]] 9 | 10 | filterPairs :: Int -> [Int] -> [Int] 11 | filterPairs p = filter test where 12 | test x = isPrime (read $ show x ++ show p) && isPrime (read $ show p ++ show x) 13 | 14 | candidates :: [[Int]] 15 | candidates = [[a, b, c, d, e] | a <- primes', 16 | let bs = filterPairs a $ dropWhile (<= a) primes', 17 | b <- bs, 18 | let cs = filterPairs b $ dropWhile (<= b) bs, 19 | c <- cs, 20 | let ds = filterPairs c $ dropWhile (<= c) cs, 21 | d <- ds, 22 | let es = filterPairs d $ dropWhile (<= d) ds, 23 | e <- es] 24 | where primes' = takeWhile (< 10000) primes 25 | 26 | main :: IO () 27 | main = print $ sum $ head candidates 28 | -------------------------------------------------------------------------------- /060/question.md: -------------------------------------------------------------------------------- 1 | The primes 3, 7, 109, and 673, are quite remarkable. By taking any two 2 | primes and concatenating them in any order the result will always be 3 | prime. For example, taking 7 and 109, both 7109 and 1097 are prime. The 4 | sum of these four primes, 792, represents the lowest sum for a set of 5 | four primes with this property. 6 | 7 | Find the lowest sum for a set of five primes for which any two primes 8 | concatenate to produce another prime. 9 | 10 | -------------------------------------------------------------------------------- /061/answer.txt: -------------------------------------------------------------------------------- 1 | 28684 2 | -------------------------------------------------------------------------------- /062/answer.txt: -------------------------------------------------------------------------------- 1 | 127035954683 2 | -------------------------------------------------------------------------------- /062/cube-permutations.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from collections import defaultdict 3 | def cube(x): return x**3 4 | 5 | def main(): 6 | cubes = defaultdict(list) 7 | for i in range(10000): 8 | c = cube(i) 9 | digits = ''.join(sorted([d for d in str(c)])) 10 | cubes[digits].append(c) 11 | print(min([min(v) for k, v in list(cubes.items()) if len(v) == 5])) 12 | 13 | if __name__ == "__main__": 14 | main() 15 | -------------------------------------------------------------------------------- /062/cubic-permutations.hs: -------------------------------------------------------------------------------- 1 | import Data.List (sort) 2 | import qualified Data.Map as Map 3 | 4 | cubes :: Map.Map String [Integer] 5 | cubes = Map.fromListWith (++) [(sort (show cube), [cube]) | x <- [1..10000], let cube = x^3] 6 | 7 | main :: IO () 8 | main = print $ minimum [minimum ns | (_, ns) <- Map.toList cubes, length ns == 5] 9 | -------------------------------------------------------------------------------- /062/question.html: -------------------------------------------------------------------------------- 1 |

2 | The cube, $41063625$ ($345^3$), can be permuted to produce two other cubes: $56623104$ ($384^3$) and $66430125$ ($405^3$). 3 | In fact, $41063625$ is the smallest cube which has exactly three permutations of its digits which are also cube. 4 |

5 | 6 |

7 | Find the smallest cube for which exactly five permutations of its digits are cube. 8 |

9 | -------------------------------------------------------------------------------- /063/answer.txt: -------------------------------------------------------------------------------- 1 | 49 2 | -------------------------------------------------------------------------------- /063/n-power.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | print(sum(1 for i in range(1,100) for x in range(1,100) if len(str(i**x)) == x)) 3 | -------------------------------------------------------------------------------- /063/nPower.hs: -------------------------------------------------------------------------------- 1 | main :: IO () 2 | main = print $ sum $ [1 | i <- [1..99], n <- [1..99], length (show (i^n)) == n] 3 | -------------------------------------------------------------------------------- /063/question.html: -------------------------------------------------------------------------------- 1 |

2 | The 5-digit number, $16807=7^5$, is also a fifth power. Similarly, the 9-digit number, $134217728=8^9$, is a ninth power. 3 |

4 | 5 |

6 | How many n-digit positive integers exist which are also an nth power? 7 |

8 | -------------------------------------------------------------------------------- /064/answer.txt: -------------------------------------------------------------------------------- 1 | 1322 2 | -------------------------------------------------------------------------------- /065/answer.txt: -------------------------------------------------------------------------------- 1 | 272 2 | -------------------------------------------------------------------------------- /065/continued.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from itertools import islice 3 | 4 | def take(iterable, n): 5 | return list(islice(iterable, n)) 6 | 7 | def e(): 8 | yield 2 9 | k = 1 10 | while True: 11 | yield 1 12 | yield 2*k 13 | yield 1 14 | k += 1 15 | 16 | def rationalize(frac): 17 | if len(frac) == 0: 18 | return (1, 0) 19 | elif len(frac) == 1: 20 | return (frac[0], 1) 21 | else: 22 | remainder = frac[1:len(frac)] 23 | (num, denom) = rationalize(remainder) 24 | return (frac[0] * num + denom, num) 25 | 26 | numerator = rationalize(take(e(), 100))[0] 27 | print(sum(int(d) for d in str(numerator))) 28 | -------------------------------------------------------------------------------- /065/e-convergents.hs: -------------------------------------------------------------------------------- 1 | convergents :: [Integer] 2 | convergents = 2 : concat [[1, 2*k, 1] | k <- [1..]] 3 | 4 | rationalize :: [Integer] -> (Integer, Integer) 5 | rationalize = foldr (\x (n, d) -> (x*n + d, n)) (1, 0) 6 | 7 | digits :: Integer -> [Integer] 8 | digits 0 = [] 9 | digits n = r : digits q 10 | where (q, r) = quotRem n 10 11 | 12 | main :: IO () 13 | main = print $ sum $ digits $ fst $ rationalize $ take 100 convergents 14 | -------------------------------------------------------------------------------- /066/answer.txt: -------------------------------------------------------------------------------- 1 | 661 2 | -------------------------------------------------------------------------------- /066/question.md: -------------------------------------------------------------------------------- 1 | Consider quadratic Diophantine equations of the form: 2 | 3 | $$ 4 | \begin{aligned} 5 | x^2-Dy^2=1 6 | \end{aligned} 7 | $$ 8 | 9 | For example, when $D=13$, the minimal solution in $x$ is 10 | $6492 - 131802 = 1$. 11 | 12 | It can be assumed that there are no solutions in positive integers when 13 | $D$ is square. 14 | 15 | By finding minimal solutions in $x$ for $D = {2, 3, 5, 6, 7}$, we obtain 16 | the following: 17 | 18 | $$ 19 | \begin{aligned} 20 | 3^2 - 2 \times 2^2 &= 1 \\ 21 | 2^2 - 3 \times 1^2 &= 1 \\ 22 | 9^2 - 5 \times 4^2 &= 1 \\ 23 | 5^2 - 6 \times 2^2 &= 1 \\ 24 | 8^2 - 7 \times 3^2 &= 1 \\ 25 | \end{aligned} 26 | $$ 27 | 28 | Hence, by considering minimal solutions in $x$ for $D \leq 7$, the 29 | largest $x$ is obtained when $D=5$. 30 | 31 | Find the value of $D \leq 1000$ in minimal solutions of $x$ for which 32 | the largest value of $x$ is obtained. 33 | 34 | -------------------------------------------------------------------------------- /067/answer.txt: -------------------------------------------------------------------------------- 1 | 7273 2 | -------------------------------------------------------------------------------- /067/maximum-path-sum.hs: -------------------------------------------------------------------------------- 1 | parse :: String -> [[Integer]] 2 | parse = map (map read . words) . lines 3 | 4 | best :: [Integer] -> [Integer] 5 | best row = map maximum choices where 6 | choices = zipWith (\a b -> a : [b]) row (tail row) 7 | 8 | maxStep :: [Integer] -> [Integer] -> [Integer] 9 | maxStep current next = zipWith (+) next (best current) 10 | 11 | maxPath :: [[Integer]] -> Integer 12 | maxPath [[x]] = x 13 | maxPath (current:next:rest) = maxPath $ (maxStep current next) : rest 14 | 15 | main :: IO () 16 | main = do 17 | str <- readFile "/home/zach/code/euler/067/triangle.txt" 18 | print $ maxPath $ reverse $ parse str 19 | 20 | -------------------------------------------------------------------------------- /067/question.md: -------------------------------------------------------------------------------- 1 | By starting at the top of the triangle below and moving to adjacent 2 | numbers on the row below, the maximum total from top to bottom is 23. 3 | 4 |
   3
 5 |   7 4
 6 |  2 4 6
 7 | 8 5 9 3
 8 | 
9 | 10 | That is, $3 + 7 + 4 + 9 = 23$. 11 | 12 | Find the maximum total from top to bottom in [triangle.txt][] (right 13 | click and 'Save Link/Target As...'), a 15K text file containing a 14 | triangle with one-hundred rows. 15 | 16 | **NOTE:** This is a much more difficult version of Problem 18. It is not 17 | possible to try every route to solve this problem, as there are 2^99^ 18 | altogether! If you could check one trillion ($10^{12}$) routes every 19 | second it would take over twenty billion years to check them all. There 20 | is an efficient algorithm to solve it. ;o) 21 | 22 | [triangle.txt]: https://projecteuler.net/project/resources/p067_triangle.txt 23 | -------------------------------------------------------------------------------- /067/triangle-max.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | 4 | def find_sum(triangle): 5 | def get_options(row, index): 6 | return triangle[row+1][index], triangle[row+1][index+1] 7 | row = len(triangle) - 2 8 | while True: 9 | try: 10 | for index, node in enumerate(triangle[row]): 11 | best = max([node + option for option in get_options(row, index)]) 12 | triangle[row][index] = best 13 | row -= 1 14 | except: 15 | return triangle[0][0] 16 | 17 | def main(): 18 | triangle = [[int(digit) for digit in line.split()] for line in open(os.path.join(os.path.dirname(__file__), 'triangle.txt')).readlines()] 19 | print(find_sum(triangle)) 20 | 21 | if __name__ == "__main__": 22 | main() 23 | -------------------------------------------------------------------------------- /068/answer.txt: -------------------------------------------------------------------------------- 1 | 6531031914842725 2 | -------------------------------------------------------------------------------- /068/magic-5-gon.hs: -------------------------------------------------------------------------------- 1 | fivegon :: Int -> [[[Int]]] 2 | fivegon n = [[[a, b, c], [d, c, e], [f, e, g], [h, g, i], [k, i, b]] 3 | | a <- [1..10], 4 | b <- filter (`notElem` [a]) [1..10], 5 | c <- filter (`notElem` [a, b]) [1..10], 6 | a + b + c == n, 7 | d <- filter (`notElem` [a, b, c]) [a..10], 8 | e <- filter (`notElem` [a, b, c, d]) [1..10], 9 | d + c + e == n, 10 | f <- filter (`notElem` [a, b, c, d, e]) [a..10], 11 | g <- filter (`notElem` [a, b, c, d, e, f]) [1..10], 12 | f + e + g == n, 13 | h <- filter (`notElem` [a, b, c, d, e, f, g]) [a..10], 14 | i <- filter (`notElem` [a, b, c, d, e, f, g, h]) [1..10], 15 | h + g + i == n, 16 | k <- filter (`notElem` [a, b, c, d, e, f, g, h, i]) [a..10], 17 | k + i + b == n] 18 | 19 | main :: IO () 20 | main = putStrLn $ maximum [s | n <- [1..50], gon <- fivegon n, let s = concatMap show $ concat gon, length s == 16] 21 | -------------------------------------------------------------------------------- /069/answer.txt: -------------------------------------------------------------------------------- 1 | 510510 2 | -------------------------------------------------------------------------------- /069/totient.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import math 3 | from operator import mul 4 | from functools import reduce 5 | 6 | def factorize(n): 7 | res = [] 8 | # iterate over all even numbers first. 9 | while n % 2 == 0: 10 | res.append(2) 11 | n //= 2 12 | # try odd numbers up to sqrt(n) 13 | limit = math.sqrt(n+1) 14 | i = 3 15 | while i <= limit: 16 | if n % i == 0: 17 | res.append(i) 18 | n //= i 19 | limit = math.sqrt(n+i) 20 | else: 21 | i += 2 22 | if n != 1: 23 | res.append(n) 24 | return res 25 | 26 | def totient(n): 27 | return n * reduce(mul, [1 - (1.0 / p) for p in set(factorize(n))]) 28 | 29 | def main(): 30 | print(max((n / totient(n), n) for n in range(2, 1000001))[1]) 31 | 32 | if __name__ == "__main__": main() 33 | -------------------------------------------------------------------------------- /069/totient.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'set' 3 | 4 | def factorize(orig) 5 | factors = {} 6 | factors.default = 0 # return 0 instead nil if key not found in hash 7 | n = orig 8 | i = 2 9 | sqi = 4 # square of i 10 | while sqi <= n do 11 | while n.modulo(i) == 0 do 12 | n /= i 13 | factors[i] += 1 14 | end 15 | # we take advantage of the fact that (i +1)**2 = i**2 + 2*i +1 16 | sqi += 2 * i + 1 17 | i += 1 18 | end 19 | 20 | if (n != 1) && (n != orig) 21 | factors[n] += 1 22 | end 23 | factors 24 | end 25 | 26 | def totient(n) 27 | n * factorize(n).each_key.map { |p| 1 - 1.0 / p }.reduce(1, :*) 28 | end 29 | 30 | puts (2..1000000).map { |n| [n / totient(n), n] }.max[1] 31 | -------------------------------------------------------------------------------- /070/answer.txt: -------------------------------------------------------------------------------- 1 | 8319823 2 | -------------------------------------------------------------------------------- /070/question.html: -------------------------------------------------------------------------------- 1 |

2 | Euler's Totient function, $\varphi(n)$ [sometimes called the phi function], is used to determine the number of positive numbers less than or equal to $n$ which are relatively prime to $n$. For example, as 1, 2, 4, 5, 7, and 8, are all less than nine and relatively prime to nine, $\varphi(9)=6$. 3 | The number 1 is considered to be relatively prime to every positive number, so $\varphi(1)=1$. 4 |

5 | 6 |

7 | Interestingly, $\varphi(87109)=79180$, and it can be seen that 87109 is a permutation of 79180. 8 |

9 | 10 |

11 | Find the value of $n$, $1 \lt n \lt 10^7$, for which $\varphi(n)$ is a permutation of $n$ and the ratio $\frac{n}{\varphi(n)}$ produces a minimum. 12 |

13 | -------------------------------------------------------------------------------- /070/totient-permutation.hs: -------------------------------------------------------------------------------- 1 | import Data.List (sort) 2 | 3 | primes :: [Int] 4 | primes = 2 : sieve primes [3,5..] where 5 | sieve (p:ps) xs = h ++ sieve ps [x | x <- t, rem x p /= 0] 6 | where (h, t) = span (< p*p) xs 7 | 8 | permutation :: Int -> Int -> Bool 9 | permutation x y = sort (show x) == sort (show y) 10 | 11 | totient :: Int -> Int -> Int 12 | totient p1 p2 = (p1 - 1) * (p2 - 1) 13 | 14 | candidates :: [(Int, Int)] 15 | candidates = [(n, phi) | p1 <- ps, p2 <- dropWhile (<= p1) ps, let n = p1 * p2, n <= 10000000, let phi = totient p1 p2] 16 | where ps = take 500 primes 17 | 18 | main :: IO () 19 | main = print $ snd $ minimum [(fromIntegral n / fromIntegral phi, n) | (n, phi) <- candidates, permutation n phi] 20 | -------------------------------------------------------------------------------- /070/totient.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from math import sqrt 3 | from operator import mul 4 | from itertools import * 5 | 6 | def primes(n): 7 | if n == 2: 8 | return [2] 9 | elif n < 2: 10 | return [] 11 | sieve = list(range(3, n+1, 2)) 12 | mroot = n ** 0.5 13 | half = (n + 1) // 2 - 1 14 | i = 0 15 | m = 3 16 | while m <= mroot: 17 | if sieve[i]: 18 | j = (m * m - 3) // 2 19 | sieve[j] = 0 20 | while j < half: 21 | sieve[j] = 0 22 | j += m 23 | i = i + 1 24 | m = 2 * i + 3 25 | return [2] + [p for p in sieve if p] 26 | 27 | def main(): 28 | pairs = combinations(primes(2 * int(sqrt(1e7))), 2) 29 | minimum = (100, 0) 30 | for n, t in ((a * b, (a-1) * (b-1)) for a, b in pairs if a * b < 1e7): 31 | ratio = float(n) / t 32 | if ratio < minimum[0] and sorted(str(n)) == sorted(str(t)): 33 | minimum = (ratio, n) 34 | 35 | print(minimum[1]) 36 | 37 | if __name__ == "__main__": main() 38 | -------------------------------------------------------------------------------- /070/totient.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'mathn' 3 | 4 | min = [100, 0] 5 | primes = (1..(2*Math.sqrt(1e7))).select { |n| n.prime? } 6 | primes.combination(2).select { |a, b| a * b < 1e7 }.each do |a, b| 7 | n = a * b 8 | t = (a - 1) * (b - 1) 9 | if n.to_s.split('').sort == t.to_s.split('').sort 10 | if n / t < min[0] 11 | min = [n / t, n] 12 | end 13 | end 14 | end 15 | puts min[1] 16 | -------------------------------------------------------------------------------- /071/answer.txt: -------------------------------------------------------------------------------- 1 | 428570 2 | -------------------------------------------------------------------------------- /071/ordered-fractions.hs: -------------------------------------------------------------------------------- 1 | prevFrac :: Int -> Int -> Int -> (Int, Int) 2 | prevFrac num den limit = inner 1 limit 1 where 3 | inner n d i | i == limit = (n, d) 4 | | den*m < num*i && m*d > n*i = inner m i (i+1) 5 | | otherwise = inner n d (i+1) 6 | where m = num*i `quot` den 7 | 8 | main :: IO () 9 | main = print $ fst $ prevFrac 3 7 1000000 10 | -------------------------------------------------------------------------------- /071/prop-frac.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from fractions import Fraction 3 | 4 | def main(): 5 | three_sevenths = 3.0 / 7 6 | closest = Fraction(three_sevenths).limit_denominator(1000000) 7 | while closest == Fraction(3, 7): 8 | three_sevenths -= 1e-6 9 | closest = Fraction(three_sevenths).limit_denominator(1000000) 10 | print(closest.numerator) 11 | 12 | if __name__ == "__main__": main() 13 | 14 | -------------------------------------------------------------------------------- /071/question.markdown: -------------------------------------------------------------------------------- 1 | Consider the fraction, $\frac{n}{d}$, where $n$ and $d$ are positive 2 | integers. If $n \lt d$ and $\mathrm{HCF}(n,d)=1$, it is called a reduced 3 | proper fraction. 4 | 5 | If we list the set of reduced proper fractions for $d \leq 8$ in 6 | ascending order of size, we get: 7 | 8 | $$\frac{1}{8}, \frac{1}{7}, \frac{1}{6}, \frac{1}{5}, \frac{1}{4}, \frac{2}{7}, \frac{1}{3}, \frac{3}{8}, \frac{2}{5}, \frac{3}{7}, \frac{1}{2}, \frac{4}{7}, \frac{3}{5}, \frac{5}{8}, \frac{2}{3}, \frac{5}{7}, \frac{3}{4}, \frac{4}{5}, \frac{5}{6}, \frac{6}{7}, \frac{7}{8}$$ 9 | 10 | It can be seen that $\frac{2}{5}$ is the fraction immediately to the 11 | left of $\frac{3}{7}$. 12 | 13 | By listing the set of reduced proper fractions for $d \leq 1,000,000$ in 14 | ascending order of size, find the numerator of the fraction immediately 15 | to the left of $\frac{3}{7}$. 16 | -------------------------------------------------------------------------------- /072/answer.txt: -------------------------------------------------------------------------------- 1 | 303963552391 2 | -------------------------------------------------------------------------------- /072/counting-fractions.hs: -------------------------------------------------------------------------------- 1 | farey :: Int -> Int 2 | farey = (map f [0..] !!) where 3 | f n = (n*(n + 3)) `quot` 2 - sum [farey (n `quot` k) | k <- [2..n]] 4 | 5 | main :: IO () 6 | main = print $ farey 1000000 - farey 1 7 | -------------------------------------------------------------------------------- /072/farey.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import math 3 | from operator import mul 4 | from functools import reduce 5 | 6 | def prime_factors(n): 7 | res = set() 8 | # iterate over all even numbers first. 9 | while n % 2 == 0: 10 | res.add(2) 11 | n //= 2 12 | # try odd numbers up to sqrt(n) 13 | limit = math.sqrt(n+1) 14 | i = 3 15 | while i <= limit: 16 | if n % i == 0: 17 | res.add(i) 18 | n //= i 19 | limit = math.sqrt(n+i) 20 | else: 21 | i += 2 22 | if n != 1: 23 | res.add(n) 24 | return res 25 | 26 | def totient(n): 27 | if n == 1: return 1 28 | return int(round(n * reduce(mul, [1 - 1.0 / p for p in prime_factors(n)]))) 29 | 30 | def farey_length(n): 31 | return sum(totient(m) for m in range(1, n+1)) - 1 32 | 33 | def main(): 34 | print(farey_length(1000000)) 35 | 36 | if __name__ == "__main__": main() 37 | -------------------------------------------------------------------------------- /072/question.markdown: -------------------------------------------------------------------------------- 1 | Consider the fraction, $\frac{n}{d}$, where $n$ and $d$ are positive 2 | integers. If $n \lt d$ and $\mathrm{HCF}(n,d)=1$, it is called a reduced 3 | proper fraction. 4 | 5 | If we list the set of reduced proper fractions for $d \leq 8$ in 6 | ascending order of size, we get: 7 | 8 | $$\frac{1}{8}, \frac{1}{7}, \frac{1}{6}, \frac{1}{5}, \frac{1}{4}, \frac{2}{7}, \frac{1}{3}, \frac{3}{8}, \frac{2}{5}, \frac{3}{7}, \frac{1}{2}, \frac{4}{7}, \frac{3}{5}, \frac{5}{8}, \frac{2}{3}, \frac{5}{7}, \frac{3}{4}, \frac{4}{5}, \frac{5}{6}, \frac{6}{7}, \frac{7}{8}$$ 9 | 10 | It can be seen that there are 21 elements in this set. 11 | 12 | How many elements would be contained in the set of reduced proper 13 | fractions for $d \leq 1,000,000$? 14 | -------------------------------------------------------------------------------- /073/answer.txt: -------------------------------------------------------------------------------- 1 | 7295372 2 | -------------------------------------------------------------------------------- /073/fraction-range.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from fractions import gcd 3 | 4 | print(sum(1 for d in range(2, 12001) for n in range(1, d) if (n*3 > d) and (n*2 < d) and gcd(n, d) == 1)) 5 | 6 | -------------------------------------------------------------------------------- /073/question.markdown: -------------------------------------------------------------------------------- 1 | Consider the fraction, $\frac{n}{d}$, where $n$ and $d$ are positive 2 | integers. If $n \lt d$ and $\mathrm{HCF}(n,d)=1$, it is called a reduced 3 | proper fraction. 4 | 5 | If we list the set of reduced proper fractions for $d \leq 8$ in 6 | ascending order of size, we get: 7 | 8 | $$\frac{1}{8}, \frac{1}{7}, \frac{1}{6}, \frac{1}{5}, \frac{1}{4}, \frac{2}{7}, \frac{1}{3}, \frac{3}{8}, \frac{2}{5}, \frac{3}{7}, \frac{1}{2}, \frac{4}{7}, \frac{3}{5}, \frac{5}{8}, \frac{2}{3}, \frac{5}{7}, \frac{3}{4}, \frac{4}{5}, \frac{5}{6}, \frac{6}{7}, \frac{7}{8}$$ 9 | 10 | It can be seen that there are 3 fractions between $\frac{1}{3}$ and 11 | $\frac{1}{2}$. 12 | 13 | How many fractions lie between $\frac{1}{3}$ and $\frac{1}{2}$ in the 14 | sorted set of reduced proper fractions for $d \leq 12,000$? 15 | -------------------------------------------------------------------------------- /074/answer.txt: -------------------------------------------------------------------------------- 1 | 402 2 | -------------------------------------------------------------------------------- /074/factorial-chains.hs: -------------------------------------------------------------------------------- 1 | import qualified Data.Set as Set 2 | 3 | factorial :: Integer -> Integer 4 | factorial n = product [1..n] 5 | 6 | digits :: Integer -> [Integer] 7 | digits 0 = [] 8 | digits n = r : digits q 9 | where (q, r) = quotRem n 10 10 | 11 | next :: Integer -> Integer 12 | next = sum . map factorial . digits 13 | 14 | chain :: Integer -> Integer 15 | chain = inner Set.empty where 16 | inner set x | Set.member x set = 0 17 | | otherwise = 1 + inner (Set.insert x set) (next x) 18 | 19 | main :: IO () 20 | main = print $ length $ filter ((== 60) . chain) [1..1000000] 21 | -------------------------------------------------------------------------------- /074/question.md: -------------------------------------------------------------------------------- 1 | The number 145 is well known for the property that the sum of the 2 | factorial of its digits is equal to 145: 3 | 4 | $$ 5 | \begin{aligned} 6 | 1! + 4! + 5! = 1 + 24 + 120 = 145 7 | \end{aligned} 8 | $$ 9 | 10 | Perhaps less well known is 169, in that it produces the longest chain of 11 | numbers that link back to 169; it turns out that there are only three 12 | such loops that exist: 13 | 14 | $$ 15 | \begin{aligned} 16 | 169 &\to 363601 \to 1454 \to 169 \\ 17 | 871 &\to 45361 \to 871 \\ 18 | 872 &\to 45362 \to 872 19 | \end{aligned} 20 | $$ 21 | 22 | It is not difficult to prove that EVERY starting number will eventually 23 | get stuck in a loop. For example, 24 | 25 | $$ 26 | \begin{aligned} 27 | 69 &\to 363600 \to 1454 \to 169 \to 363601 \, (\to 1454) \\ 28 | 78 &\to 45360 \to 871 \to 45361 \, (\to 871) \\ 29 | 540 &\to 145 \, (\to 145) 30 | \end{aligned} 31 | $$ 32 | 33 | Starting with 69 produces a chain of five non-repeating terms, but the 34 | longest non-repeating chain with a starting number below one million is 35 | sixty terms. 36 | 37 | How many chains, with a starting number below one million, contain 38 | exactly sixty non-repeating terms? 39 | 40 | -------------------------------------------------------------------------------- /075/answer.txt: -------------------------------------------------------------------------------- 1 | 161667 2 | -------------------------------------------------------------------------------- /075/question.md: -------------------------------------------------------------------------------- 1 | It turns out that 12 cm is the smallest length of wire that can be bent 2 | to form an integer sided right angle triangle in exactly one way, but 3 | there are many more examples. 4 | 5 | **12 cm**: (3,4,5) 6 | 7 | **24 cm**: (6,8,10) 8 | 9 | **30 cm**: (5,12,13) 10 | 11 | **36 cm**: (9,12,15) 12 | 13 | **40 cm**: (8,15,17) 14 | 15 | **48 cm**: (12,16,20) 16 | 17 | In contrast, some lengths of wire, like 20 cm, cannot be bent to form an 18 | integer sided right angle triangle, and other lengths allow more than 19 | one solution to be found; for example, using 120 cm it is possible to 20 | form exactly three different integer sided right angle triangles. 21 | 22 | **120 cm**: (30,40,50), (20,48,52), (24,45,51) 23 | 24 | Given that $L$ is the length of the wire, for how many values of 25 | $L \leq 1500000$ can exactly one integer sided right angle triangle be 26 | formed? 27 | 28 | -------------------------------------------------------------------------------- /075/singular-triangles.hs: -------------------------------------------------------------------------------- 1 | import Data.Array 2 | 3 | triples :: Int -> [Int] 4 | triples limit = [a + b + c | u <- [1..l'], v <- [u+1,u+3..l'-u], gcd u v == 1, 5 | let a = v^2 - u^2, let b = 2*u*v, let c = u^2 + v^2] 6 | where l' = round $ sqrt $ fromIntegral limit 7 | 8 | perimeters :: Int -> Array Int Int 9 | perimeters limit = accumArray (+) 0 (1, limit) $ map (\p -> (p, 1)) $ concat [takeWhile (<= limit) $ map (*p) [1..] | p <- triples limit] 10 | 11 | main :: IO () 12 | main = print $ length $ filter (== 1) $ elems $ perimeters 1500000 13 | -------------------------------------------------------------------------------- /076/answer.txt: -------------------------------------------------------------------------------- 1 | 190569291 2 | -------------------------------------------------------------------------------- /076/counting-summations.hs: -------------------------------------------------------------------------------- 1 | import Data.Array 2 | 3 | change :: Integer -> Integer -> Integer 4 | change t c = cache ! (t, c) where 5 | cache = array ((0, 0), (t, c)) [((i, j), f i j) | i <- [0..t], j <- [0..c]] 6 | f _ 1 = 1 7 | f t' c' = sum [cache ! (t' - i*c', c' - 1) | i <- [0..t' `quot` c']] 8 | 9 | main :: IO () 10 | main = print $ change 100 99 11 | -------------------------------------------------------------------------------- /076/partitions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | partitions = {} 4 | def partition(n): 5 | if n < 0: return 0 6 | if n == 0: return 1 7 | if n not in partitions: 8 | # http://mathworld.wolfram.com/PartitionFunctionP.html 9 | partitions[n] = sum([(-1)**(k+1) * (partition(n - (k * (3 * k - 1) // 2)) 10 | + partition(n - (k * (3 * k + 1) // 2))) for k in range(1, n+1)]) 11 | return partitions[n] 12 | 13 | def main(): 14 | print(partition(100) - 1) 15 | 16 | if __name__ == "__main__": main() 17 | -------------------------------------------------------------------------------- /076/question.markdown: -------------------------------------------------------------------------------- 1 | It is possible to write five as a sum in exactly six different ways: 2 | 3 | $$\begin{aligned} 4 | &4 + 1 \\ 5 | &3 + 2 \\ 6 | &3 + 1 + 1 \\ 7 | &2 + 2 + 1 \\ 8 | &2 + 1 + 1 + 1 \\ 9 | &1 + 1 + 1 + 1 + 1 10 | \end{aligned}$$ 11 | 12 | How many different ways can one hundred be written as a sum of at least two positive integers? 13 | -------------------------------------------------------------------------------- /077/answer.txt: -------------------------------------------------------------------------------- 1 | 71 2 | -------------------------------------------------------------------------------- /077/prime-summations.hs: -------------------------------------------------------------------------------- 1 | primes :: [Int] 2 | primes = 2 : sieve primes [3,5..] where 3 | sieve (p:ps) xs = h ++ sieve ps [x | x <- t, rem x p /= 0] 4 | where (h, t) = span (< p*p) xs 5 | 6 | primePartition :: Int -> Int 7 | primePartition = p primes where 8 | p _ 0 = 1 9 | p ks'@(k:ks) m = if m < k then 0 else p ks' (m - k) + p ks m 10 | 11 | main :: IO () 12 | main = print $ fst $ head $ dropWhile ((<= 5000) . snd) [(n, primePartition n) | n <- [1..]] 13 | -------------------------------------------------------------------------------- /077/question.md: -------------------------------------------------------------------------------- 1 | It is possible to write ten as the sum of primes in exactly five 2 | different ways: 3 | 4 | $$ 5 | \begin{aligned} 6 | &7 + 3 \\ 7 | &5 + 5 \\ 8 | &5 + 3 + 2 \\ 9 | &3 + 3 + 2 + 2 \\ 10 | &2 + 2 + 2 + 2 + 2 11 | \end{aligned} 12 | $$ 13 | 14 | What is the first value which can be written as the sum of primes in 15 | over five thousand different ways? 16 | 17 | -------------------------------------------------------------------------------- /078/answer.txt: -------------------------------------------------------------------------------- 1 | 55374 2 | -------------------------------------------------------------------------------- /078/coin-partitions.hs: -------------------------------------------------------------------------------- 1 | import Data.Array 2 | import Data.List (sort) 3 | 4 | pentagonals :: [Integer] 5 | pentagonals = sort [n*(3*n - 1) `quot` 2 | n <- [-250..250], n /= 0] 6 | 7 | cache :: Array Integer Integer 8 | cache = array (0, 100000) [(x, partition x) | x <- [0..100000]] 9 | 10 | partition :: Integer -> Integer 11 | partition n | n <= 1 = 1 12 | | otherwise = sum [s * (cache ! (n - p)) | (s, p) <- zip (cycle [1, 1, -1, -1]) (takeWhile (<= n) pentagonals)] 13 | 14 | main :: IO () 15 | main = print $ head [i | (i, p) <- assocs cache, p `rem` 1000000 == 0] 16 | -------------------------------------------------------------------------------- /078/partitions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from itertools import * 3 | 4 | def pentagonal(n): 5 | return n*(3*n - 1) / 2 6 | 7 | partitions = {} 8 | generalized_pentagonals = sorted(map(pentagonal, list(range(-250, 250))))[1:] 9 | def partition(n): 10 | if n <= 1: return 1 11 | if n not in partitions: 12 | signs = cycle([1, 1, -1, -1]) 13 | pentagonals = takewhile(lambda p: p <= n, generalized_pentagonals) 14 | partitions[n] = sum(sign * partition(n - p) for sign, p in zip(signs, pentagonals)) 15 | 16 | return partitions[n] 17 | 18 | def main(): 19 | print(next((n for n in count(0) if partition(n) % 1000000 == 0))) 20 | 21 | if __name__ == "__main__": main() 22 | -------------------------------------------------------------------------------- /078/question.html: -------------------------------------------------------------------------------- 1 |

Let p(n) represent the number of different ways in which n coins can be separated into piles. For example, five coins can separated into piles in exactly seven different ways, so p(5)=7.

2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
OOOOO
OOOO   O
OOO   OO
OOO   O   O
OO   OO   O
OO   O   O   O
O   O   O   O   O
25 |

Find the least value of n for which p(n) is divisible by one million.

26 | 27 | -------------------------------------------------------------------------------- /079/answer.txt: -------------------------------------------------------------------------------- 1 | 73162890 2 | -------------------------------------------------------------------------------- /079/commentary.markdown: -------------------------------------------------------------------------------- 1 | I used a statistical approach to solve this problem. 2 | Essentially, these are the steps I used: 3 | 4 | 1. For each successful login attempt in the file, make a note of the characters and their position. For example, if the attempt is '319', we would note that '3' is at position 0, '1' is at position 1, and '9' is at position 2. These results are stored in a dictionary of lists, where the keys are the characters and the values are a list of all positions where that character is found. 5 | 2. Next, we calculate the average position of each character. To do this we simply divide the sum of the character's positions by the number of times the character appeared. 6 | 3. Then, we sort the dictionary by value, so that characters with a smaller average position appear before those with a greater average position. 7 | 4. Finally, we concatenate the sorted characters and return this as the result. 8 | -------------------------------------------------------------------------------- /079/keylog.txt: -------------------------------------------------------------------------------- 1 | 319 2 | 680 3 | 180 4 | 690 5 | 129 6 | 620 7 | 762 8 | 689 9 | 762 10 | 318 11 | 368 12 | 710 13 | 720 14 | 710 15 | 629 16 | 168 17 | 160 18 | 689 19 | 716 20 | 731 21 | 736 22 | 729 23 | 316 24 | 729 25 | 729 26 | 710 27 | 769 28 | 290 29 | 719 30 | 680 31 | 318 32 | 389 33 | 162 34 | 289 35 | 162 36 | 718 37 | 729 38 | 319 39 | 790 40 | 680 41 | 890 42 | 362 43 | 319 44 | 760 45 | 316 46 | 729 47 | 380 48 | 319 49 | 728 50 | 716 51 | -------------------------------------------------------------------------------- /079/passcode-derivation.hs: -------------------------------------------------------------------------------- 1 | import Data.List (nub) 2 | 3 | crack :: [String] -> String 4 | crack [] = [] 5 | crack xs = first : crack rest where 6 | heads = map head xs 7 | reject = nub $ map (!! 1) $ filter ((> 1) . length) xs 8 | first = head $ nub $ filter (`notElem` reject) heads 9 | rest = filter ((> 0) . length) $ map (\ys'@(y:ys) -> if y == first then ys else ys') xs 10 | 11 | main :: IO () 12 | main = do 13 | str <- readFile "/home/zach/code/euler/079/keylog.txt" 14 | let attempts = lines str 15 | putStrLn $ crack attempts 16 | -------------------------------------------------------------------------------- /079/password-crack.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | from itertools import * 4 | from collections import defaultdict 5 | 6 | def main(): 7 | attempts = [line.strip() for line in open(os.path.join(os.path.dirname(__file__), 'keylog.txt')).readlines()] 8 | appearances = defaultdict(list) 9 | for attempt in attempts: 10 | for i, n in enumerate(attempt): 11 | appearances[n].append(i) 12 | 13 | average_positions = {} 14 | for k,v in list(appearances.items()): 15 | average_positions[k] = float(sum(v))/float(len(v)) 16 | 17 | a = [k for k,v in sorted(list(average_positions.items()), key=lambda a: a[1])] 18 | print(''.join(str(x) for x in a)) 19 | 20 | if __name__ == "__main__": 21 | main() 22 | -------------------------------------------------------------------------------- /079/question.markdown: -------------------------------------------------------------------------------- 1 | A common security method used for online banking is to ask the user for three random characters from a passcode. For example, if the passcode was 531278, they may ask for the 2nd, 3rd, and 5th characters; the expected reply would be: 317. 2 | 3 | The text file, [keylog.txt](https://projecteuler.net/project/resources/p079_keylog.txt), contains fifty successful login attempts. 4 | 5 | Given that the three characters are always asked for in order, analyse the file so as to determine the shortest possible secret passcode of unknown length. 6 | 7 | -------------------------------------------------------------------------------- /080/answer.txt: -------------------------------------------------------------------------------- 1 | 40886 2 | -------------------------------------------------------------------------------- /080/question.md: -------------------------------------------------------------------------------- 1 | It is well known that if the square root of a natural number is not an 2 | integer, then it is irrational. The decimal expansion of such square 3 | roots is infinite without any repeating pattern at all. 4 | 5 | The square root of two is 1.41421356237309504880..., and the digital sum 6 | of the first one hundred decimal digits is 475. 7 | 8 | For the first one hundred natural numbers, find the total of the digital 9 | sums of the first one hundred decimal digits for all the irrational 10 | square roots. 11 | -------------------------------------------------------------------------------- /080/root-expansion.hs: -------------------------------------------------------------------------------- 1 | isqrt :: Integer -> Integer 2 | isqrt 0 = 0 3 | isqrt 1 = 1 4 | isqrt n = head $ dropWhile (\x -> x*x > n) $ iterate (\x -> (x + n `div` x) `div` 2) (n `div` 2) 5 | 6 | digits :: Integer -> [Integer] 7 | digits = map (read . return) . show 8 | 9 | sqrtDigits :: Integer -> Integer -> [Integer] 10 | sqrtDigits count x = digits $ isqrt $ x*(10^(2*count)) 11 | 12 | isSquare :: Integer -> Bool 13 | isSquare n = root * root == n 14 | where root = round $ sqrt $ fromIntegral n 15 | 16 | main :: IO () 17 | main = print $ sum $ concat [ds | n <- [1..99], not $ isSquare n, let ds = sqrtDigits 99 n] 18 | -------------------------------------------------------------------------------- /081/answer.txt: -------------------------------------------------------------------------------- 1 | 427337 2 | -------------------------------------------------------------------------------- /082/answer.txt: -------------------------------------------------------------------------------- 1 | 260324 2 | -------------------------------------------------------------------------------- /083/answer.txt: -------------------------------------------------------------------------------- 1 | 425185 2 | -------------------------------------------------------------------------------- /084/answer.txt: -------------------------------------------------------------------------------- 1 | 101524 2 | -------------------------------------------------------------------------------- /085/answer.txt: -------------------------------------------------------------------------------- 1 | 2772 2 | -------------------------------------------------------------------------------- /085/question.html: -------------------------------------------------------------------------------- 1 |

By counting carefully it can be seen that a rectangular grid measuring 3 by 2 contains eighteen rectangles:

2 |
3 | 4 |
5 |

Although there exists no rectangular grid that contains exactly two million rectangles, find the area of the grid with the nearest solution.

6 | -------------------------------------------------------------------------------- /085/rectangles.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from operator import mul 3 | 4 | def pack(w, h): 5 | return (w + 1) * (h + 1) * (w * h) / 4 6 | 7 | def f(x, y): 8 | return abs(pack(x, y) - 2000000) 9 | 10 | def main(): 11 | candidates = ((x, y) for x in range(1000) for y in range(1000)) 12 | print((mul(*min((f(*pair), pair) for pair in candidates)[1]))) 13 | 14 | if __name__ == "__main__": main() 15 | -------------------------------------------------------------------------------- /086/answer.txt: -------------------------------------------------------------------------------- 1 | 1818 2 | -------------------------------------------------------------------------------- /086/cuboid.hs: -------------------------------------------------------------------------------- 1 | isSquare :: Int -> Bool 2 | isSquare x = let x' = truncate $ sqrt (fromIntegral x :: Double) in x'*x' == x 3 | 4 | solutions :: Int -> Int 5 | solutions m = length [1 | a <- [1..m], b <- [a..m], isSquare((a + b)^2 + m^2)] 6 | 7 | main :: IO () 8 | main = print $ length $ takeWhile (<= 1000000) $ scanl1 (+) $ map solutions [0..] 9 | -------------------------------------------------------------------------------- /086/cuboid.py.wip: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from itertools import combinations_with_replacement 3 | from gmpy import is_square 4 | 5 | def integer_path(l, w, h): 6 | return is_square(min([((l + w)**2 + h**2), (w**2 + (l + h)**2), (l**2 + (h + w)**2)])) 7 | 8 | def solutions(m): 9 | return [dimensions for dimensions in combinations_with_replacement(range(1, m + 1), 3) if integer_path(*dimensions)] 10 | 11 | def main(): 12 | m = 1 13 | while len(solutions(m)) < 10000: 14 | m += 1 15 | print(m - 1) 16 | 17 | if __name__ == "__main__": main() 18 | -------------------------------------------------------------------------------- /086/question.html: -------------------------------------------------------------------------------- 1 |

A spider, S, sits in one corner of a cuboid room, measuring 6 by 5 by 3, and a fly, F, sits in the opposite corner. By travelling on the surfaces of the room the shortest "straight line" distance from S to F is 10 and the path is shown on the diagram.

2 |
3 |
4 |
5 |

However, there are up to three "shortest" path candidates for any given cuboid and the shortest route doesn't always have integer length.

6 |

It can be shown that there are exactly 2060 distinct cuboids, ignoring rotations, with integer dimensions, up to a maximum size of M by M by M, for which the shortest route has integer length when M = 100. This is the least value of M for which the number of solutions first exceeds two thousand; the number of solutions when M = 99 is 1975.

7 |

Find the least value of M such that the number of solutions first exceeds one million.

8 | -------------------------------------------------------------------------------- /087/answer.txt: -------------------------------------------------------------------------------- 1 | 1097343 2 | -------------------------------------------------------------------------------- /087/question.html: -------------------------------------------------------------------------------- 1 |

The smallest number expressible as the sum of a prime square, prime cube, and prime fourth power is 28. In fact, there are exactly four numbers below fifty that can be expressed in such a way:

2 |

28 = 22 + 23 + 24
3 | 33 = 32 + 23 + 24
4 | 49 = 52 + 23 + 24
5 | 47 = 22 + 33 + 24

6 |

How many numbers below fifty million can be expressed as the sum of a prime square, prime cube, and prime fourth power?

7 | -------------------------------------------------------------------------------- /087/triples.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from itertools import product, takewhile 3 | 4 | def euler(n): 5 | # Create a candidate list within which non-primes will 6 | # marked as None, noting that only candidates below 7 | # sqrt(n) need be checked. 8 | candidates = list(range(n+1)) 9 | fin = int(n**0.5) 10 | 11 | # Loop over the candidates, marking out each multiple. 12 | # If the current candidate is already checked off then 13 | # continue to the next iteration. 14 | for i in range(2, fin+1): 15 | if not candidates[i]: 16 | continue 17 | 18 | candidates[2*i::i] = [None] * (n//i - 1) 19 | 20 | # Filter out non-primes and return the list. 21 | return [i for i in candidates[2:] if i] 22 | 23 | def main(): 24 | limit = 50000000 25 | primes = euler(int(limit**0.5)) 26 | squares = takewhile(lambda x: x < limit, (prime**2 for prime in primes)) 27 | cubes = takewhile(lambda x: x < limit, (prime**3 for prime in primes)) 28 | tesseracts = takewhile(lambda x: x < limit, (prime**4 for prime in primes)) 29 | print((len(set(s + c + t for (s, c, t) in product(squares, cubes, tesseracts) if s + c + t < limit)))) 30 | 31 | if __name__ == "__main__": main() 32 | -------------------------------------------------------------------------------- /088/product_sum.py.wip: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from itertools import combinations_with_replacement 3 | from functools import reduce 4 | from operator import mul 5 | 6 | def product(iterable): 7 | return reduce(mul, iterable) 8 | 9 | def candidates(k): 10 | return combinations_with_replacement(range(1, k + 1), k) 11 | 12 | def minimal(k): 13 | twice = 2 * k 14 | for c in candidates(k): 15 | s = sum(c) 16 | if s >= twice: 17 | continue 18 | p = product(c) 19 | if s == p: 20 | return s 21 | return twice 22 | 23 | def main(): 24 | result = set(map(minimal, range(2, 30))) 25 | print(result) 26 | 27 | if __name__ == "__main__": 28 | main() 29 | -------------------------------------------------------------------------------- /088/question.md: -------------------------------------------------------------------------------- 1 | A natural number, N, that can be written as the sum and product of a 2 | given set of at least two natural numbers, {a1, a2, ... , ak} is called 3 | a product-sum number: N = a1 + a2 + ... + ak = a1 × a2 × ... × ak. 4 | 5 | For example, 6 = 1 + 2 + 3 = 1 × 2 × 3. 6 | 7 | For a given set of size, k, we shall call the smallest N with this 8 | property a minimal product-sum number. The minimal product-sum numbers 9 | for sets of size, k = 2, 3, 4, 5, and 6 are as follows. 10 | 11 | k=2: 4 = 2 × 2 = 2 + 2 12 | k=3: 6 = 1 × 2 × 3 = 1 + 2 + 3 13 | k=4: 8 = 1 × 1 × 2 × 4 = 1 + 1 + 2 + 4 14 | k=5: 8 = 1 × 1 × 2 × 2 × 2 = 1 + 1 + 2 + 2 + 2 15 | k=6: 12 = 1 × 1 × 1 × 1 × 2 × 6 = 1 + 1 + 1 + 1 + 2 + 6 16 | 17 | Hence for 2≤k≤6, the sum of all the minimal product-sum numbers is 18 | 4+6+8+12 = 30; note that 8 is only counted once in the sum. 19 | 20 | In fact, as the complete set of minimal product-sum numbers for 2≤k≤12 21 | is {4, 6, 8, 12, 15, 16}, the sum is 61. 22 | 23 | What is the sum of all the minimal product-sum numbers for 2≤k≤12000? 24 | -------------------------------------------------------------------------------- /089/answer.txt: -------------------------------------------------------------------------------- 1 | 743 2 | -------------------------------------------------------------------------------- /089/minimal.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | 4 | def subtractive(roman): 5 | result = roman 6 | replacements = [ 7 | ("VIIII", "IX"), 8 | ("IIII", "IV"), 9 | ("LXXXX", "XC"), 10 | ("XXXX", "XL"), 11 | ("DCCCC", "CM"), 12 | ("CCCC", "CD"), 13 | ] 14 | for old, new in replacements: 15 | result = result.replace(old, new) 16 | return result 17 | 18 | current = 0 19 | improved = 0 20 | for line in open(os.path.join(os.path.dirname(__file__), 'roman.txt')): 21 | roman = line.strip() 22 | current += len(roman) 23 | improved += len(subtractive(roman)) 24 | print(current - improved) 25 | -------------------------------------------------------------------------------- /092/answer.txt: -------------------------------------------------------------------------------- 1 | 8581146 2 | -------------------------------------------------------------------------------- /092/question.markdown: -------------------------------------------------------------------------------- 1 | A number chain is created by continuously adding the square of the 2 | digits in a number to form a new number until it has been seen before. 3 | 4 | For example, 5 | 6 | $$\begin{aligned} 7 | & 44 \rightarrow 32 \rightarrow 13 \rightarrow 10 \rightarrow 1 \rightarrow 1 \\ 8 | & 85 \rightarrow 89 \rightarrow 145 \rightarrow 42 \rightarrow 20 \rightarrow 4 \rightarrow 16 \rightarrow 37 \rightarrow 58 \rightarrow 89 9 | \end{aligned}$$ 10 | 11 | Therefore any chain that arrives at 1 or 89 will become stuck in an 12 | endless loop. What is most amazing is that EVERY starting number will 13 | eventually arrive at 1 or 89. 14 | 15 | How many starting numbers below ten million will arrive at 89? 16 | -------------------------------------------------------------------------------- /096/answer.txt: -------------------------------------------------------------------------------- 1 | 24702 2 | -------------------------------------------------------------------------------- /097/answer.txt: -------------------------------------------------------------------------------- 1 | 8739992577 2 | -------------------------------------------------------------------------------- /097/commentary.markdown: -------------------------------------------------------------------------------- 1 | The `gmpy` library makes this problem trivial. Using `gmpy`, this code 2 | takes about half a second to run. Without `gmpy`, well, let's just say 3 | it takes considerably more than a minute to run. 4 | 5 | If you're dealing with large numbers in Python, I highly recommend `gmpy`. 6 | -------------------------------------------------------------------------------- /097/non-mersenne.go.wip: -------------------------------------------------------------------------------- 1 | package main 2 | import "fmt" 3 | import "math/big" 4 | 5 | func main() { 6 | a := big.NewInt(28433*2) 7 | b := big.NewInt(7830457) 8 | x := big.NewInt(0).Add(big.NewInt(1), big.NewInt(0).Exp(a, b, nil)) 9 | fmt.Println(x) 10 | //s := fmt.Sprintf("%d", x) 11 | //fmt.Println(s[-10:]) 12 | } 13 | 14 | -------------------------------------------------------------------------------- /097/non-mersenne.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from gmpy2 import mpz 3 | print(str(mpz(28433*2**7830457+1))[-10:]) 4 | -------------------------------------------------------------------------------- /097/question.html: -------------------------------------------------------------------------------- 1 |

2 | The first known prime found to exceed one million digits 3 | was discovered in 1999, and is a Mersenne prime of the 4 | form $2^{6972593}-1$; it contains exactly $2,098,960$ 5 | digits. Subsequently other Mersenne primes, of the form 6 | $2^p-1$, have been found which contain more digits. 7 |

8 | 9 |

10 | However, in 2004 there was found a massive non-Mersenne 11 | prime which contains $2,357,207$ digits: $28433\times2^{7830457}+1$. 12 |

13 | 14 |

15 | Find the last ten digits of this prime number. 16 |

17 | -------------------------------------------------------------------------------- /099/answer.txt: -------------------------------------------------------------------------------- 1 | 709 2 | -------------------------------------------------------------------------------- /099/commentary.html: -------------------------------------------------------------------------------- 1 |

2 | As the question notes, it would be difficult to evaluate these exponents directly as they contain 3 | over three million digits each. Therefore, we must find a way to reduce these exponents to a 4 | manageable size. 5 |

6 | 7 |

8 | To do so, we use the identity $\log{a^x} = x \times \log{a}$. Since $\log{b} \gt \log{a}$ if $ b \gt a$, 9 | this will serve as an approximation of calculating the exponents directly. 10 |

11 | 12 | -------------------------------------------------------------------------------- /099/largest-exponent.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | from math import log10 4 | largest = [0, 0] 5 | for i, line in enumerate(open(os.path.join(os.path.dirname(__file__), 'base_exp.txt'))): 6 | a, x = list(map(int, line.split(','))) 7 | if x * log10(a) > largest[0]: 8 | largest = [x * log10(a), i+1] 9 | print(largest[1]) 10 | -------------------------------------------------------------------------------- /099/question.html: -------------------------------------------------------------------------------- 1 |

2 | Comparing two numbers written in index form like $2^{11}$ and $3^7$ is not difficult, as any calculator would confirm that $2^{11} = 2048 \lt 3^7 = 2187$. 3 |

4 | 5 |

6 | However, confirming that $632382^{518061} \gt 519432^{525806}$ would be much more difficult, as both numbers contain over three million digits. 7 |

8 | 9 |

10 | Using base_exp.txt (right click and 'Save Link/Target As...'), a 22K text file containing one thousand lines with a base/exponent pair on each line, determine which line number has the greatest numerical value. 11 |

12 | 13 |

14 | NOTE: The first two lines in the file represent the numbers in the example given above. 15 |

16 | -------------------------------------------------------------------------------- /112/answer.txt: -------------------------------------------------------------------------------- 1 | 1587000 2 | -------------------------------------------------------------------------------- /112/bouncy.hs: -------------------------------------------------------------------------------- 1 | import Data.List (sort, find) 2 | 3 | isIncreasing :: Integer -> Bool 4 | isIncreasing n = show n == sort (show n) 5 | 6 | isDecreasing :: Integer -> Bool 7 | isDecreasing n = show n == reverse (sort (show n)) 8 | 9 | isBouncy :: Integer -> Bool 10 | isBouncy n = not (isIncreasing n) && not (isDecreasing n) 11 | 12 | bouncy :: [(Integer, Integer)] 13 | bouncy = b' 1 0 where 14 | b' n acc | isBouncy n = (n, acc+1) : b' (n+1) (acc+1) 15 | | otherwise = (n, acc) : b' (n+1) acc 16 | 17 | main :: IO () 18 | main = print $ maybe 0 fst $ find (\(n, b) -> (n * 99) == (b * 100)) bouncy 19 | -------------------------------------------------------------------------------- /112/bouncy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from itertools import * 3 | 4 | def pairwise(iterable): 5 | "s -> (s0,s1), (s1,s2), (s2, s3), ..." 6 | a, b = tee(iterable) 7 | next(b, None) 8 | return zip(a, b) 9 | 10 | def digits(n): 11 | return list(map(int, str(n))) 12 | 13 | def is_increasing(n): 14 | return all(prev <= curr for prev, curr in pairwise(digits(n))) 15 | 16 | def is_decreasing(n): 17 | return all(prev >= curr for prev, curr in pairwise(digits(n))) 18 | 19 | def is_bouncy(n): 20 | return not is_increasing(n) and not is_decreasing(n) 21 | 22 | def running_total(iterable): 23 | total = 0 24 | for element in iterable: 25 | total += element 26 | yield total 27 | 28 | def main(): 29 | nums = count(1) 30 | bouncy = running_total(map(lambda n: float(is_bouncy(n)), count(1))) 31 | print(next((n for n, b in zip(nums, bouncy) if b / n == 0.99))) 32 | 33 | if __name__ == "__main__": main() 34 | -------------------------------------------------------------------------------- /112/question.markdown: -------------------------------------------------------------------------------- 1 | Working from left-to-right if no digit is exceeded by the digit to its 2 | left it is called an increasing number; for example, 134468. 3 | 4 | Similarly if no digit is exceeded by the digit to its right it is called 5 | a decreasing number; for example, 66420. 6 | 7 | We shall call a positive integer that is neither increasing nor 8 | decreasing a "bouncy" number; for example, 155349. 9 | 10 | Clearly there cannot be any bouncy numbers below one-hundred, but just 11 | over half of the numbers below one-thousand (525) are bouncy. In fact, 12 | the least number for which the proportion of bouncy numbers first 13 | reaches 50% is 538. 14 | 15 | Surprisingly, bouncy numbers become more and more common and by the time 16 | we reach 21780 the proportion of bouncy numbers is equal to 90%. 17 | 18 | Find the least number for which the proportion of bouncy numbers is 19 | exactly 99%. 20 | -------------------------------------------------------------------------------- /206/answer.txt: -------------------------------------------------------------------------------- 1 | 1389019170 2 | -------------------------------------------------------------------------------- /206/concealed.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | def is_concealed(n): 4 | digits = str(n) 5 | template = "1_2_3_4_5_6_7_8_9_0" 6 | 7 | if len(digits) != len(template): 8 | return False 9 | 10 | return all(digits[i] == template[i] for i in range(0, len(digits), 2)) 11 | 12 | def main(): 13 | print(next((n for n in range(1000000000, 1390000000, 10) 14 | if (n % 100 == 30 or n % 100 == 70) and is_concealed(n*n)))) 15 | 16 | if __name__ == "__main__": main() 17 | -------------------------------------------------------------------------------- /206/question.markdown: -------------------------------------------------------------------------------- 1 | Find the unique positive integer whose square has the form 1\_2\_3\_4\_5\_6\_7\_8\_9\_0, 2 | where each "\_" is a single digit. 3 | -------------------------------------------------------------------------------- /243/answer.txt: -------------------------------------------------------------------------------- 1 | 892371480 2 | -------------------------------------------------------------------------------- /243/question.markdown: -------------------------------------------------------------------------------- 1 | A positive fraction whose numerator is less than its denominator is called a proper fraction. 2 | 3 | For any denominator, $d$, there will be $d - 1$ proper fractions; for example, with $d = 12$: 4 | 5 | $$\frac{1}{12}, \frac{2}{12}, \frac{3}{12}, \frac{4}{12}, \frac{5}{12}, \frac{6}{12}, \frac{7}{12}, \frac{8}{12}, \frac{9}{12}, \frac{10}{12}, \frac{11}{12}.$$ 6 | 7 | We shall call a fraction that cannot be cancelled down a resilient fraction. 8 | 9 | Furthermore we shall define the resilience of a denominator, $R(d)$, to be the ratio of its proper fractions that are resilient; for example, $R(12) = \frac{4}{11}$. 10 | 11 | In fact, $d = 12$ is the smallest denominator having a resilience $R(d) < \frac{4}{10}$. 12 | 13 | Find the smallest denominator $d$, having a resilience $R(d) < \frac{15499}{94744}$. 14 | -------------------------------------------------------------------------------- /379/summatory.py.wip: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import math 3 | from itertools import * 4 | from operator import mul 5 | 6 | def gcd(a, b): 7 | if b == 0: return a 8 | return gcd(b, a % b) 9 | 10 | def lcm(a, b): 11 | return (a / gcd(a, b)) * b 12 | 13 | def factorize(n): 14 | res = [] 15 | # iterate over all even numbers first. 16 | while n % 2 == 0: 17 | res.append(2) 18 | n //= 2 19 | # try odd numbers up to sqrt(n) 20 | limit = math.sqrt(n+1) 21 | i = 3 22 | while i <= limit: 23 | if n % i == 0: 24 | res.append(i) 25 | n //= i 26 | limit = math.sqrt(n+i) 27 | else: 28 | i += 2 29 | if n != 1: 30 | res.append(n) 31 | return res 32 | 33 | def f(n): 34 | s = 0 35 | for y in range(1, n + 1): 36 | for x in range(1, y + 1): 37 | if lcm(x, y) == n: 38 | s += 1 39 | return s 40 | 41 | def g(n): 42 | return sum(f(i) for i in range(1, n + 1)) 43 | 44 | print g(100) 45 | -------------------------------------------------------------------------------- /379/summatory.rb.wip: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'prime' 3 | 4 | def f(n) 5 | 3 ** n.prime_division.length 6 | end 7 | 8 | def g(n) 9 | (1..n).map { |i| f(i) }.reduce(:+) 10 | end 11 | 12 | puts g(100000) 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Zach Denton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Python and Clojure solutions to Project Euler problems. 2 | 3 | http://zacharydenton.com/project-euler-solutions/ 4 | --------------------------------------------------------------------------------