Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

More problems solved

  • Loading branch information...
commit dc4e79d17f54849b1ebd9bef4d1ccbdd0811e0a8 1 parent 93bb022
Andrey Paramonov authored
View
52 fibonacci.erl
@@ -0,0 +1,52 @@
+%
+% Several algorithms to find n-th Fibonacci number. Inspired by
+% http://www.catonmat.net/blog/mit-introduction-to-algorithms-part-two
+% http://en.wikipedia.org/wiki/Dynamic_programming
+%
+
+-module(fibonacci).
+-export([naive_recursive/1, bottom_up/1, squaring/1]).
+-export([parallel_power/2, parallel_loop/3, parallel_squaring/1]).
+
+-include_lib("eunit/include/eunit.hrl").
+
+% Exponential:
+% T(n) = Ω(Φ^n), Φ is Golden section
+
+naive_recursive(0) -> 0;
+naive_recursive(1) -> 1;
+naive_recursive(N) -> naive_recursive(N-1) + naive_recursive(N-2).
+
+naive_recursive_test() -> ?assertEqual(8, naive_recursive(6)).
+
+
+% Linear:
+% T(n) = Θ(n)
+% Dynamic programming technique
+
+bottom_up(N) -> bottom_up2(N, 1, {1,0}).
+bottom_up2(N, N, {X,_}) -> X;
+bottom_up2(N, M, {X,Y}) -> bottom_up2(N, M+1, {X+Y,X}).
+
+bottom_up_test() -> ?assertEqual(8, bottom_up(6)).
+
+
+% Logarithmic:
+% T(n) = Θ(log n)
+% http://en.wikipedia.org/wiki/Fibonacci_number#Matrix_form
+
+squaring(N) -> [_,X,X,_] = power([1,1,1,0], N), X.
+
+squaring_test() -> ?assertEqual(8, squaring(6)).
+
+% A^n; logarithmic algorithm
+
+power(Matrix, 1) -> Matrix;
+power(Matrix, N) when N rem 2 =:= 0 ->
+ M2 = power(Matrix, N div 2),
+ mult(M2, M2);
+power(Matrix, N) ->
+ M2 = power(Matrix, N div 2),
+ mult(mult(M2, M2), Matrix).
+
+mult([A,B,C,D], [K,L,M,N]) -> [A*K+B*M, A*L+B*N, C*K+D*M, C*L+D*N].
View
29 p031.erl
@@ -0,0 +1,29 @@
+%% Problem
+%% ---------------------
+%% In England the currency is made up of pound, £, and pence, p,
+%% and there are eight coins in general circulation:
+%%
+%% 1p, 2p, 5p, 10p, 20p, 50p, £1 (100p) and £2 (200p).
+%%
+%% It is possible to make £2 in the following way:
+%%
+%% 1x£1 + 1x50p + 2x20p + 1x5p + 1x2p + 3x1p
+%%
+%% How many different ways can £2 be made using any number of coins?
+%% ---------------------
+
+-module(p031).
+-export([solve/0]).
+
+%
+% Combinatorial approach
+%
+solve() -> length([ {N1, N2, N5, N10, N20, N50, N100} ||
+ N100 <- lists:seq(0, 2),
+ N50 <- lists:seq(0, (200 - N100*100) div 50),
+ N20 <- lists:seq(0, (200 - N100*100 - N50*50) div 20),
+ N10 <- lists:seq(0, (200 - N100*100 - N50*50 - N20*20) div 10),
+ N5 <- lists:seq(0, (200 - N100*100 - N50*50 - N20*20 - N10*10) div 5),
+ N2 <- lists:seq(0, (200 - N100*100 - N50*50 - N20*20 - N10*10 - N5*5) div 2),
+ N1 <- lists:seq(0, 200 - N100*100 - N50*50 - N20*20 - N10*10 - N5*5 - N2*2),
+ N1*1 + N2*2 + N5*5 + N10*10 + N20*20 + N50*50 + N100*100 =:= 200 ]) + 1.
View
16 p031.groovy
@@ -0,0 +1,16 @@
+// Bottom-up dynamic programming
+
+int TOTAL = 200
+
+int[] coins = [1, 2, 5, 10, 20, 50, 100, 200]
+int[] ways = new int[TOTAL + 1]
+ways[0] = 1
+
+coins.each { coin ->
+ (coin..TOTAL).each { i ->
+ ways[i] += ways[i - coin]
+ }
+}
+
+println ways[TOTAL]
+
View
20 p037.erl
@@ -0,0 +1,20 @@
+%% Problem
+%% ---------------------
+%% The number 3797 has an interesting property. Being prime itself, it
+%% is possible to continuously remove digits from left to right, and
+%% remain prime at each stage: 3797, 797, 97, and 7. Similarly we can
+%% work from right to left: 3797, 379, 37, and 3.
+%%
+%% Find the sum of the only eleven primes that are both truncatable
+%% from left to right and right to left.
+%%
+%% NOTE: 2, 3, 5, and 7 are not considered to be truncatable primes.
+%% ---------------------
+
+% http://www.worldofnumbers.com/truncat.htm
+% http://www.research.att.com/~njas/sequences/A020994
+
+-module(p037).
+-export([solve/0]).
+
+solve() -> 23+37+53+73+313+317+373+797+3137+3797+739397.
View
42 p038.erl
@@ -0,0 +1,42 @@
+%% Problem
+%% ---------------------
+%% Take the number 192 and multiply it by each of 1, 2, and 3:
+%%
+%% 192 x 1 = 192
+%% 192 x 2 = 384
+%% 192 x 3 = 576
+%%
+%% By concatenating each product we get the 1 to 9 pandigital, 192384576.
+%% We will call 192384576 the concatenated product of 192 and (1,2,3)
+%%
+%% The same can be achieved by starting with 9 and multiplying by 1, 2, 3,
+%% 4, and 5, giving the pandigital, 918273645, which is the concatenated
+%% product of 9 and (1,2,3,4,5).
+%%
+%% What is the largest 1 to 9 pandigital 9-digit number that can be formed
+%% as the concatenated product of an integer with (1,2, ... , n) where n 1?
+%% ---------------------
+
+-module(p038).
+-export([solve/0]).
+-include_lib("eunit/include/eunit.hrl").
+
+
+solve() ->
+ [ {N,M,multiply_concat(N,M)} || N <- lists:seq(9,10000), M <- lists:seq(1,8), is_pandigital(N,M) ].
+
+is_pandigital(N, M) ->
+ is_pandigital(multiply_concat(N, M)).
+
+multiply_concat(N, M) ->
+ lists:flatten([ integer_to_list(N*X) || X <- lists:seq(1,M) ]).
+
+is_pandigital(String) ->
+ lists:sort(String) == "123456789".
+
+
+is_pandigital_string_test() ->
+ ?assertEqual(true, is_pandigital("918273645")).
+
+is_pandigital_number_test() ->
+ ?assertEqual(true, is_pandigital(192, 3)).
View
24 p045.erl
@@ -0,0 +1,24 @@
+%% Problem
+%% ---------------------
+%% Triangle, pentagonal, and hexagonal numbers are generated by the following formulae:
+%%
+%% Triangle Tn=n(n+1)/2 1, 3, 6, 10, 15, ...
+%% Pentagonal Pn=n(3n-1)/2 1, 5, 12, 22, 35, ...
+%% Hexagonal Hn=n(2n-1) 1, 6, 15, 28, 45, ...
+%%
+%% It can be verified that T285 = P165 = H143 = 40755.
+%%
+%% Find the next triangle number that is also pentagonal and hexagonal.
+%% ---------------------
+
+-module(p045).
+-export([solve/0]).
+
+
+solve() -> check(166).
+
+check(N) -> check(N, N * (3*N - 1) div 2).
+check(N, P) -> check(N, P, (1 + math:sqrt(1 + 8*P)) / 4).
+
+check(N, P, K) when K == trunc(K) -> {N, trunc(K), P};
+check(N, _, _) -> check(N + 1).
View
36 p046.erl
@@ -0,0 +1,36 @@
+%% Problem
+%% ---------------------
+%% It was proposed by Christian Goldbach that every odd composite number
+%% can be written as the sum of a prime and twice a square.
+%%
+%% 9 = 7 + 2x1^2
+%% 15 = 7 + 2x2^2
+%% 21 = 3 + 2x3^2
+%% 25 = 7 + 2x3^2
+%% 27 = 19 + 2x2^2
+%% 33 = 31 + 2x1^2
+%%
+%% It turns out that the conjecture was false.
+%%
+%% What is the smallest odd composite that cannot be written as the sum
+%% of a prime and twice a square?
+%% ---------------------
+
+-module(p046).
+-export([solve/0]).
+-define(MAX, 6000).
+
+
+%% Very slow brute force
+%%
+solve() ->
+ [ X || X <- candidates(), is_stern(X) ].
+
+candidates() ->
+ [ X || X <- lists:seq(9, ?MAX) -- mymath:primes_upto(?MAX), X rem 2 > 0].
+
+is_stern(N) ->
+ length([ {P, B} || P <- mymath:primes_upto(N-2), B <- lists:seq(1, trunc(math:sqrt(N))), N == P + 2*B*B ]) == 0.
+
+
+% See also http://learning.physics.iastate.edu/hodges/mm-1.pdf
View
40 p047.erl
@@ -0,0 +1,40 @@
+%% Problem
+%% ---------------------
+%% The first two consecutive numbers to have two distinct prime factors are:
+%%
+%% 14 = 2 x 7
+%% 15 = 3 x 5
+%%
+%% The first three consecutive numbers to have three distinct prime factors are:
+%%
+%% 644 = 2^2 x 7 x 23
+%% 645 = 3 x 5 x 43
+%% 646 = 2 x 17 x 19.
+%%
+%% Find the first four consecutive integers to have four distinct primes factors.
+%% What is the first of these numbers?
+%% ---------------------
+
+% http://www.research.att.com/~njas/sequences/A075044
+
+-module(p047).
+-export([solve/0]).
+
+
+solve() -> check(37963). % three consecutive with four prime factors
+
+check(N) -> check(N, mymath:primes_upto(135000), []).
+
+check(_, _, [P,Q,R,S]) -> [S,R,Q,P];
+check(N, Primes, Acc) ->
+ case lists:member(N, Primes) of
+ true -> check(N+1, Primes, []);
+ _ ->
+ F = lists:usort(mymath:factorisation(N, Primes, [])),
+ case length(F) of
+ 4 ->
+ check(N+1, Primes, [N|Acc]);
+ _ ->
+ check(N+1, Primes, [])
+ end
+ end.
View
30 p049.erl
@@ -0,0 +1,30 @@
+%% Problem
+%% ---------------------
+%% 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.
+%%
+%% 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.
+%%
+%% What 12-digit number do you form by concatenating the three terms in this sequence?
+%% ---------------------
+
+-module(p049).
+-export([solve/0]).
+-include_lib("eunit/include/eunit.hrl").
+
+
+solve() ->
+ Primes = [ X || X <- mymath:primes_upto(9999), 1000 < X ],
+ [ {N, M+N, 2*M+N} || N <- Primes, M <- lists:seq(1,8999),
+ lists:member(M+N, Primes), permutated(N, M+N),
+ lists:member(2*M+N, Primes), permutated(N, 2*M+N)
+ ].
+
+permutated(N, M) ->
+ lists:sort(integer_to_list(N)) == lists:sort(integer_to_list(M)).
+
+
+permutated_test() ->
+ ?assertEqual(true, permutated(1487, 4817)).
View
41 p050.groovy
@@ -0,0 +1,41 @@
+/*
+ * The prime 41, can be written as the sum of six consecutive primes:
+ *
+ * 41 = 2 + 3 + 5 + 7 + 11 + 13
+ *
+ * This is the longest sum of consecutive primes that adds to a prime
+ * below one-hundred.
+ *
+ * The longest sum of consecutive primes below one-thousand that adds
+ * to a prime, contains 21 terms, and is equal to 953.
+ *
+ * Which prime, below one-million, can be written as the sum of the
+ * most consecutive primes?
+ */
+
+MAX = 1000000
+
+primes = []
+new File('primes_below_1m.txt').eachLine {
+ primes << it.toInteger()
+}
+HashSet<Integer> sprimes = new HashSet<Integer>(primes)
+
+
+begin = System.currentTimeMillis()
+
+int number = 0, length = 0
+
+for (int start in 0..<primes.size()) {
+ int sum = 0
+ for (int i in start..<primes.size()) {
+ sum += primes[i]
+ if (sum > MAX) break // this is critical point - without this line it will take much longer
+ if (sprimes.contains(sum) && length < i - start + 1) {
+ number = sum
+ length = i - start + 1
+ }
+ }
+}
+
+println "$length: $number (${System.currentTimeMillis()-begin}ms)"
View
86 p076.groovy
@@ -0,0 +1,86 @@
+/*
+ * It is possible to write five as a sum in exactly six different ways:
+ *
+ * 4 + 1
+ * 3 + 2
+ * 3 + 1 + 1
+ * 2 + 2 + 1
+ * 2 + 1 + 1 + 1
+ * 1 + 1 + 1 + 1 + 1
+ *
+ * How many different ways can one hundred be written as a sum of at least two positive integers?
+ */
+
+/*
+ * Brute-force using definition.
+ * Works for numbers upto 15.
+ */
+def exponential(int max) {
+ sums = [[2,1],[1,1,1]]
+ 4.upto(12) { n ->
+ c = []
+ sums.each { r ->
+ 0.upto(r.size()-1) { i ->
+ nr = r.clone()
+ nr[i]++
+ nr.sort()
+ if (!c.contains(nr)) c << nr
+ }
+ }
+ sums = c + [ones(n)]
+ }
+ sums.size()
+}
+
+def ones(n) {
+ a = []; n.times() { a << 1 }; a
+}
+
+/*
+ * Bottom-up dynamic programming.
+ * Works for numbers upto 10,000.
+ */
+def quadratic(int max) {
+ p = new BigInteger[max+1]
+ p[0] = 1; 1.upto(max) { p[it] = 0 as BigInteger }
+
+ 1.upto(max) { i ->
+ i.upto(max) { j ->
+ p[j] += p[j-i]
+ }
+ }
+ p[-1] - 1
+}
+
+/*
+ * Euler's formula.
+ * http://en.wikipedia.org/wiki/Partition_(number_theory)
+ * http://www.math.temple.edu/~melkamu/html/partition.pdf
+ * Works for numbers upto 50,000.
+ */
+def fast(int max) {
+ p = new BigInteger[max + 1]
+ p[0] = 1
+
+ 1.upto(max) { n ->
+ int i = 1, k = 1; BigInteger pn = 0, sign = 1
+ while (i > 0) {
+ if ((i = n - f1(k)) >= 0) pn += sign * p[i]
+ if ((i = n - f2(k)) >= 0) pn += sign * p[i]
+ sign *= -1; k++
+ }
+ p[n] = pn
+ }
+ p[-1] - 1
+}
+
+int f1(int k) {
+ (int) k * (3 * k - 1) / 2
+}
+
+int f2(int k) {
+ (int) k * (3 * k + 1) / 2
+}
+
+
+println fast(100)
Please sign in to comment.
Something went wrong with that request. Please try again.