This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/JIT/examples/fannkuch.pl

109 lines
2.4 KiB
Prolog

% ----------------------------------------------------------------------
% 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).
% ------------------------------- %