Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Solved firest 10 problems

  • Loading branch information...
commit 6241c3ea6f60db044452e8e5ceabd3e236e904ba 0 parents
Andrey Paramonov authored
52 mymath.erl
@@ -0,0 +1,52 @@
+-module(mymath).
+-export([primes_upto/1]).
+-include_lib("eunit/include/eunit.hrl").
+
+%% Find all prime numbers upto specified value.
+%%
+primes_upto(N) -> eratosthenes(math:sqrt(N), lists:seq(2, N)).
+
+
+%% Functional implementation of Eratosthenes sieve algorithm
+%% http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
+%%
+%% Very clean but very slow. Works relatively fast for N < 100,000
+%%
+eratosthenes_sieve([]) -> [];
+eratosthenes_sieve([P|Xs]) -> [P | eratosthenes_sieve([X || X <- Xs, X rem P > 0])].
+
+
+%% Functional implementation of Euler sieve algorithm
+%%
+%% Very clean but very slow. Works relatively fast for N < 10,000
+%%
+euler_sieve([]) -> [];
+euler_sieve([P|Xs]) -> [P | euler_sieve(Xs -- lists:map(fun(X) -> X*P end, [P|Xs]))].
+
+
+%% Recursion implementation of Eratosthenes sieve algorithm
+%% Author: Zac Brown
+%%
+%% Not so obvious but very efficient
+%%
+eratosthenes(Max, [H|T]) when H =< Max -> [H | eratosthenes(Max, sieve([H|T], H))];
+eratosthenes(_Max, L) -> L.
+
+sieve([H|T], N) when H rem N =/= 0 -> [H | sieve(T, N)];
+sieve([_H|T], N) -> sieve(T, N);
+sieve([], _N) -> [].
+
+%% Tests
+
+primes_upto_30_test() ->
+ ?assertEqual([2, 3, 5, 7, 11, 13, 17, 19, 23, 29], primes_upto(30)).
+
+primes_upto_2m_test() ->
+ ?assertEqual(1999993, lists:last(primes_upto(2000000))).
+
+
+euler_sieve_test() ->
+ ?assertEqual([2, 3, 5, 7, 11, 13, 17, 19, 23, 29], euler_sieve(lists:seq(2, 30))).
+
+eratosthenes_sieve_test() ->
+ ?assertEqual([2, 3, 5, 7, 11, 13, 17, 19, 23, 29], eratosthenes_sieve(lists:seq(2, 30))).
22 p001.erl
@@ -0,0 +1,22 @@
+%% Problem
+%% ---------------------
+%% If we list all the natural numbers below 10 that are multiples of 3 or 5,
+%% we get 3, 5, 6 and 9. The sum of these multiples is 23.
+%%
+%% Find the sum of all the multiples of 3 or 5 below 1000.
+%% ---------------------
+
+-module(p001).
+-include_lib("eunit/include/eunit.hrl").
+
+multiples35(N) ->
+ [X || X <- lists:seq(1, N), (X rem 3 =:= 0) or (X rem 5 =:= 0)].
+
+multiples35_test() ->
+ ?assertEqual(466, length(multiples35(999))).
+
+result() ->
+ lists:sum(multiples35(999)).
+
+result_test() ->
+ ?assertEqual(233168, result()).
60 p002.erl
@@ -0,0 +1,60 @@
+%% Problem
+%% ---------------------
+%% Each new term in the Fibonacci sequence is generated by adding the previous two terms.
+%% By starting with 1 and 2, the first 10 terms will be:
+%% 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
+%%
+%% Find the sum of all the even-valued terms in the sequence which do not exceed four million.
+%% ---------------------
+
+-module(p002).
+-include_lib("eunit/include/eunit.hrl").
+
+%% Solution
+%% ---------------------
+%% Streight forward
+%% ---------------------
+
+fib(Max) ->
+ fib(1, 1, Max).
+
+fib(Fst, Snd, Max) ->
+ fib(Fst, Snd, Max, 0).
+
+fib(_Fst, Snd, Max, Acc) when Snd > Max ->
+ Acc;
+fib(Fst, Snd, Max, Acc) when Snd rem 2 =:= 0 ->
+ fib(Snd, Fst+Snd, Max, Acc+Snd);
+fib(Fst, Snd, Max, Acc) ->
+ fib(Snd, Fst+Snd, Max, Acc).
+
+fib_test() ->
+ ?assertEqual(4613732, fib(4000000)).
+
+%% Solution
+%% ---------------------
+%% Found on Euler forum
+%% ---------------------
+
+fse(Max) -> fse({1, 1}, Max, 0).
+
+fse({P1, P2}, Max, T) when (P1 + P2) < Max ->
+ fse({P1 + 2 * P2, 2 * P1 + 3 * P2}, Max, T + P1 + P2);
+fse({P1, P2}, Max, T) when (P1 + P2) >= Max -> T.
+
+fse_test() ->
+ ?assertEqual(4613732, fse(4000000)).
+
+%% Solution
+%% ---------------------
+%% 2 8 34 144...
+%% E(n) = 4*E(n-1) + E(n-2)
+%% ---------------------
+
+f(M) -> f(2, 8, M, 10).
+
+f(A, B, Max, R) when A + 4*B > Max -> R;
+f(A, B, Max, R) -> f(B, A + 4*B, Max, R + A + 4*B).
+
+f_test() ->
+ ?assertEqual(4613732, f(4000000)).
47 p003.erl
@@ -0,0 +1,47 @@
+%% Problem
+%% ---------------------
+%% The prime factors of 13195 are 5, 7, 13 and 29.
+%% What is the largest prime factor of the number 600851475143?
+%% ---------------------
+
+-module(p003).
+-include_lib("eunit/include/eunit.hrl").
+
+%% Solution
+%% ---------------------
+%% Inspired by:
+%% http://thetaoishere.blogspot.com/2008/05/largest-prime-factor-of-number.html
+%% ---------------------
+
+lpf(1) -> 1;
+lpf(2) -> 2;
+lpf(N) when N rem 2 == 0 -> lpf(erlang:max(2, N div 2));
+lpf(N) -> lpf(3, trunc(math:sqrt(N)), N).
+
+lpf(I, Sn, N) when I > Sn -> N;
+lpf(I, _S, N) when N rem I == 0 -> erlang:max(I, lpf(N div I));
+lpf(I, Sn, N) -> lpf(I + 2, Sn, N).
+
+
+%% Tests
+
+lpf_1_test() ->
+ ?assertEqual(1, lpf(1)).
+
+lpf_2_test() ->
+ ?assertEqual(2, lpf(2)).
+
+lpf_3_test() ->
+ ?assertEqual(3, lpf(3)).
+
+lpf_16_test() ->
+ ?assertEqual(2, lpf(16)).
+
+lpf_20_test() ->
+ ?assertEqual(5, lpf(20)).
+
+lpf_17_test() ->
+ ?assertEqual(17, lpf(17)).
+
+problem_test() ->
+ ?assertEqual(6857, lpf(600851475143)).
37 p004.erl
@@ -0,0 +1,37 @@
+%% Problem
+%% ---------------------
+%% A palindromic number reads the same both ways. The largest palindrome made from the
+%% product of two 2-digit numbers is 9009 = 91 * 99.
+%%
+%% Find the largest palindrome made from the product of two 3-digit numbers.
+%% ---------------------
+
+-module(p004).
+-include_lib("eunit/include/eunit.hrl").
+
+%% Solution
+%% ---------------------
+%% Brute force
+%% ---------------------
+
+find_largest_palindrome() ->
+ lists:max(palindromes(lists:seq(100, 999))).
+
+palindromes(Factors) ->
+ [M * N || M <- Factors, N <- Factors, is_palindrome(M * N)].
+
+is_palindrome(N) ->
+ Nl = integer_to_list(N),
+ Nl =:= lists:reverse(Nl).
+
+
+%% Tests
+
+is_palindrome_true_test() ->
+ ?assertEqual(true, is_palindrome(9009)).
+
+is_palindrome_false_test() ->
+ ?assertEqual(false, is_palindrome(9001)).
+
+find_test() ->
+ ?assertEqual(906609, find_largest_palindrome()).
59 p005.erl
@@ -0,0 +1,59 @@
+%% Problem
+%% ---------------------
+%% 2520 is the smallest number that can be divided by each of the numbers from 1 to 10
+%% without any remainder.
+%%
+%% What is the smallest number that is evenly divisible by all of the numbers from 1 to 20?
+%% ---------------------
+
+-module(p005).
+-include_lib("eunit/include/eunit.hrl").
+
+%% Solution
+%% ---------------------
+%% Inspired by:
+%% http://basildoncoder.com/blog/2008/06/10/project-euler-problem-5/
+%% ---------------------
+
+find(Max) -> lists:foldl(fun lcm/2, 1, lists:seq(1, Max)).
+
+lcm(A, B) -> (A * B) div gcd(A, B).
+
+gcd(A, B) when A < B -> gcd(B, A);
+gcd(A, 0) -> A;
+gcd(A, B) -> gcd(B, A rem B).
+
+
+%% Tests
+
+gcd_test() ->
+ ?assertEqual(6, gcd(84, 18)).
+
+lcm_test() ->
+ ?assertEqual(12, lcm(4, 6)).
+
+find_10_test() ->
+ ?assertEqual(2520, find(10)).
+
+find_20_test() ->
+ ?assertEqual(232792560, find(20)).
+
+%% Solution from bitRAKE
+%% ---------------------
+%% This does not require programming at all. Compute the prime factorization of each number from 1
+%% to 20, and multiply the greatest power of each prime together:
+%%
+%% 20 = 2^2 * 5
+%% 19 = 19
+%% 18 = 2 * 3^2
+%% 17 = 17
+%% 16 = 2^4
+%% 15 = 3 * 5
+%% 14 = 2 * 7
+%% 13 = 13
+%% 11 = 11
+%%
+%% All others are included in the previous numbers.
+%%
+%% ANSWER: 2^4 * 3^2 * 5 * 7 * 11 * 13 * 17 * 19 = 232,792,560
+%% ---------------------
43 p006.erl
@@ -0,0 +1,43 @@
+%% Problem
+%% ---------------------
+%% The sum of the squares of the first ten natural numbers is,
+%% 1^2 + 2^2 + ... + 10^2 = 385
+%% The square of the sum of the first ten natural numbers is,
+%% (1 + 2 + ... + 10)^2 = 55^2 = 3025
+%% Hence the difference between the sum of the squares of the
+%% first ten natural numbers and the square of the sum is 3025 - 385 = 2640.
+%%
+%% Find the difference between the sum of the squares of the
+%% first one hundred natural numbers and the square of the sum.
+%% ---------------------
+
+-module(p006).
+-include_lib("eunit/include/eunit.hrl").
+
+%% Solution (long)
+%% ---------------------
+
+diff(Max) -> 2 * lists:sum([M * N || M <- lists:seq(1, Max), N <- lists:seq(1, Max), M < N]).
+
+%% Solution (fast)
+%% ---------------------
+
+diff2(N) -> N * (N + 1) * (3*N + 2) * (N - 1) div 12.
+
+
+%% Tests
+
+diff_1_test() ->
+ ?assertEqual(0, diff(1)).
+
+diff_2_test() ->
+ ?assertEqual(4, diff(2)).
+
+diff_10_test() ->
+ ?assertEqual(2640, diff(10)).
+
+diff_100_test() ->
+ ?assertEqual(25164150, diff(100)).
+
+diff2_100_test() ->
+ ?assertEqual(25164150, diff2(100)).
41 p007.erl
@@ -0,0 +1,41 @@
+%% Problem
+%% ---------------------
+%% By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13,
+%% we can see that the 6th prime is 13.
+%%
+%% What is the 10001st prime number?
+%% ---------------------
+
+-module(p007).
+-include_lib("eunit/include/eunit.hrl").
+
+%% Solution
+%% ---------------------
+%% Inspired by:
+%% http://basildoncoder.com/blog/2008/10/26/project-euler-problem-7/
+%% ---------------------
+
+find_prime(N) ->
+ lists:nth(N, sieve_with_atleast_n_primes(N)).
+
+sieve_with_atleast_n_primes(N) ->
+ mymath:primes_upto(upper_bound_estimate(N)).
+
+upper_bound_estimate(N) ->
+ trunc(N * math:log(N) + N * math:log(math:log(N))).
+
+
+%% Tests
+
+find_prime_10_test() ->
+ ?assertEqual(29, find_prime(10)).
+
+upper_bound_estimate_test() ->
+ ?assertEqual(114319, upper_bound_estimate(10001)).
+
+find_prime_10001_test() ->
+ ?assertEqual(104743, find_prime(10001)).
+
+
+%% See also:
+%% http://primes.utm.edu/lists/small/
51 p008.erl
@@ -0,0 +1,51 @@
+%% Problem
+%% ---------------------
+%% Find the greatest product of five consecutive digits in the 1000-digit number.
+%% ---------------------
+
+-module(p008).
+-include_lib("eunit/include/eunit.hrl").
+
+%% Solution
+%% ---------------------
+
+number() ->
+ "73167176531330624919225119674426574742355349194934" ++
+ "96983520312774506326239578318016984801869478851843" ++
+ "85861560789112949495459501737958331952853208805511" ++
+ "12540698747158523863050715693290963295227443043557" ++
+ "66896648950445244523161731856403098711121722383113" ++
+ "62229893423380308135336276614282806444486645238749" ++
+ "30358907296290491560440772390713810515859307960866" ++
+ "70172427121883998797908792274921901699720888093776" ++
+ "65727333001053367881220235421809751254540594752243" ++
+ "52584907711670556013604839586446706324415722155397" ++
+ "53697817977846174064955149290862569321978468622482" ++
+ "83972241375657056057490261407972968652414535100474" ++
+ "82166370484403199890008895243450658541227588666881" ++
+ "16427171479924442928230863465674813919123162824586" ++
+ "17866458359124566529476545682848912883142607690042" ++
+ "24219022671055626321111109370544217506941658960408" ++
+ "07198403850962455444362981230987879927244284909188" ++
+ "84580156166097919133875499200524063689912560717606" ++
+ "05886116467109405077541002256983155200055935729725" ++
+ "71636269561882670428252483600823257530420752963450".
+
+fivelets([A,B,C,D,E]) -> [[A,B,C,D,E]];
+fivelets([A,B,C,D,E|Xs]) -> [[A,B,C,D,E]|fivelets([B,C,D,E|Xs])].
+
+prod(List) -> lists:foldl(fun(X, Prod) -> (X-$0) * Prod end, 1, List).
+
+find() -> lists:max(lists:map(fun prod/1, fivelets(number()))).
+
+
+%% Tests
+
+fivelets_test() ->
+ ?assertEqual(["12345", "23456"], fivelets("123456")).
+
+prod_test() ->
+ ?assertEqual(120, prod("12345")).
+
+find_test() ->
+ ?assertEqual(40824, find()).
31 p009.erl
@@ -0,0 +1,31 @@
+%% Problem
+%% ---------------------
+%% A Pythagorean triplet is a set of three natural numbers, a < b < c, for which, a^2 + b^2 = c^2
+%% For example, 3^2 + 4^2 = 9 + 16 = 25 = 5^2.
+%%
+%% There exists exactly one Pythagorean triplet for which a + b + c = 1000.
+%% Find the product abc.
+%% ---------------------
+
+-module(p009).
+-include_lib("eunit/include/eunit.hrl").
+
+%% Solution
+%% ---------------------
+%% Does not work for big P, i.e. 1,000,000
+%% ---------------------
+
+triplets(P) ->
+ [ {A,B,round(math:sqrt(A*A + B*B))} ||
+ A <- lists:seq(1, P-2),
+ B <- lists:seq(A+1, P-1),
+ P*P =:= 2*(A*P + B*P - A*B)
+ ].
+
+%% Tests
+
+triplets_12_test() ->
+ ?assertEqual([{3,4,5}], triplets(12)).
+
+triplets_k_test() ->
+ ?assertEqual([{200,375,425}], triplets(1000)).
16 p010.erl
@@ -0,0 +1,16 @@
+%% Problem
+%% ---------------------
+%% The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
+%%
+%% Find the sum of all the primes below two million.
+%% ---------------------
+
+-module(p010).
+-include_lib("eunit/include/eunit.hrl").
+
+sum_primes(N) -> lists:sum(mymath:primes_upto(N)).
+
+% Tests
+
+sum_primes_test() ->
+ ?assertEqual(142913828922, sum_primes(2000000)).
Please sign in to comment.
Something went wrong with that request. Please try again.