Skip to content

Instantly share code, notes, and snippets.

@Koitaro
Created March 22, 2012 18:32
Show Gist options
  • Select an option

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

Select an option

Save Koitaro/2161382 to your computer and use it in GitHub Desktop.
Erlang : Project Euler 60-69
-module(problem61B).
-include("euler.hrl").
-record(poly, {p,up,lo}).
answer() ->
G = digraph:new(),
try
[make(G,P) || P <- polygonals()],
find(G)
catch
Answer -> Answer
after
digraph:delete(G)
end.
polygonals() -> lists:flatmap(fun polygonals/1, lists:seq(3,8)).
polygonals(P) -> polygonals(P,1).
polygonals(P,N) ->
case N*(N*(P-2)-(P-4)) div 2 of
X when X > 9999 -> [];
X when X < 1000 -> polygonals(P,N+1);
X -> [#poly{p=P, up=X div 100, lo=X rem 100}|polygonals(P,N+1)]
end.
make(G,#poly{p=P,up=X,lo=Y}) ->
digraph:add_vertex(G,X),
digraph:add_vertex(G,Y),
digraph:add_edge(G,X,Y,P).
find(G) -> [find(G,[V],[]) || V <- digraph:vertices(G)].
find(G,[V1,V2,V3,V4,V5,V6],Ps) ->
Es = [digraph:edge(G,E) || E <- digraph:out_edges(G,V6)],
[throw(101*(V1+V2+V3+V4+V5+V6)) || {_,_,V,P} <- Es, V =:= V1, not lists:member(P,Ps)];
find(G,Vs,Ps) ->
Es = [digraph:edge(G,E) || E <- digraph:out_edges(G,lists:last(Vs))],
[find(G, Vs++[V], [P|Ps]) || {_,_,V,P} <- Es, not lists:member(P,Ps)].
-module(problem62).
-include("euler.hrl").
answer() ->
G = digraph:new(),
try
solve(G,1)
after
digraph:delete(G)
end.
solve(G,N) ->
Cube = N*N*N,
V = lists:sort(i2d(Cube)),
digraph:add_vertex(G,V),
digraph:add_vertex(G,Cube),
digraph:add_edge(G,Cube,V),
case digraph:in_degree(G,V) of
5 -> lists:min(digraph:in_neighbours(G,V));
_ -> solve(G,N+1)
end.
-module(problem63).
-include("euler.hrl").
answer() -> lists:sum([count(N,1) || N <- lists:seq(1,9)]).
count(N,P) ->
case trunc(math:log10(math:pow(N,P))) + 1 =:= P of
true -> 1 + count(N,P+1);
false -> 0
end.
-module(problem67).
-include("euler.hrl").
answer() -> solve(data()).
solve([H|T]) -> [X] = lists:foldl(fun join/2, H, T), X.
join([],_) -> [];
join([X|Xs],[Y,Y1|Ys]) -> [X+max(Y,Y1)|join(Xs,[Y1|Ys])].
data() ->
{ok,IO} = file:open("triangle.txt", [read]),
try
read_lines(IO,[])
after
file:close(IO)
end.
read_lines(IO,L) ->
F = fun(X) ->
Line = string:tokens(string:strip(X, right, $\n), " "),
[list_to_integer(Word) || Word <- Line]
end,
case file:read_line(IO) of
{ok,Line} -> read_lines(IO, [F(Line)|L]);
eof -> L
end.
-module(problem68).
-include("euler.hrl").
-define(digits, [10,9,8,7,6,5,4,3,2,1]).
answer() -> try find(tree([])) catch L -> join(L) end.
tree(L) -> {L, [fun () -> tree(L ++ [X]) end || X <- ?digits -- L]}.
find({[A,B,C,D,E],_}) when A+B+C =/= C+D+E; A > D -> [];
find({[A,B,C,_,E,F,G],_}) when A+B+C =/= E+F+G; A > F -> [];
find({[A,B,C,_,_,_,G,H,I],_}) when A+B+C =/= G+H+I; A > H -> [];
find({[A,B,C,_,_,_,_,_,I,J],_}) when A+B+C =/= I+J+B; A > J -> [];
find({L,_}) when length(L) =:= 10 ->
[_,_,_,D,_,F,_,H,_,J] = L,
case lists:member(10,[D,F,H,J]) of
true -> throw(L);
false -> []
end;
find({_,Fs}) -> [find(F()) || F <- Fs].
join([A,B,C,D,E,F,G,H,I,J]) -> join([A,B,C,D,C,E,F,E,G,H,G,I,J,I,B],0).
join([],N) -> N;
join([H|T],N) when H =:= 10 -> join([1,0|T],N);
join([H|T],N) -> join(T,10*N+H).
%%%%
-module(problem68).
-include("euler.hrl").
-define(digits, [1,2,3,4,5,6,7,8,9,10]).
-record(line, {sum, top, middle, bottom}).
answer() ->
Graph = digraph:new(),
try
make(Graph),
lists:max(find(Graph))
after
digraph:delete(Graph)
end.
make(G) ->
Lines = [#line{sum=A+B+C, top=A, middle=B, bottom=C} ||
A <- ?digits, B <- ?digits -- [A], C <- ?digits -- [A,B],
A+B+C >= 1+2+10, A+B+C =< 1+9+10],
[digraph:add_vertex(G,L) || L <- Lines],
[digraph:add_edge(G,V1,V2) ||
V1 <- digraph:vertices(G), V2 <- digraph:vertices(G), joinable(V1,V2)].
joinable(A,B) ->
A#line.sum =:= B#line.sum andalso
A#line.top =/= B#line.top andalso
A#line.top =/= B#line.middle andalso
A#line.top =/= B#line.bottom andalso
A#line.middle =/= B#line.top andalso
A#line.middle =/= B#line.middle andalso
A#line.middle =/= B#line.bottom andalso
A#line.bottom =/= B#line.top andalso
A#line.bottom =:= B#line.middle andalso
A#line.bottom =/= B#line.bottom.
find(G) ->
[format(V1,V2,V3,V4,V5) ||
V1 <- digraph:vertices(G),
V2 <- digraph:out_neighbours(G,V1),
V3 <- digraph:out_neighbours(G,V2),
V4 <- digraph:out_neighbours(G,V3),
V5 <- digraph:out_neighbours(G,V4),
answer(V1,V2,V3,V4,V5)].
answer(L1,L2,L3,L4,L5) ->
L = [L1,L2,L3,L4,L5],
P = lists:flatten([[X#line.top,X#line.bottom] || X <- L]),
T = [X#line.top || X <- L],
L1#line.middle =:= L5#line.bottom andalso
lists:min([X#line.top || X <- L]) =:= L1#line.top andalso
lists:sort(P) =:= ?digits andalso
lists:member(10,T).
format(L1,L2,L3,L4,L5) ->
L = [L1,L2,L3,L4,L5],
num(lists:flatten([[X#line.top,X#line.middle,X#line.bottom] || X <- L])).
num(L) -> num(L,0).
num([],N) -> N;
num([10|T],N) -> num([1,0|T],N);
num([H|T],N) -> num(T,10*N+H).
-module(problem69).
-include("euler.hrl").
answer() -> solve(2,primes(3)).
solve(N,{P,_}) when N*P > 1000000 -> N;
solve(N,{P,F}) -> solve(N*P, F()).
primes(P) -> {P, fun () -> primes(next_prime(P)) end}.
next_prime(P) ->
P1 = P+2,
case primes:is_prime(P1) of
true -> P1;
false -> next_prime(P1)
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment