This commit is contained in:
Ingy döt Net 2013-10-27 22:24:23 +00:00
parent 6f050a029e
commit 776bba907c
3887 changed files with 59894 additions and 7280 deletions

View file

@ -0,0 +1,167 @@
/*
Name : The following code generates the permutations of first 'N' natural nos.
Description: The value of 'N' can be set through #define N.
The permutation are displayed in lexical order, smallest to largest, with appropriate signs
*/
#include<iostream>
#include<conio.h>
using namespace std;
//Function to calculate the factorial of a number
long int fact(int size)
{
int i;
long int temp =1;
if (size<=1)
{
return 1;
}
else
{
for(i=size;i>0;i--)
temp*=i;
}
return temp;
}
//Function to display the permutations.
void Permutations(int N)
{
//Flag to indicate the sign
signed short int Toggle_Flag = 1;
//To keep track of when to change the sign.
//Sign reverses when Toggle_Flag_Change_Condition = 0
unsigned short int Toggle_Flag_Change_Condition =0;
//Loop variables
short int i =0;
short int j =0;
short int k =0;
//Iterations
long int Loops = fact(N);
//Array of pointers to hold the digits
int **Index_Nos_ptr = new int*[N];
//Repetition of each digit (Master copy)
int *Digit_Rep_Master = new int[N];
//Repetition of each digit (Local copy)
int *Digit_Rep_Local = new int[N];
//Index for Index_Nos_ptr
int *Element_Num = new int[N];
//Initialization
for(i=0;i<N;i++)
{
//Allocate memory to hold the subsequent digits in the form of a LUT
//For N = N, memory required for LUT = N(N+1)/2
Index_Nos_ptr[i] = new int[N-i];
//Initialise the repetition value of each digit (Master and Local)
//Each digit repeats for (i-1)!, where 1 is the position of the digit
Digit_Rep_Local[i] = Digit_Rep_Master[i] = fact(N-i-1);
//Initialise index values to access the arrays
Element_Num[i] = N-i-1;
//Initialise the arrays with the required digits
for(j=0;j<(N-i);j++)
{
*(Index_Nos_ptr[i] +j) = N-j-1;
}
}//end of for()
//Start with iteration
while(Loops>0)
{
Loops--;
cout<<"Perm: [";
for(i=0;i<N;i++)
{
//Print from MSD to LSD
cout<<" "<<*(Index_Nos_ptr[i] + Element_Num[i]);
//Decrement the repetition count for each digit
Digit_Rep_Local[i]--;
//If repetition count has reached 0...
if(Digit_Rep_Local[i] <=0 )
{
//Refill the repitition factor
Digit_Rep_Local[i] = Digit_Rep_Master[i];
//And the index to access the required digit is also 0...
if(Element_Num[i] <=0 && i!=0)
{
//Reset the index
Element_Num[i] = N-i-1;
//Update the numbers held un Index_Nos_ptr[]
for(j=0,k=0;j<=N-i;j++)
{
//Exclude the preceeding digit(from the previous array) already printed.
if(j!=Element_Num[i-1])
{
*(Index_Nos_ptr[i]+k)= *(Index_Nos_ptr[i-1]+j);
k++;
}
}
}
//If the index is not 0...
else
{
//Decrement the index value so as to print the appropriate digit
//in the same array
Element_Num[i]--;
}//end of if-else
}//end of if()
}//end of for()
//Print the sign.
cout<<"] Sign: "<<Toggle_Flag<<"\n";
if(Toggle_Flag_Change_Condition > 0)
{
Toggle_Flag_Change_Condition--;
}
else
{
//Update the sign value.
Toggle_Flag=-Toggle_Flag;
//Reset Toggle_Flag_Change_Condition
Toggle_Flag_Change_Condition =1;
}//end of if-else
}//end of while()
}//end of Permutations()
int main()
{
Permutations(4);
getch();
return 0;
}

View file

