function p = perms1(n,b)
% PERMS1(n,b), where n is a positive integer, creates a vector with n
% columns containing one permutation of the numbers from 1 to n. Input b is
% a number between 1 and n! which is the index of the required permutation,
% such that the output of PERMS1(n,b) for b from 1 to n! is equivalent to
% the output from perms(1:n). The order of the permutations is, however,
% different (e.g.,PERMS1(n,5) does not give the fifth row of the PERMS(1:n) output).
% The algorithm is based on imagining that the permutations are obtained by
% using n nested loops. The counter in each inner loop skips the values of all
% outer loops to generate the required permutations. A counter (index) in the
% innermost loop would count n! permutations. Working backwards, given the value
% of an index between 1 and n! this algorithm figures out the state of the
% counter in each these imaginary loops, which are actually the required
% permutation indices.
%K. H. Hamed,
%Sultan Qaboos University, Muscat, Oman
%khhamed@squ.edu.om
%21 November 2006
if nargin <2
error('PERMS1:minrhs','Two Input Arguments are required.')
end;
if fix(n) ~= n || fix(b) ~= b ||n < 0 || b < 0 || ~isa(n,'double') || ~isa(b,'double') || ~isreal(n) || ~isreal(b)
error('PERMS1:nnegint','Input Parameters n and b Must be Non-negative Integers');
end
a=factorial(n:-1:1);
if b>a;
error('PERMS1:brange','Input Parameter b Should be between 1 and n!')
end;
p=zeros(1,n); %initialize output variable
idx=ones(1,n); %initialize loop counters
id=find(a<b,1); %locate the level at which the given index stands
for i=id-1:n-1 %work down to figure out the counter states (idx) in each inner loop
d=mod(b,a(i+1)); %how far down this loop?
idx(i)=floor(b/a(i+1))+(d~=0); %set counter, account for counter resetting
b=d;
if d==0; %adjust indices of inner loops if current loop is reset
for j=i+1:n-1;
idx(j)=n-j+1;
end;
break;
end;
end;
m=1:n; %all possible indices
for i=1:n;
p(i)=m(idx(i)); %set permutation index according to current counter index
m=m(m~=p(i)); %current premutation index is no longer available
end;