Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Next chunk of solutions

  • Loading branch information...
commit 96bb90f308d857c07a23450a2b09189950c62a14 1 parent a0f2aeb
Andrey Paramonov authored
View
42 mymath.erl
@@ -1,5 +1,5 @@
-module(mymath).
--export([c/2, ds/1, factorial/1, lcm/2, primes_upto/1, prod/1]).
+-export([c/2, ds/1, factorial/1, is_palindrome/1, lcm/2, perms/1, pow/2, primes_upto/1, prod/1]).
-include_lib("eunit/include/eunit.hrl").
%% Find all prime numbers upto specified value.
@@ -60,8 +60,9 @@ c(N, M) -> prod(lists:seq(M+1, N)) div factorial(N-M).
%% Product of numbers in the list
%%
-prod(List) -> lists:foldl(fun(X,Y) -> X*Y end, 1, List).
+prod(List) -> lists:foldl(fun erlang:'*'/2, 1, List).
+factorial(0) -> 1;
factorial(N) -> prod(lists:seq(1,N)).
@@ -70,6 +71,25 @@ factorial(N) -> prod(lists:seq(1,N)).
ds(M) -> lists:foldl(fun(N, Sum) -> Sum + N - $0 end, 0, integer_to_list(M)).
+%% Integer power of another integer
+%%
+pow(N, 1) -> N;
+pow(N, E) -> N * pow(N, E-1).
+
+
+%% Calculates all permutations for elements from given list
+%%
+perms([]) -> [[]];
+perms(L) -> [[H|T] || H <- L, T <- perms(L--[H])].
+
+
+%% Returns true if given list or integer is palindrom
+%%
+is_palindrome([]) -> [];
+is_palindrome([X|Xs]) -> [X|Xs] =:= lists:reverse([X|Xs]);
+is_palindrome(N) -> is_palindrome(integer_to_list(N)).
+
+
%% Tests
primes_upto_30_test() ->
@@ -101,3 +121,21 @@ factorial_test() ->
ds_test() ->
?assertEqual(21, ds(1569)).
+
+pow_test() ->
+ ?assertEqual(32, pow(2, 5)).
+
+perms_test() ->
+ ?assertEqual(["012", "021", "102", "120", "201", "210"], perms("012")).
+
+is_palindrome_int_true_test() ->
+ ?assertEqual(true, is_palindrome(9009)).
+
+is_palindrome_int_false_test() ->
+ ?assertEqual(false, is_palindrome(9001)).
+
+is_palindrome_list_true_test() ->
+ ?assertEqual(true, is_palindrome("1001001001")).
+
+is_palindrome_list_false_test() ->
+ ?assertEqual(false, is_palindrome("1001001011")).
View
16 p004.erl
@@ -8,7 +8,6 @@
-module(p004).
-export([solve/0]).
--include_lib("eunit/include/eunit.hrl").
%% Brute force solution
%% ---------------------
@@ -17,17 +16,4 @@ solve() ->
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)).
+ [M * N || M <- Factors, N <- Factors, mymath:is_palindrome(M * N)].
View
21 p017.erl
@@ -0,0 +1,21 @@
+%% Problem
+%% ---------------------
+%% If the numbers 1 to 5 are written out in words: one, two, three, four,
+%% five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.
+%%
+%% If all the numbers from 1 to 1000 (one thousand) inclusive were written
+%% out in words, how many letters would be used?
+%% ---------------------
+
+-module(p017).
+-export([solve/0]).
+
+
+solve() ->
+ Units = length("onetwothreefourfivesixseveneightnine"),
+ Teens = length("teneleventwelvethirteenfourteenfifteensixteenseventeeneighteennineteen"),
+ Ties = length("twentythirtyfortyfiftysixtyseventyeightyninety"),
+ Hundred = length("hundred"),
+ And = length("and"),
+ Thousand = length("onethousand"),
+ Thousand + 9*100*Hundred + 9*99*And + 10*10*Ties + 10*Teens + (9*10+100)*Units.
View
11 p019.erl
@@ -0,0 +1,11 @@
+%% Problem
+%% ---------------------
+%% How many Sundays fell on the first of the month during
+%% the twentieth century (1 Jan 1901 to 31 Dec 2000)?
+%% ---------------------
+
+-module(p019).
+-export([solve/0]).
+
+
+solve() -> length([ {M, Y} || Y <- lists:seq(1901, 2000), M <- lists:seq(1, 12), calendar:day_of_the_week(Y, M, 1) =:= 7 ]).
View
8 p024.erl
@@ -19,14 +19,8 @@ solve() -> find(1000000, "0123456789").
%% Brute force works relatively fast.
%%
-find(Nth, List) -> lists:nth(Nth, perms(List)).
+find(Nth, List) -> lists:nth(Nth, mymath:perms(List)).
-perms([]) -> [[]];
-perms(L) -> [[H|T] || H <- L, T <- perms(L--[H])].
-
-
-perms_test() ->
- ?assertEqual(["012", "021", "102", "120", "201", "210"], perms("012")).
find_test() ->
?assertEqual("120", find(4, "012")).
View
22 p029.erl
@@ -0,0 +1,22 @@
+%% Problem
+%% ---------------------
+%% Consider all integer combinations of ab for 2 =< a =< 5 and 2 =< b =< 5:
+%%
+%% 2^2=4, 2^3=8, 2^4=16, 2^5=32
+%% 3^2=9, 3^3=27, 3^4=81, 3^5=243
+%% 4^2=16, 4^3=64, 4^4=256, 4^5=1024
+%% 5^2=25, 5^3=125, 5^4=625, 5^5=3125
+%%
+%% If they are then placed in numerical order, with any repeats removed,
+%% we get the following sequence of 15 distinct terms:
+%%
+%% 4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125
+%%
+%% How many distinct terms are in the sequence generated by ab for 2 a 100 and 2 b 100?
+%% ---------------------
+
+-module(p029).
+-export([solve/0]).
+
+
+solve() -> length(lists:usort([ mymath:pow(N, M) || N <- lists:seq(2, 100), M <- lists:seq(2, 100) ])).
View
31 p030.erl
@@ -0,0 +1,31 @@
+%% Problem
+%% ---------------------
+%% Surprisingly there are only three numbers that can be written as
+%% the sum of fourth powers of their digits:
+%%
+%% 1634 = 1^4 + 6^4 + 3^4 + 4^4
+%% 8208 = 8^4 + 2^4 + 0^4 + 8^4
+%% 9474 = 9^4 + 4^4 + 7^4 + 4^4
+%%
+%% The sum of these numbers is 1634 + 8208 + 9474 = 19316.
+%%
+%% Find the sum of all the numbers that can be written as the sum of
+%% fifth powers of their digits.
+%% ---------------------
+
+-module(p030).
+-export([solve/0]).
+-include_lib("eunit/include/eunit.hrl").
+
+
+%% 6 * 9^5 = 354294
+%%
+solve() -> lists:sum([ N || N <- lists:seq(11, 354294), value(N) =:= N ]).
+
+value(N) -> lists:sum([ mymath:pow(M-$0, 5) || M <- integer_to_list(N)]).
+
+
+value_test() ->
+ ?assertEqual(33, value(12)).
+
+% [4150,4151,54748,92727,93084,194979]
View
32 p034.erl
@@ -0,0 +1,32 @@
+%% Problem
+%% ---------------------
+%% 145 is a curious number, as 1! + 4! + 5! = 1 + 24 + 120 = 145.
+%%
+%% Find the sum of all numbers which are equal to the sum of the factorial of their digits.
+%%
+%% Note: as 1! = 1 and 2! = 2 are not sums they are not included.
+%% ---------------------
+
+-module(p034).
+-export([solve/0]).
+-include_lib("eunit/include/eunit.hrl").
+
+
+%% Some thoughts:
+%% 9! = 362880; 7 times 9! is less than 9999999.
+%% Brute force with that bound is very slow.
+%% To find more accurate upper bound solve the equation:
+%% x = 9! * ln(x) => x = 2309171
+%% Even with this bound brute force is still slow.
+%%
+solve() -> lists:sum([ N || N <- lists:seq(3, 2309171), N =:= sum(N) ]).
+
+sum(N) -> lists:sum([ mymath:factorial(M-$0) || M <- integer_to_list(N) ]).
+
+
+sum_test() ->
+ ?assertEqual(145, sum(145)).
+
+
+% See also:
+% http://mathworld.wolfram.com/Factorion.html
View
55 p035.erl
@@ -0,0 +1,55 @@
+%% Problem
+%% ---------------------
+%% The number, 197, is called a circular prime because all rotations
+%% of the digits: 197, 971, and 719, are themselves prime.
+%%
+%% There are thirteen such primes below 100: 2, 3, 5, 7, 11, 13, 17,
+%% 31, 37, 71, 73, 79, and 97.
+%%
+%% How many circular primes are there below one million?
+%% ---------------------
+
+-module(p035).
+-export([solve/0]).
+-include_lib("eunit/include/eunit.hrl").
+
+
+solve() -> find(1000000-1).
+
+find(Max) -> find([ integer_to_list(N) || N <- mymath:primes_upto(Max), no_even(N) ], 0).
+
+no_even(N) -> length([ M || M <- integer_to_list(N), M rem 2 > 0]) =:= length(integer_to_list(N)).
+
+find([], Acc) -> Acc;
+find([X|Xs], Acc) ->
+ Circle = circle(X),
+ Xs1 = Xs -- Circle,
+ Acc1 = case length(Xs1) == length([X|Xs]) - length(Circle) of
+ true -> Acc + length(Circle);
+ false -> Acc
+ end,
+ find(Xs1, Acc1).
+
+
+circle(S) -> circle(S, length(S), []).
+circle(_, 0, Acc) -> lists:usort(Acc);
+circle([H|T], N, Acc) -> circle(T++[H], N-1, [[H|T]|Acc]).
+
+
+no_even_13_test() ->
+ ?assertEqual(true, no_even(13)).
+
+no_even_12_test() ->
+ ?assertEqual(false, no_even(12)).
+
+circle_1_test() ->
+ ?assertEqual(["1"], circle("1")).
+
+circle_11_test() ->
+ ?assertEqual(["11"], circle("11")).
+
+circle_123_test() ->
+ ?assertEqual(["123","231","312"], circle("123")).
+
+find_test() ->
+ ?assertEqual(13, find(100)).
View
16 p036.erl
@@ -0,0 +1,16 @@
+%% Problem
+%% ---------------------
+%% The decimal number, 585 = 1001001001 (binary), is palindromic in both bases.
+%%
+%% Find the sum of all numbers, less than one million, which are palindromic in base 10 and base 2.
+%% ---------------------
+
+-module(p036).
+-export([solve/0]).
+
+
+%% Brute force is pretty fast
+%%
+solve() -> lists:sum([ N || N <- lists:seq(1, 1000000-1), mymath:is_palindrome(N), mymath:is_palindrome(bin(N)) ]).
+
+bin(N) -> hd(io_lib:format("~.2B", [N])).
View
20 p040.erl
@@ -0,0 +1,20 @@
+%% Problem
+%% ---------------------
+%% An irrational decimal fraction is created by concatenating the positive integers:
+%%
+%% 0.123456789101112131415161718192021...
+%%
+%% It can be seen that the 12th digit of the fractional part is 1.
+%%
+%% If dn represents the nth digit of the fractional part, find the value of the following expression.
+%%
+%% d1 x d10 x d100 x d1000 x d10000 x d100000 x d1000000
+%% ---------------------
+
+-module(p040).
+-export([solve/0]).
+
+
+solve() ->
+ Number = lists:flatten([ integer_to_list(X) || X <- lists:seq(1,230000) ]),
+ mymath:prod([ lists:nth(N,Number) - $0 || N <- [1,10,100,1000,10000,100000,1000000] ]).
View
69 p043.erl
@@ -0,0 +1,69 @@
+%% Problem
+%% ---------------------
+%% The number, 1406357289, is a 0 to 9 pandigital number because it
+%% is made up of each of the digits 0 to 9 in some order, but it also
+%% has a rather interesting sub-string divisibility property.
+%%
+%% Let d1 be the 1st digit, d2 be the 2nd digit, and so on. In this
+%% way, we note the following:
+%%
+%% d2d3d4=406 is divisible by 2
+%% d3d4d5=063 is divisible by 3
+%% d4d5d6=635 is divisible by 5
+%% d5d6d7=357 is divisible by 7
+%% d6d7d8=572 is divisible by 11
+%% d7d8d9=728 is divisible by 13
+%% d8d9d10=289 is divisible by 17
+%%
+%% Find the sum of all 0 to 9 pandigital numbers with this property.
+%% ---------------------
+
+-module(p043).
+-export([solve/0]).
+-include_lib("eunit/include/eunit.hrl").
+
+
+%% Brute force works for less than a minute.
+%% perms/1 function is slow.
+%%
+solve() ->
+ lists:sum([ list_to_integer(X) || X <- mymath:perms("0123456789"), condition(X) ]).
+
+%% Explicit and fast but long
+condition(X) ->
+ condition(X, 2, 2) and
+ condition(X, 3, 3) and
+ condition(X, 4, 5) and
+ condition(X, 5, 7) and
+ condition(X, 6, 11) and
+ condition(X, 7, 13) and
+ condition(X, 8, 17).
+
+% Functional and short but slow
+%condition(X) ->
+% lists:foldl(fun([S,P],Acc) -> condition(X,S,P) and Acc end, true,
+% [[2,2],[3,3],[4,5],[5,7],[6,11],[7,13],[8,17]]).
+
+condition(Str, Start, P) ->
+ list_to_integer(lists:sublist(Str, Start, 3)) rem P == 0.
+
+
+cond_test() ->
+ ?assertEqual(true, condition("1406357289")).
+
+cond_3_test() ->
+ ?assertEqual(true, condition("1406357289", 3, 3)).
+
+cond_7_test() ->
+ ?assertEqual(true, condition("1406357289", 5, 7)).
+
+cond_11_test() ->
+ ?assertEqual(true, condition("1406357289", 6, 11)).
+
+cond_13_test() ->
+ ?assertEqual(true, condition("1406357289", 7, 13)).
+
+cond_17_test() ->
+ ?assertEqual(true, condition("1406357289", 8, 17)).
+
+% 1406357289,1430952867,1460357289,4106357289,4130952867,4160357289
View
43 p044.erl
@@ -0,0 +1,43 @@
+%% Problem
+%% ---------------------
+%% Pentagonal numbers are generated by the formula, Pn=n(3n1)/2. The
+%% first ten pentagonal numbers are:
+%%
+%% 1, 5, 12, 22, 35, 51, 70, 92, 117, 145, ...
+%%
+%% It can be seen that P4 + P7 = 22 + 70 = 92 = P8. However, their
+%% difference, 70 - 22 = 48, is not pentagonal.
+%%
+%% Find the pair of pentagonal numbers, Pj and Pk, for which their
+%% sum and difference is pentagonal and D = |Pk - Pj| is minimised;
+%% what is the value of D?
+%% ---------------------
+
+-module(p044).
+-export([solve/0]).
+-include_lib("eunit/include/eunit.hrl").
+
+
+solve() -> pent(1, 1, []).
+
+%% P(n+1) = P(n) + 3n + 1
+%%
+pent(N, P, Ps) ->
+ List = [ P-X || X <- Ps, is_pentagonal(P-X), is_pentagonal(P+X) ],
+ case List of
+ [] -> pent(N+1, P+3*N+1, [P|Ps]);
+ _ -> List
+ end.
+
+%% http://en.wikipedia.org/wiki/Pentagonal_number
+%%
+is_pentagonal(X) ->
+ N = (math:sqrt(24*X+1) + 1) / 6,
+ N == trunc(N).
+
+
+is_pentagonal_true_test() ->
+ ?assertEqual(true, is_pentagonal(92)).
+
+is_pentagonal_false_test() ->
+ ?assertEqual(false, is_pentagonal(91)).
Please sign in to comment.
Something went wrong with that request. Please try again.