@ -9,64 +9,60 @@ struct Spermutations(bool doCopy=true) {
int sign = 1;
alias Int2 = Tuple!(int, int);
auto p = iota(n).map!(i => Int2(i, i ? -1 : 0))().array();
auto p = n.iota.map!(i => Int2(i, i ? -1 : 0)).array;
TResult aux;
if (doCopy) {
aux[0] = p.map!(pp => pp[0])().array();
} else {
aux[0] = new int[n];
foreach (immutable i, immutable pp; p)
aux[0][i] = pp[0];
}
aux[0] = p.map!(pi => pi[0]).array;
aux[1] = sign;
result = dg(aux);
if (result)
goto END;
while (p.canFind!(pp => pp[1])()) {
while (p.canFind!q{ a[1] }) {
// Failed to use std.algorithm here, too much complex.
auto largest = Int2(-100, -100);
int i1 = -1;
foreach (immutable i, immutable pp; p) {
if (pp[1]) {
if (pp[0] > largest[0]) {
foreach (immutable i, immutable pi; p) {
if (pi[1]) {
if (pi[0] > largest[0]) {
i1 = i;
largest = pp;
largest = pi;
}
}
}
immutable n1 = largest[0], d1 = largest[1];
immutable n1 = largest[0],
d1 = largest[1];
sign *= -1;
int i2;
if (d1 == -1) {
i2 = i1 - 1;
swap(p[i1], p[i2]);
p[i1].swap(p[i2]);
if (i2 == 0 || p[i2 - 1][0] > n1)
p[i2][1] = 0;
} else if (d1 == 1) {
i2 = i1 + 1;
swap(p[i1], p[i2]);
p[i1].swap(p[i2]);
if (i2 == n - 1 || p[i2 + 1][0] > n1)
p[i2][1] = 0;
}
if (doCopy) {
aux[0] = p.map!(pp => pp[0])().array();
aux[0] = p.map!(pi => pi[0]).array;
} else {
foreach (immutable i, immutable pp; p)
aux[0][i] = pp[0];
foreach (immutable i, immutable pi; p)
aux[0][i] = pi[0];
}
aux[1] = sign;
result = dg(aux);
if (result)
goto END;
foreach (immutable i3, ref pp; p) {
immutable n3 = pp[0], d3 = pp[1];
foreach (immutable i3, ref pi; p) {
immutable n3 = pi[0],
d3 = pi[1];
if (n3 > n1)
pp[1] = (i3 < i2) ? 1 : -1;
pi[1] = (i3 < i2) ? 1 : -1;
}
}
@ -78,14 +74,13 @@ Spermutations!doCopy spermutations(bool doCopy=true)(in uint n) {
return typeof(return)(n);
}
version (permutations_by_swapping1) {
void main() {
import std.stdio;
foreach (n; [3, 4]) {
foreach (immutable n; [3, 4]) {
writefln("\nPermutations and sign of %d items", n);
foreach (tp; spermutations(n))
writefln("Perm: %s Sign: %2d", tp.tupleof);
foreach (const tp; n.spermutations)
writefln("Perm: %s Sign: %2d", tp[]);
}
}
}

View file

@ -1,34 +1,30 @@
import std.algorithm, std.array, std.typecons, std.range;
Tuple!(int[], int)[] sPermutations(in int n) /*pure nothrow*/ {
auto sPermutations(in int n) /*pure nothrow*/ {
static int[][] sPermu(in int items) /*pure nothrow*/ {
if (items <= 0)
return [[]];
typeof(return) r;
foreach (i, item; sPermu(items - 1)) {
if (i % 2)
r ~= iota(cast(int)item.length, -1, -1)
.map!(i => item[0..i] ~ (items-1) ~ item[i..$])()
.array();
else
r ~= iota(item.length + 1)
.map!(i => item[0..i] ~ (items-1) ~ item[i..$])()
.array();
foreach (immutable i, item; sPermu(items - 1)) {
//r.put((i % 2 ? iota(cast(int)item.length, -1, -1) :
// iota(item.length + 1))
// .map!(i => item[0..i] ~ (items-1) ~ item[i..$]));
immutable f=(in int i)=>item[0..i] ~ (items-1) ~ item[i..$];
r ~= (i % 2) ?
iota(cast(int)item.length, -1, -1).map!f.array :
iota(item.length + 1).map!f.array;
}
return r;
}
auto r = sPermu(n);
return iota(r.length)
.map!(i => tuple(r[i], i % 2 ? -1 : 1))()
.array();
return sPermu(n).zip([1, -1].cycle);
}
void main() {
import std.stdio;
foreach (n; [3, 4]) {
foreach (immutable n; [3, 4]) {
writefln("\nPermutations and sign of %d items", n);
foreach (tp; sPermutations(n))
writefln("Perm: %s Sign: %2d", tp.tupleof);
foreach (const tp; n.sPermutations)
writefln("Perm: %s Sign: %2d", tp[]);
}
}