@@ -77,7 +77,7 @@ T2=$(TR $(TDNW $(LREF $1)) $(TD $+))
7777 */
7878module std.algorithm.sorting ;
7979
80- import std.algorithm.mutation : SwapStrategy;
80+ import std.algorithm.mutation : SwapStrategy, reverse ;
8181import std.functional : unaryFun, binaryFun;
8282import std.range.primitives ;
8383import std.typecons : Flag, No, Yes;
@@ -5025,6 +5025,8 @@ bool nthPermutationImpl(Range)
50255025 (auto ref Range range, ulong perm)
50265026if (isRandomAccessRange! Range && hasLength! Range )
50275027{
5028+
5029+
50285030 import std.range.primitives : ElementType;
50295031 import std.numeric : decimalToFactorial;
50305032
@@ -5037,10 +5039,22 @@ if (isRandomAccessRange!Range && hasLength!Range)
50375039 return false ;
50385040 }
50395041
5042+ if (idx < range.length)
5043+ {
5044+ reverse(fac[0 .. idx]);
5045+
5046+ // Preserve leading zero digits in the Lehmer code to ensure lexicographic order
5047+
5048+ reverse(fac[0 .. range.length]);
5049+ }
5050+
5051+
5052+ size_t len = range.length;
5053+
50405054 ElementType! Range tmp;
50415055 size_t i = 0 ;
50425056
5043- for (; i < idx ; ++ i)
5057+ for (; i < len ; ++ i)
50445058 {
50455059 size_t re = fac[i];
50465060 tmp = range[re + i];
@@ -5055,6 +5069,41 @@ if (isRandomAccessRange!Range && hasLength!Range)
50555069}
50565070
50575071// /
5072+ pure @safe unittest
5073+ {
5074+ auto src = [0 , 1 , 2 ];
5075+ auto rslt = [0 , 2 , 1 ];
5076+
5077+ src = nthPermutation(src, 1 );
5078+ assert (src == rslt);
5079+ }
5080+ pure @safe unittest
5081+ {
5082+ auto src = [0 , 1 , 2 , 3 ];
5083+ auto rslt = [0 , 3 , 1 , 2 ];
5084+
5085+ src = nthPermutation(src, 4 );
5086+ assert (src == rslt);
5087+ }
5088+ pure @safe unittest
5089+ {
5090+ auto src = [0 , 1 , 2 ];
5091+ auto rslt = [0 , 2 , 1 ];
5092+
5093+ bool worked = nthPermutationImpl(src, 1 );
5094+ assert (worked);
5095+ assert (src == rslt);
5096+ }
5097+ pure @safe unittest
5098+ {
5099+ auto src = [0 , 1 , 2 , 3 ];
5100+ auto rslt = [0 , 3 , 1 , 2 ];
5101+
5102+ bool worked = nthPermutationImpl(src, 4 );
5103+ assert (worked);
5104+ assert (src == rslt);
5105+ }
5106+
50585107pure @safe unittest
50595108{
50605109 auto src = [0 , 1 , 2 , 3 , 4 , 5 , 6 ];
@@ -5076,7 +5125,7 @@ pure @safe unittest
50765125pure @safe unittest
50775126{
50785127 auto src = [0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ];
5079- auto rslt = [4 , 0 , 6 , 2 , 1 , 3 , 5 , 7 , 8 , 9 , 10 ];
5128+ auto rslt = [0 , 1 , 2 , 3 , 8 , 4 , 10 , 6 , 5 , 7 , 9 ];
50805129
50815130 src = nthPermutation(src, 2982 );
50825131 assert (src == rslt);
@@ -5097,7 +5146,7 @@ pure @safe unittest
50975146 import std.meta : AliasSeq;
50985147
50995148 auto src = [0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ];
5100- auto rsl = [4 , 0 , 6 , 2 , 1 , 3 , 5 , 7 , 8 , 9 , 10 ];
5149+ auto rsl = [0 , 1 , 2 , 3 , 8 , 4 , 10 , 6 , 5 , 7 , 9 ];
51015150
51025151 foreach (T; AliasSeq! (
51035152 DummyRange! (ReturnBy.Reference, Length.Yes, RangeType.Random , int []),
0 commit comments