@@ -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,7 @@ bool nthPermutationImpl(Range)
50255025 (auto ref Range range, ulong perm)
50265026if (isRandomAccessRange! Range && hasLength! Range )
50275027{
5028+
50285029 import std.range.primitives : ElementType;
50295030 import std.numeric : decimalToFactorial;
50305031
@@ -5037,10 +5038,20 @@ if (isRandomAccessRange!Range && hasLength!Range)
50375038 return false ;
50385039 }
50395040
5041+ if (idx < range.length)
5042+ {
5043+ reverse(fac[0 .. idx]);
5044+ // Preserve leading zero digits in the Lehmer code to ensure lexicographic order
5045+
5046+ reverse(fac[0 .. range.length]);
5047+ }
5048+
5049+ size_t len = range.length;
5050+
50405051 ElementType! Range tmp;
50415052 size_t i = 0 ;
50425053
5043- for (; i < idx ; ++ i)
5054+ for (; i < len ; ++ i)
50445055 {
50455056 size_t re = fac[i];
50465057 tmp = range[re + i];
@@ -5055,6 +5066,41 @@ if (isRandomAccessRange!Range && hasLength!Range)
50555066}
50565067
50575068// /
5069+ pure @safe unittest
5070+ {
5071+ auto src = [0 , 1 , 2 ];
5072+ auto rslt = [0 , 2 , 1 ];
5073+
5074+ src = nthPermutation(src, 1 );
5075+ assert (src == rslt);
5076+ }
5077+ pure @safe unittest
5078+ {
5079+ auto src = [0 , 1 , 2 , 3 ];
5080+ auto rslt = [0 , 3 , 1 , 2 ];
5081+
5082+ src = nthPermutation(src, 4 );
5083+ assert (src == rslt);
5084+ }
5085+ pure @safe unittest
5086+ {
5087+ auto src = [0 , 1 , 2 ];
5088+ auto rslt = [0 , 2 , 1 ];
5089+
5090+ bool worked = nthPermutationImpl(src, 1 );
5091+ assert (worked);
5092+ assert (src == rslt);
5093+ }
5094+ pure @safe unittest
5095+ {
5096+ auto src = [0 , 1 , 2 , 3 ];
5097+ auto rslt = [0 , 3 , 1 , 2 ];
5098+
5099+ bool worked = nthPermutationImpl(src, 4 );
5100+ assert (worked);
5101+ assert (src == rslt);
5102+ }
5103+
50585104pure @safe unittest
50595105{
50605106 auto src = [0 , 1 , 2 , 3 , 4 , 5 , 6 ];
@@ -5076,7 +5122,7 @@ pure @safe unittest
50765122pure @safe unittest
50775123{
50785124 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 ];
5125+ auto rslt = [0 , 1 , 2 , 3 , 8 , 4 , 10 , 6 , 5 , 7 , 9 ];
50805126
50815127 src = nthPermutation(src, 2982 );
50825128 assert (src == rslt);
@@ -5097,7 +5143,7 @@ pure @safe unittest
50975143 import std.meta : AliasSeq;
50985144
50995145 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 ];
5146+ auto rsl = [0 , 1 , 2 , 3 , 8 , 4 , 10 , 6 , 5 , 7 , 9 ];
51015147
51025148 foreach (T; AliasSeq! (
51035149 DummyRange! (ReturnBy.Reference, Length.Yes, RangeType.Random , int []),
0 commit comments