% ---------------------------------------------------------------------- % The Computer Language Benchmarks Game % http://shootout.alioth.debian.org/ % Contributed by Anthony Borla % Modified by Glendon Holst % ---------------------------------------------------------------------- :- yap_flag(unknown,error). :- use_module(library(lists)). :- initialization(main). main :- unix( argv([H|_]) ), number_atom(N,H), f_permutations(N, MaxFlips), format('Pfannkuchen(~d) = ~d~n', [N, MaxFlips]), statistics, statistics_jit. % ------------------------------- % f_permutations(N, MaxFlips) :- numlist(1, N, L), f_permutations_(L, N, 0, 0, MaxFlips, 0, _). % ------------- % f_permutations_(L, N, I, MaxFlips0, MaxFlips, PermN0, PermN) :- (I < N -> ( N =:= 1 -> !, processPerm(L, MaxFlips0, MaxFlips, PermN0, PermN) ; N1 is N - 1, f_permutations_(L, N1, 0, MaxFlips0, MaxFlips1, PermN0, PermN1), split_list(L, N, Lt, Ld), rotateLeft(Lt, LtRL), append(LtRL, Ld, La), Ii is I + 1, !, f_permutations_(La, N, Ii, MaxFlips1, MaxFlips, PermN1, PermN) ) ; !, MaxFlips = MaxFlips0, PermN = PermN0 ). % ------------------------------- % flips(L, Flips) :- flips_(L, 0, Flips). flips_([1|_], Fla, Fla) :- !. flips_([N|T], Fla, Flips) :- take_drop([N|T], N, Lt, Ld), append(Lt, Ld, La), Fla1 is Fla + 1, !, flips_(La, Fla1, Flips). % ------------------------------- % rotateLeft([H|T], RL) :- append(T, [H], RL). rotateLeft([], []). % ------------------------------- % numlist(N, M, [N|Ls]) :- N < M, !, N1 is N + 1, numlist(N1, M, Ls). numlist(M, M, [M]). % ------------------------------- % printPerm([L|Ls]) :- write(L), printPerm(Ls). printPerm([]) :- nl. % ------------------------------- % processPerm(L, MaxFlips0, MaxFlips, PermN0, PermN) :- flips(L, Flips), ( Flips > MaxFlips0 -> MaxFlips = Flips ; MaxFlips = MaxFlips0 ), ( PermN0 < 30 -> printPerm(L), PermN is PermN0 + 1 ; PermN = PermN0 ). % ------------------------------- % split_list([L|Ls], N, [L|Hs], Ts) :- N > 0, !, N1 is N - 1, split_list(Ls, N1, Hs, Ts). split_list(Ls, 0, [], Ls) :- !. % ------------------------------- % take_drop(L, N, Taken, Rest) :- take_drop_(L, N, 0, [], Taken, Rest). take_drop_(L, N, N, Ta, Ta, L) :- !. take_drop_([H|T], N, Nc, Ta, Taken, Rest) :- Nc1 is Nc + 1, !, take_drop_(T, N, Nc1, [H|Ta], Taken, Rest). % ------------------------------- %