Skip to content

Commit d16bf8c

Browse files
committed
More tests, fix NthPermutation
1 parent 0b7bcc4 commit d16bf8c

2 files changed

Lines changed: 69 additions & 17 deletions

File tree

mathics/packages/DiscreteMath/CombinatoricaV0.9.m

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -626,16 +626,30 @@
626626
RankPermutation[p_?PermutationQ] := (p[[1]]-1) (Length[Rest[p]]!) +
627627
RankPermutation[ Map[(If[#>p[[1]], #-1, #])&, Rest[p]] ]
628628

629-
NthPermutation[n1_Integer,l_List] :=
630-
Module[{k, n=n1, s=l, i},
631-
Table[
632-
n = Mod[n,(i+1)!];
633-
k = s [[Quotient[n,i!]+1]];
634-
s = Complement[s,{k}];
635-
k,
636-
{i,Length[l]-1,0,-1}
637-
]
638-
]
629+
(* UP, and UnrankPermutation come from the V2.1 code.
630+
There is some problem in the v0.9 code and rather than try to fix that
631+
we use the newer version
632+
*)
633+
UP[r_Integer, n_Integer] :=
634+
Module[{r1 = r, q = n!, i},
635+
Table[r1 = Mod[r1, q];
636+
q = q/(n - i + 1);
637+
Quotient[r1, q] + 1,
638+
{i, n}
639+
]
640+
]
641+
UnrankPermutation[r_Integer, {}] := {}
642+
UnrankPermutation[r_Integer, l_List] :=
643+
Module[{s = l, k, t, p = UP[Mod[r, Length[l]!], Length[l]], i},
644+
Table[k = s[[t = p[[i]] ]];
645+
s = Delete[s, t];
646+
k,
647+
{i, Length[ p ]}
648+
]
649+
]
650+
UnrankPermutation[r_Integer, n_Integer?Positive] :=
651+
UnrankPermutation[r, Range[n]]
652+
NthPermutation[r_Integer, l_List] := UnrankPermutation[r, l]
639653

640654
NextPermutation[p_?PermutationQ] :=
641655
NthPermutation[ RankPermutation[p]+1, Sort[p] ]
@@ -1036,6 +1050,7 @@
10361050
]
10371051
]
10381052

1053+
(* 1.5.5 Generating k-Subsets *)
10391054
KSubsets[l_List,0] := { {} }
10401055
KSubsets[l_List,1] := Partition[l,1]
10411056
KSubsets[l_List,k_Integer?Positive] := {l} /; (k == Length[l])

test/test_combinatorica.py

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,16 @@ def test_combinatorica_permutations_1_1():
4646
" {d, b, c, a}, {d, c, a, b}, {d, c, b, a}}",
4747
"LexicographicPermuations, 1.1.1 Page 4",
4848
),
49-
# NthPermutation does not work
49+
(
50+
"Table[ NthPermutation[n, Range[4]], {n, 0, 23}]",
51+
"{{1, 2, 3, 4}, {1, 2, 4, 3}, {1, 3, 2, 4}, {1, 3, 4, 2}, "
52+
" {1, 4, 2, 3}, {1, 4, 3, 2}, {2, 1, 3, 4}, {2, 1, 4, 3}, "
53+
" {2, 3, 1, 4}, {2, 3, 4, 1}, {2, 4, 1, 3}, {2, 4, 3, 1}, "
54+
" {3, 1, 2, 4}, {3, 1, 4, 2}, {3, 2, 1, 4}, {3, 2, 4, 1}, "
55+
" {3, 4, 1, 2}, {3, 4, 2, 1}, {4, 1, 2, 3}, {4, 1, 3, 2}, "
56+
" {4, 2, 1, 3}, {4, 2, 3, 1}, {4, 3, 1, 2}, {4, 3, 2, 1}} ",
57+
"slower method for computing permutations in lex order, 1.1.2, Page 6"
58+
),
5059
(
5160
"Map[RankPermutation, Permutations[Range[4]]]",
5261
"Range[0, 23]",
@@ -146,13 +155,13 @@ def test_combinatorica_permutations_1_2():
146155
(
147156
"EquivalenceClasses[relation]",
148157
"{{1, 2, 3, 4}, {5}}",
149-
"EquivalenceClasses, 1.2.3, Page 19"
158+
"EquivalenceClasses, 1.2.3, Page 19",
159+
),
160+
(
161+
"PermutationGroupQ[{{1, 2, 3, 4}, {4, 2, 3, 1}}]",
162+
"True",
163+
"PermutationGroupQ, 1.2.3 Page 20",
150164
),
151-
# (
152-
# "PermutationGroupQ[Range[4], {4, 2, 3, 1}]",
153-
# "True",
154-
# "PermutationGroupQ, 1.2.3 Page 20",
155-
# ),
156165
(
157166
"ToCycles[Range[10]]",
158167
"{{1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}}",
@@ -198,6 +207,34 @@ def test_combinatorica_permutations_1_2():
198207
check_evaluation(str_expr, str_expected, message)
199208

200209

210+
def test_combinatorica_permutations_1_5():
211+
212+
# We include this earlier since the above in fact rely on KSubsets
213+
for str_expr, str_expected, message in (
214+
(
215+
"KSubsets[Range[5], 3]",
216+
"{{1, 2, 3}, {1, 2, 4}, {1, 2, 5}, {1, 3, 4}, {1, 3, 5}, "
217+
"{1, 4, 5}, {2, 3, 4}, {2, 3, 5}, {2, 4, 5}, {3, 4, 5}}",
218+
"KSubsets 1.5.5, Page 45",
219+
),
220+
(
221+
"KSubsets[Range[3], 0]",
222+
"{ {} } ",
223+
"KSubsets[0] == { {} }",
224+
),
225+
(
226+
"KSubsets[Range[5], 1]",
227+
"{{1}, {2}, {3}, {4}, {5}}",
228+
"KSubsets[Range[n, 1] == Partition[n]",
229+
),
230+
(
231+
"KSubsets[Range[5], 5]",
232+
"{Range[5]} ",
233+
"KSubsets[l, k] == Length(l)",
234+
),
235+
):
236+
check_evaluation(str_expr, str_expected, message)
237+
201238
def test_combinatorica_rest():
202239

203240
# Permutation[3] doesn't work

0 commit comments

Comments
 (0)