Skip to content

Instantly share code, notes, and snippets.

@Koitaro
Created March 4, 2012 13:05
Show Gist options
  • Select an option

  • Save Koitaro/1972912 to your computer and use it in GitHub Desktop.

Select an option

Save Koitaro/1972912 to your computer and use it in GitHub Desktop.
Erlang : Project Euler 30-39
-module(problem30).
-include("euler.hrl").
answer() -> sum(tree([]), max_digits(1)).
tree([]) -> {[], [fun() -> tree([X]) end || X <- lists:seq(0,9)]};
tree([H|T]) -> {[H|T], [fun() -> tree([X,H|T]) end || X <- lists:seq(0,H)]}.
sum({L,_}, Max) when length(L) =:= Max -> sum_fifth(L);
sum({L,Fs},Max) -> sum_fifth(L) + lists:sum([sum(F(),Max) || F <- Fs]).
max_digits(N) ->
case math:pow(9,5) * N > math:pow(10,N) of
true -> max_digits(N+1); _ -> N
end.
sum_fifth([1]) -> 0;
sum_fifth(L) ->
N = lists:sum([trunc(math:pow(X,5)) || X <- L]),
L1 = lists:sort(i2d(N)),
if L =:= L1 -> N; true -> 0 end.
%%%%
-module(problem30).
-include("euler.hrl").
answer() ->
G = digraph:new(),
try
make(G),
lists:sum([sum_fifth(L) || L <- digraph:vertices(G)])
after
digraph:delete(G)
end.
make(G) ->
Max = max_digits(1),
[make(G,[N],Max) || N <- lists:seq(0,9)].
make(G,L,Max) when length(L) =:= Max -> digraph:add_vertex(G,L);
make(G,[H|T],Max) ->
digraph:add_vertex(G,[H|T]),
[make(G,[X,H|T],Max) || X <- lists:seq(0,H)].
max_digits(N) ->
case math:pow(9,5) * N > math:pow(10,N) of
true -> max_digits(N+1);
false -> N
end.
sum_fifth([1]) -> 0;
sum_fifth(L) ->
N = lists:sum([trunc(math:pow(X,5)) || X <- L]),
L1 = lists:sort(i2d(N)),
if L =:= L1 -> N; true -> 0 end.
-module(problem31).
-include("euler.hrl").
answer() -> solve(200,[200,100,50,20,10,5,2]).
solve(_,[]) -> 1;
solve(N,[H|T]) -> lists:sum([solve(N-H*X,T) || X <- lists:seq(0,N div H)]).
%%%%
-module(problem31).
-include("euler.hrl").
-define(COINS,[2,5,10,20,50,100,200]).
answer() -> count(coins([])).
coins(L) ->
F = fun
([]) -> ?COINS;
([H|_]) -> [X || X <- ?COINS, X =< H]
end,
{L, [fun() -> coins([H|L]) end || H <- F(L)]}.
count({L,Fs}) ->
Sum = lists:sum(L),
if
Sum > 200 -> 0;
true -> 1 + lists:sum([count(F()) || F <- Fs])
end.
%%%% pattern matching with stack
-module(problem31).
-include("euler.hrl").
answer() -> solve(1,[{2,2},{5,5},{10,10},{20,20},{50,50},{100,100},{200,200}]).
solve(A,[{_,B}|T]) when B > 200 -> solve(A,T);
solve(A,[{2,B}|T]) -> solve(A+1,[{2,2+B}|T]);
solve(A,[{5,B}|T]) -> solve(A+1,[{2,2+B},{5,5+B}|T]);
solve(A,[{10,B}|T]) -> solve(A+1,[{2,2+B},{5,5+B},{10,10+B}|T]);
solve(A,[{20,B}|T]) -> solve(A+1,[{2,2+B},{5,5+B},{10,10+B},{20,20+B}|T]);
solve(A,[{50,B}|T]) -> solve(A+1,[{2,2+B},{5,5+B},{10,10+B},{20,20+B},{50,50+B}|T]);
solve(A,[{100,B}|T]) -> solve(A+1,[{2,2+B},{5,5+B},{10,10+B},{20,20+B},{50,50+B},{100,100+B}|T]);
solve(A,[{200,200}]) -> A+1.
-module(problem32).
-include("euler.hrl").
-define(DIGITS, [1,2,3,4,5,6,7,8,9]).
answer() -> lists:sum(lists:usort(products())).
products() -> [product(X) || X <- leaves(tree([]))].
product({Xs,Ys}) ->
A = d2i(Xs), B = d2i(Ys), C = A*B, Zs = i2d(C),
case lists:sort(lists:flatten([Xs,Ys,Zs])) of
L when L =:= ?DIGITS -> C;
_ -> 0
end.
tree(L) -> {L, [fun() -> tree([H|L]) end || H <- ?DIGITS--L]}.
leaves({Ds,_}) when length(Ds) =:= 5 -> divide(Ds);
leaves({_,Fs}) -> lists:flatmap(fun (F) -> leaves(F()) end, Fs).
divide([A,B,C,D,E]) -> [{[A],[B,C,D,E]}, {[A,B],[C,D,E]}].
-module(problem33).
-include("euler.hrl").
answer() ->
L = [{N,D} || N <- lists:seq(10,98),
D <- lists:seq(N+1,99),
curious_fraction({N,D})],
{N,D} = lists:foldl(fun ({A,B},{C,D}) -> {A*C,B*D} end, {1,1}, L),
D div gcd(D,N).
curious_fraction({N,D}) ->
N1 = N div 10, N2 = N rem 10, D1 = D div 10, D2 = D rem 10,
(N1 =:= D2 andalso N2*D =:= D1*N) orelse
(N2 =:= D1 andalso N1*D =:= D2*N).
-module(problem34).
-include("euler.hrl").
answer() -> sum(tree([]), max_digits(1)).
tree(L) ->
N = fun ([]) -> 9; ([H|_]) -> H end(L),
{L, [fun() -> tree([H|L]) end || H <- lists:seq(0,N)]}.
sum({L,_},Max) when length(L) =:= Max -> sum_facts(L);
sum({L,Fs},Max) -> sum_facts(L) + lists:sum([sum(F(),Max) || F <- Fs]).
sum_facts([1]) -> 0;
sum_facts([2]) -> 0;
sum_facts(L) ->
N = lists:sum([facts(X) || X <- L]), L1 = lists:sort(i2d(N)),
if L =:= L1 -> N; true -> 0 end.
max_digits(N) ->
X = facts(9) * N, Y = pow(10,N),
if X < Y -> N; true -> max_digits(N+1) end.
facts(0) -> 1; facts(N) -> N * facts(N-1).
-module(problem35).
-import(primes, [is_prime/1]).
-include("euler.hrl").
answer() ->
G = digraph:new(),
to_graph(G,digits([])),
[rotate(G,L) || L <- digraph:vertices(G)],
Vss = digraph_utils:cyclic_strong_components(G),
digraph:delete(G),
13 + lists:sum([length(Vs) || Vs <- Vss]).
digits(L) -> {L, [fun() -> digits([H|L]) end || H <- [1,3,7,9]]}.
to_graph(_,{L,_}) when length(L) =:= 7 -> noop;
to_graph(G,{L,Fs}) when length(L) < 3 -> [to_graph(G,F()) || F <- Fs];
to_graph(G,{L,Fs}) ->
case is_prime(d2i(L)) of
true -> digraph:add_vertex(G,L);
false -> noop
end,
[to_graph(G,F()) || F <- Fs].
rotate(G,[H|T]) ->
L = T ++ [H],
case digraph:vertex(G,L) of
{L,_} -> digraph:add_edge(G,[H|T],L);
false -> digraph:del_vertex(G,[H|T])
end.
-module(problem36).
-include("euler.hrl").
answer() ->
D = [1,3,5,7,9], D1 = lists:seq(0,9),
F = fun(X) -> lists:flatmap(fun palindrome/1, X) end,
L1 = F([[A] || A <- D]),
L2 = F([[B,A] || A <- D, B <- D1]),
L3 = F([[C,B,A] || A <- D, B <- D1, C <- D1]),
lists:sum([answer(X) || X <- L1++L2++L3]).
answer(L) ->
N = d2i(L), L1 = i2b(N), L2 = lists:reverse(L1),
if L1 =:= L2 -> N; true -> 0 end.
palindrome([H|T]) -> L1 = lists:reverse([H|T]), [L1++T, L1++[H|T]].
i2b(N) -> i2b(N,[]).
i2b(0,L) -> L;
i2b(N,L) -> i2b(N div 2, [N rem 2|L]).
-module(problem37).
-include("euler.hrl").
answer() -> lists:sum([N || N <- leaves(tree()), is_answer(N)]).
tree() -> {root, [fun() -> tree(X) end || X <- [2,3,5,7]]}.
tree(N) -> {N, [fun() -> tree(10*N+X) end || X <- [1,3,7,9]]}.
leaves({root,Fs}) -> lists:flatmap(fun(F) -> leaves(F()) end, Fs);
leaves({N,Fs}) ->
case primes:is_prime(N) of
true -> [N | lists:flatmap(fun(F) -> leaves(F()) end, Fs)];
false -> []
end.
is_answer(N) when N < 10 -> false;
is_answer(N) -> lists:all(fun primes:is_prime/1, trim_lefts(N)).
trim_lefts(N) when N < 10 -> [N];
trim_lefts(N) -> [N|trim_lefts(N rem pow(10,trunc(math:log10(N))))].
-module(problem38).
-include("euler.hrl").
answer() -> lists:max([concat(N) || N <- lists:seq(1,9876)]).
concat(N) ->
L = concat(1,N,[]),
case lists:sort(L) =:= lists:seq(1,9) of
true -> d2i(L);
_ -> 0
end.
concat(M,N,L) ->
L1 = i2d(M*N),
if
length(L) + length(L1) > 9 -> L;
true -> concat(M+1,N,L++L1)
end.
-module(problem39).
-include("euler.hrl").
answer() ->
G = digraph:new(),
[make(G,N) || N <- sum_triples()],
L = [{digraph:in_degree(G,V), V} || V <- digraph:vertices(G)],
digraph:delete(G),
element(2, lists:last(lists:sort(L))).
sum_triples() -> sum_triples(ppt:triples()).
sum_triples({{A,B,C},_}) when A+B+C > 1000 -> [];
sum_triples({{A,B,C},Fs}) ->
[A+B+C|lists:flatmap(fun (F) -> sum_triples(F()) end, Fs)].
make(G,N) ->
digraph:add_vertex(G,N),
digraph:add_edge(G,N,N),
make(G,N,2).
make(_,N,X) when N*X > 1000 -> noop;
make(G,N,X) ->
A = N*(X-1), B = N*X,
digraph:add_vertex(G,B),
digraph:add_edge(G,A,B),
make(G,N,X+1).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment