109 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
		
		
			
		
	
	
			109 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| 
								 | 
							
								% ----------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								% 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).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								% ------------------------------- %
							 |