tasks a-s
This commit is contained in:
parent
47bf37c096
commit
b83f433714
12433 changed files with 156208 additions and 123 deletions
12
Task/Permutations-by-swapping/0DESCRIPTION
Normal file
12
Task/Permutations-by-swapping/0DESCRIPTION
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
Generate permutations of n items in which successive permutations differ from each other by the swapping of any two items. Also generate the sign of the permutation which is +1 when the permutation is generated from an even number of swaps from the initial state, and -1 for odd. Show the permutations and signs of three items, in order of generation ''here''.
|
||||
|
||||
Such data are of use in generating the [[Matrix arithmetic|determinant]] of a square matrix and any functions created should bear this in mind.
|
||||
|
||||
Note: The Steinhaus–Johnson–Trotter algorithm generates successive permutations where ''adjacent'' items are swapped, but from [[wp:Parity_of_a_permutation#Example|this]] discussion adjacency is not a requirement.
|
||||
|
||||
;References:
|
||||
* [[wp:Steinhaus–Johnson–Trotter algorithm|Steinhaus–Johnson–Trotter algorithm]]
|
||||
* [http://www.cut-the-knot.org/Curriculum/Combinatorics/JohnsonTrotter.shtml Johnson-Trotter Algorithm Listing All Permutations]
|
||||
|
||||
;Cf.:
|
||||
* [[Matrix arithmetic]]
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
PROCperms(3)
|
||||
PRINT
|
||||
PROCperms(4)
|
||||
END
|
||||
|
||||
DEF PROCperms(n%)
|
||||
LOCAL p%(), i%, k%, s%
|
||||
DIM p%(n%)
|
||||
FOR i% = 1 TO n%
|
||||
p%(i%) = -i%
|
||||
NEXT
|
||||
s% = 1
|
||||
REPEAT
|
||||
PRINT "Perm: [ ";
|
||||
FOR i% = 1 TO n%
|
||||
PRINT ;ABSp%(i%) " ";
|
||||
NEXT
|
||||
PRINT "] Sign: ";s%
|
||||
k% = 0
|
||||
FOR i% = 2 TO n%
|
||||
IF p%(i%)<0 IF ABSp%(i%)>ABSp%(i%-1) IF ABSp%(i%)>ABSp%(k%) k% = i%
|
||||
NEXT
|
||||
FOR i% = 1 TO n%-1
|
||||
IF p%(i%)>0 IF ABSp%(i%)>ABSp%(i%+1) IF ABSp%(i%)>ABSp%(k%) k% = i%
|
||||
NEXT
|
||||
IF k% THEN
|
||||
FOR i% = 1 TO n%
|
||||
IF ABSp%(i%)>ABSp%(k%) p%(i%) *= -1
|
||||
NEXT
|
||||
i% = k%+SGNp%(k%)
|
||||
SWAP p%(k%),p%(i%)
|
||||
s% = -s%
|
||||
ENDIF
|
||||
UNTIL k% = 0
|
||||
ENDPROC
|
||||
91
Task/Permutations-by-swapping/D/permutations-by-swapping-1.d
Normal file
91
Task/Permutations-by-swapping/D/permutations-by-swapping-1.d
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
import std.algorithm, std.array, std.typecons, std.range;
|
||||
|
||||
struct Spermutations(bool doCopy=true) {
|
||||
private immutable uint n;
|
||||
alias TResult = Tuple!(int[], int);
|
||||
|
||||
int opApply(in int delegate(in ref TResult) dg) {
|
||||
int result;
|
||||
|
||||
int sign = 1;
|
||||
alias Int2 = Tuple!(int, int);
|
||||
auto p = iota(n).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[1] = sign;
|
||||
result = dg(aux);
|
||||
if (result)
|
||||
goto END;
|
||||
|
||||
while (p.canFind!(pp => pp[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]) {
|
||||
i1 = i;
|
||||
largest = pp;
|
||||
}
|
||||
}
|
||||
}
|
||||
immutable n1 = largest[0], d1 = largest[1];
|
||||
|
||||
sign *= -1;
|
||||
int i2;
|
||||
if (d1 == -1) {
|
||||
i2 = i1 - 1;
|
||||
swap(p[i1], 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]);
|
||||
if (i2 == n - 1 || p[i2 + 1][0] > n1)
|
||||
p[i2][1] = 0;
|
||||
}
|
||||
|
||||
if (doCopy) {
|
||||
aux[0] = p.map!(pp => pp[0])().array();
|
||||
} else {
|
||||
foreach (immutable i, immutable pp; p)
|
||||
aux[0][i] = pp[0];
|
||||
}
|
||||
aux[1] = sign;
|
||||
result = dg(aux);
|
||||
if (result)
|
||||
goto END;
|
||||
|
||||
foreach (immutable i3, ref pp; p) {
|
||||
immutable n3 = pp[0], d3 = pp[1];
|
||||
if (n3 > n1)
|
||||
pp[1] = (i3 < i2) ? 1 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
END: return result;
|
||||
}
|
||||
}
|
||||
|
||||
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]) {
|
||||
writefln("\nPermutations and sign of %d items", n);
|
||||
foreach (tp; spermutations(n))
|
||||
writefln("Perm: %s Sign: %2d", tp.tupleof);
|
||||
}
|
||||
}
|
||||
}
|
||||
34
Task/Permutations-by-swapping/D/permutations-by-swapping-2.d
Normal file
34
Task/Permutations-by-swapping/D/permutations-by-swapping-2.d
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import std.algorithm, std.array, std.typecons, std.range;
|
||||
|
||||
Tuple!(int[], int)[] 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();
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
auto r = sPermu(n);
|
||||
return iota(r.length)
|
||||
.map!(i => tuple(r[i], i % 2 ? -1 : 1))()
|
||||
.array();
|
||||
}
|
||||
|
||||
void main() {
|
||||
import std.stdio;
|
||||
foreach (n; [3, 4]) {
|
||||
writefln("\nPermutations and sign of %d items", n);
|
||||
foreach (tp; sPermutations(n))
|
||||
writefln("Perm: %s Sign: %2d", tp.tupleof);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
insertEverywhere :: a -> [a] -> [[a]]
|
||||
insertEverywhere x [] = [[x]]
|
||||
insertEverywhere x l@(y:ys) = (x:l) : map (y:) (insertEverywhere x ys)
|
||||
|
||||
s_perm :: [a] -> [[a]]
|
||||
s_perm = foldl aux [[]]
|
||||
where aux items x = do (f, item) <- zip (cycle [reverse, id]) items
|
||||
f (insertEverywhere x item)
|
||||
|
||||
s_permutations :: [a] -> [([a], Int)]
|
||||
s_permutations = flip zip (cycle [1, -1]) . s_perm
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
putStrLn "3 items:"
|
||||
mapM_ print $ s_permutations [0..2]
|
||||
putStrLn "4 items:"
|
||||
mapM_ print $ s_permutations [0..3]
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
bfsjt0=: _1 - i.
|
||||
lookingat=: 0 >. <:@# <. i.@# + *
|
||||
next=: | >./@:* | > | {~ lookingat
|
||||
bfsjtn=: (((] <@, ] + *@{~) | i. next) C. ] * _1 ^ next < |)^:(*@next)
|
||||
16
Task/Permutations-by-swapping/J/permutations-by-swapping-2.j
Normal file
16
Task/Permutations-by-swapping/J/permutations-by-swapping-2.j
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
bfsjtn^:(i.!3) bfjt0 3
|
||||
_1 _2 _3
|
||||
_1 _3 _2
|
||||
_3 _1 _2
|
||||
3 _2 _1
|
||||
_2 3 _1
|
||||
_2 _1 3
|
||||
<:@| bfsjtn^:(i.!3) bfjt0 3
|
||||
0 1 2
|
||||
0 2 1
|
||||
2 0 1
|
||||
2 1 0
|
||||
1 2 0
|
||||
1 0 2
|
||||
A. <:@| bfsjtn^:(i.!3) bfjt0 3
|
||||
0 1 4 5 3 2
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
(_1^2|i.!3),. bfsjtn^:(i.!3) bfjt0 3
|
||||
1 _1 _2 _3
|
||||
_1 _1 _3 _2
|
||||
1 _3 _1 _2
|
||||
_1 3 _2 _1
|
||||
1 _2 3 _1
|
||||
_1 _2 _1 3
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
(,.~C.!.2)<:| bfsjtn^:(i.!3) bfjt0 3
|
||||
1 0 1 2
|
||||
_1 0 2 1
|
||||
1 2 0 1
|
||||
_1 2 1 0
|
||||
1 1 2 0
|
||||
_1 1 0 2
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
rsjt=: 3 :0
|
||||
if. 2>y do. i.2#y
|
||||
else. ((!y)$(,~|.)-.=i.y)#inv!.(y-1)"1 y#rsjt y-1
|
||||
end.
|
||||
)
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
(,.~ C.!.2) rsjt 3
|
||||
1 0 1 2
|
||||
_1 0 2 1
|
||||
1 2 0 1
|
||||
_1 2 1 0
|
||||
1 1 2 0
|
||||
_1 1 0 2
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
perms[0] = {{{}, 1}};
|
||||
perms[n_] :=
|
||||
Flatten[If[#2 == 1, Reverse, # &]@
|
||||
Table[{Insert[#1, n, i], (-1)^(n + i) #2}, {i, n}] & @@@
|
||||
perms[n - 1], 1];
|
||||
|
|
@ -0,0 +1 @@
|
|||
Print["Perm: ", #[[1]], " Sign: ", #[[2]]] & /@ perms@4;
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
sub insert($x, @xs) { [@xs[0..$_-1], $x, @xs[$_..*]] for 0..+@xs }
|
||||
sub order($sg, @xs) { $sg > 0 ?? @xs !! @xs.reverse }
|
||||
|
||||
multi perms([]) {
|
||||
[] => +1
|
||||
}
|
||||
|
||||
multi perms([$x, *@xs]) {
|
||||
perms(@xs).map({ order($_.value, insert($x, $_.key)) }) Z=> (+1,-1) xx *
|
||||
}
|
||||
|
||||
.say for perms([0..2]);
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
from operator import itemgetter
|
||||
|
||||
DEBUG = False # like the built-in __debug__
|
||||
|
||||
def spermutations(n):
|
||||
"""permutations by swapping. Yields: perm, sign"""
|
||||
sign = 1
|
||||
p = [[i, 0 if i == 0 else -1] # [num, direction]
|
||||
for i in range(n)]
|
||||
|
||||
if DEBUG: print ' #', p
|
||||
yield tuple(pp[0] for pp in p), sign
|
||||
|
||||
while any(pp[1] for pp in p): # moving
|
||||
i1, (n1, d1) = max(((i, pp) for i, pp in enumerate(p) if pp[1]),
|
||||
key=itemgetter(1))
|
||||
sign *= -1
|
||||
if d1 == -1:
|
||||
# Swap down
|
||||
i2 = i1 - 1
|
||||
p[i1], p[i2] = p[i2], p[i1]
|
||||
# If this causes the chosen element to reach the First or last
|
||||
# position within the permutation, or if the next element in the
|
||||
# same direction is larger than the chosen element:
|
||||
if i2 == 0 or p[i2 - 1][0] > n1:
|
||||
# The direction of the chosen element is set to zero
|
||||
p[i2][1] = 0
|
||||
elif d1 == 1:
|
||||
# Swap up
|
||||
i2 = i1 + 1
|
||||
p[i1], p[i2] = p[i2], p[i1]
|
||||
# If this causes the chosen element to reach the first or Last
|
||||
# position within the permutation, or if the next element in the
|
||||
# same direction is larger than the chosen element:
|
||||
if i2 == n - 1 or p[i2 + 1][0] > n1:
|
||||
# The direction of the chosen element is set to zero
|
||||
p[i2][1] = 0
|
||||
if DEBUG: print ' #', p
|
||||
yield tuple(pp[0] for pp in p), sign
|
||||
|
||||
for i3, pp in enumerate(p):
|
||||
n3, d3 = pp
|
||||
if n3 > n1:
|
||||
pp[1] = 1 if i3 < i2 else -1
|
||||
if DEBUG: print ' # Set Moving'
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from itertools import permutations
|
||||
|
||||
for n in (3, 4):
|
||||
print '\nPermutations and sign of %i items' % n
|
||||
sp = set()
|
||||
for i in spermutations(n):
|
||||
sp.add(i[0])
|
||||
print('Perm: %r Sign: %2i' % i)
|
||||
#if DEBUG: raw_input('?')
|
||||
# Test
|
||||
p = set(permutations(range(n)))
|
||||
assert sp == p, 'Two methods of generating permutations do not agree'
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
def s_permutations(seq):
|
||||
def s_perm(seq):
|
||||
if not seq:
|
||||
return [[]]
|
||||
else:
|
||||
new_items = []
|
||||
for i, item in enumerate(s_perm(seq[:-1])):
|
||||
if i % 2:
|
||||
# step up
|
||||
new_items += [item[:i] + seq[-1:] + item[i:]
|
||||
for i in range(len(item) + 1)]
|
||||
else:
|
||||
# step down
|
||||
new_items += [item[:i] + seq[-1:] + item[i:]
|
||||
for i in range(len(item), -1, -1)]
|
||||
return new_items
|
||||
|
||||
return [(tuple(item), -1 if i % 2 else 1)
|
||||
for i, item in enumerate(s_perm(seq))]
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
def s_permutations(seq):
|
||||
items = [[]]
|
||||
for j in seq:
|
||||
new_items = []
|
||||
for i, item in enumerate(items):
|
||||
if i % 2:
|
||||
# step up
|
||||
new_items += [item[:i] + [j] + item[i:]
|
||||
for i in range(len(item) + 1)]
|
||||
else:
|
||||
# step down
|
||||
new_items += [item[:i] + [j] + item[i:]
|
||||
for i in range(len(item), -1, -1)]
|
||||
items = new_items
|
||||
|
||||
return [(tuple(item), -1 if i % 2 else 1)
|
||||
for i, item in enumerate(items)]
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
# A simple swap operation
|
||||
proc swap {listvar i1 i2} {
|
||||
upvar 1 $listvar l
|
||||
set tmp [lindex $l $i1]
|
||||
lset l $i1 [lindex $l $i2]
|
||||
lset l $i2 $tmp
|
||||
}
|
||||
|
||||
proc permswap {n v1 v2 body} {
|
||||
upvar 1 $v1 perm $v2 sign
|
||||
|
||||
# Initialize
|
||||
set sign -1
|
||||
for {set i 0} {$i < $n} {incr i} {
|
||||
lappend items $i
|
||||
lappend dirs -1
|
||||
}
|
||||
|
||||
while 1 {
|
||||
# Report via callback
|
||||
set perm $items
|
||||
set sign [expr {-$sign}]
|
||||
uplevel 1 $body
|
||||
|
||||
# Find the largest mobile integer (lmi) and its index (idx)
|
||||
set i [set idx -1]
|
||||
foreach item $items dir $dirs {
|
||||
set j [expr {[incr i] + $dir}]
|
||||
if {$j < 0 || $j >= [llength $items]} continue
|
||||
if {$item > [lindex $items $j] && ($idx == -1 || $item > $lmi)} {
|
||||
set lmi $item
|
||||
set idx $i
|
||||
}
|
||||
}
|
||||
|
||||
# If none, we're done
|
||||
if {$idx == -1} break
|
||||
|
||||
# Swap the largest mobile integer with "what it is looking at"
|
||||
set nextIdx [expr {$idx + [lindex $dirs $idx]}]
|
||||
swap items $idx $nextIdx
|
||||
swap dirs $idx $nextIdx
|
||||
|
||||
# Reverse directions on larger integers
|
||||
set i -1
|
||||
foreach item $items dir $dirs {
|
||||
lset dirs [incr i] [expr {$item > $lmi ? -$dir : $dir}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
permswap 4 p s {
|
||||
puts "$s\t$p"
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
include c:\cxpl\codes;
|
||||
|
||||
proc PERMS(N);
|
||||
int N; \number of elements
|
||||
int I, K, S, T, P;
|
||||
[P:= Reserve((N+1)*4);
|
||||
for I:= 0 to N do P(I):= -I; \initialize facing left (also set P(0)=0)
|
||||
S:= 1;
|
||||
repeat Text(0, "Perm: [ ");
|
||||
for I:= 1 to N do
|
||||
[IntOut(0, abs(P(I))); ChOut(0, ^ )];
|
||||
Text(0, "] Sign: "); IntOut(0, S); CrLf(0);
|
||||
|
||||
K:= 0; \find largest mobile element
|
||||
for I:= 2 to N do \for left-facing elements
|
||||
if P(I) < 0 and
|
||||
abs(P(I)) > abs(P(I-1)) and \ greater than neighbor
|
||||
abs(P(I)) > abs(P(K)) then K:= I; \ get largest element
|
||||
for I:= 1 to N-1 do \for right-facing elements
|
||||
if P(I) > 0 and
|
||||
abs(P(I)) > abs(P(I+1)) and \ greater than neighbor
|
||||
abs(P(I)) > abs(P(K)) then K:= I; \ get largest element
|
||||
if K # 0 then \mobile element found
|
||||
[for I:= 1 to N do \reverse elements > K
|
||||
if abs(P(I)) > abs(P(K)) then P(I):= P(I)*-1;
|
||||
I:= K + (if P(K)<0 then -1 else 1);
|
||||
T:= P(K); P(K):= P(I); P(I):= T; \swap K with element looked at
|
||||
S:= -S; \alternate signs
|
||||
];
|
||||
until K = 0; \no mobile element remains
|
||||
];
|
||||
|
||||
[PERMS(3);
|
||||
CrLf(0);
|
||||
PERMS(4);
|
||||
]
|
||||
Loading…
Add table
Add a link
Reference in a new issue