Next highest int from digits: Difference between revisions

Added FreeBASIC
(Added FreeBASIC)
 
(37 intermediate revisions by 23 users not shown)
Line 4:
integer using only the given digits<sup>*1</sup>.
 
* &nbsp; Numbers will not be padded to the left with zeroes.
* &nbsp; Use all given digits, with their given multiplicity. (If a digit appears twice in the input number, it should appear twice in the result).
* &nbsp; If there is no next higesthighest integer return zero.
 
 
:<sup>*1</sup> &nbsp; Alternatively phrased as: &nbsp; "Find the smallest integer larger than the (positive or zero) integer &nbsp; '''N'''
:: which can be obtained by reordering the (base ten) digits of &nbsp; '''N'''".
 
<br><sup>*1</sup> Alternatively phrased as: "Find the smallest integer larger than the (positive or zero) integer N which can be obtained by reordering the (base 10) digits of N".
 
;Algorithm 1:
# &nbsp; Generate all the permutations of the digits and sort into numeric order.
# &nbsp; Find the number in the list.
# &nbsp; Return the next highest number from the list.
 
 
The above could prove slow and memory hungry for numbers with large numbers of
Line 20 ⟶ 24:
 
;Algorithm 2:
# &nbsp; Scan right-to-left through the digits of the number until you find a digit with a larger digit somewhere to the right of it.
# &nbsp; Exchange that digit with the digit on the right that is ''both'' more than it, and closest to it.
# &nbsp; Order the digits to the right of this position, after the swap; lowest-to-highest, left-to-right. (I.e. so they form the lowest numerical representation)
 
 
E.g:
'''E.g.:'''
<pre>
n = 12453
Line 38 ⟶ 43:
 
This second algorithm is faster and more memory efficient, but implementations
may be harder to test. One method of testing ,(as used in developing the task),
 
is to compare results from both algorithms for random numbers generated from a
One method of testing, (as used in developing the task), &nbsp; is to compare results from both
range that the first algorithm can handle.
algorithms for random numbers generated from a range that the first algorithm can handle.
 
 
;Task requirements:
Calculate the next highest int from the digits of the following numbers:
:* &nbsp; 0
:* &nbsp; 9
:* &nbsp; 12
:* &nbsp; 21
:* &nbsp; 12453
:* &nbsp; 738440
:* &nbsp; 45072010
:* &nbsp; 95322020
 
 
;Optional stretch goal:
:* &nbsp; 9589776899767587796600
<br><br>
 
=={{header|11l}}==
{{trans|Python: Algorithm 2}}
 
<syntaxhighlight lang="11l">F closest_more_than(n, lst)
V large = max(lst) + 1
R lst.index(min(lst, key' x -> (I x <= @n {@large} E x)))
 
F nexthigh(n)
V this = reversed(Array(n.map(digit -> Int(digit))))
V mx = this[0]
L(digit) this[1..]
V i = L.index + 1
I digit < mx
V mx_index = closest_more_than(digit, this[0 .< i + 1])
swap(&this[mx_index], &this[i])
this.sort_range(0 .< i, reverse' 1B)
R reversed(this).map(d -> String(d)).join(‘’)
E I digit > mx
mx = digit
R ‘0’
 
L(x) [‘0’, ‘9’, ‘12’, ‘21’, ‘12453’, ‘738440’, ‘45072010’, ‘95322020’,
‘9589776899767587796600’]
print(‘#12 -> #12’.format(x, nexthigh(x)))</syntaxhighlight>
 
{{out}}
<pre>
0 -> 0
9 -> 0
12 -> 21
21 -> 0
12453 -> 12534
738440 -> 740348
45072010 -> 45072100
95322020 -> 95322200
9589776899767587796600 -> 9589776899767587900667
</pre>
 
=={{header|ALGOL 68}}==
{{works with|ALGOL 68G|Any - tested with release 2.8.3.win32}}
Should work with any Algol 68 implementation if LONG INT is large to hold the stretch test case.<br>
Implements algorithm 2.
<syntaxhighlight lang="algol68">
BEGIN # find the next integer > a given integer with the same digits #
 
OP - = ( CHAR a, b )INT: ABS a - ABS b; # character subtraction #
PROC swap = ( REF STRING s, INT a, b )VOID: # swap chars at a and b in s #
BEGIN CHAR t = s[ a ]; s[ a ] := s[ b ]; s[ b ] := t END;
 
# returns the next integer greater than v with the same digits as v #
OP NEXT = ( LONG INT v )LONG INT:
BEGIN
LONG INT result := 0;
STRING s := whole( v, 0 );
INT c pos := UPB s - 1;
# find the rightmost digit that has a lower digit to the left #
WHILE IF c pos < LWB s
THEN FALSE
ELSE s[ c pos ] >= s[ c pos + 1 ]
FI
DO
c pos -:=1
OD;
IF c pos >= LWB s THEN
# the digit at c pos is lower than one to its right #
# swap the lower digit with the smallest right digit greater #
# than the lower digit #
CHAR c = s[ c pos ];
INT min pos := c pos + 1;
INT min diff := s[ c pos + 1 ] - c;
FOR m pos FROM c pos + 2 TO UPB s DO
IF s[ m pos ] > c THEN
IF INT this diff = s[ m pos ] - c;
this diff < min diff
THEN
min diff := this diff;
min pos := m pos
FI
FI
OD;
swap( s, min pos, c pos );
# sort the right digits #
FOR u FROM UPB s - 1 BY -1 TO c pos + 1
WHILE BOOL sorted := TRUE;
FOR p FROM c pos + 1 BY 1 TO u DO
IF s[ p ] > s[ p + 1 ] THEN
swap( s, p, p + 1 );
sorted := FALSE
FI
OD;
NOT sorted
DO SKIP OD;
# convert back to an integer #
result := s[ LWB s ] - "0";
FOR i FROM LWB s + 1 TO UPB s DO
result *:= 10 +:= s[ i ] - "0"
OD
FI;
result
END # NEXT # ;
 
# task test cases #
[]LONG INT tests = ( 0, 9, 12, 21, 12453, 738440, 45072010, 95322020
, 9589776899767587796600
);
FOR i FROM LWB tests TO UPB tests DO
print( ( whole( tests[ i ], -24 ), " -> ", whole( NEXT tests[ i ], 0 ), newline ) )
OD
END
</syntaxhighlight>
{{out}}
<pre>
0 -> 0
9 -> 0
12 -> 21
21 -> 0
12453 -> 12534
738440 -> 740348
45072010 -> 45072100
95322020 -> 95322200
9589776899767587796600 -> 9589776899767587900667
</pre>
 
=={{header|Arturo}}==
<syntaxhighlight lang="arturo">canHaveGreater?: function [n][
mydigs: digits n
maxdigs: reverse sort mydigs
 
return some? 0..dec size mydigs 'i ->
maxdigs\[i] > mydigs\[i]
]
nextHighest: function [n][
if not? canHaveGreater? n -> return n
 
ndigs: sort digits n
i: n + 1
while [ndigs <> sort digits i]->
i: i + 1
 
return i
]
 
loop [0, 9, 12, 21, 12453, 738440, 45072010, 95322020] 'num ->
print [pad (to :string num) 9 "->" nextHighest num]</syntaxhighlight>
 
{{out}}
 
<pre> 0 -> 0
9 -> 9
12 -> 21
21 -> 21
12453 -> 12534
738440 -> 740348
45072010 -> 45072100
95322020 -> 95322200</pre>
 
=={{header|AutoHotkey}}==
===Permutation Version===
<syntaxhighlight lang="autohotkey">Next_highest_int(num){
Arr := []
for i, v in permute(num)
Arr[v] := true
for n, v in Arr
if found
return n
else if (n = num)
found := true
return 0
}
permute(str, k:=0, l:=1){
static res:=[]
r := StrLen(str)
k := k ? k : r
if (l = r)
return SubStr(str, 1, k)
i := l
while (i <= r){
str := swap(str, l, i)
x := permute(str, k, l+1)
if (x<>"")
res.push(x)
str := swap(str, l, i++)
}
if (l=1)
return x:=res, res := []
}
swap(str, l, i){
x := StrSplit(str), var := x[l], x[l] := x[i], x[i] := var
Loop, % x.count()
res .= x[A_Index]
return res
}</syntaxhighlight>
Examples:<syntaxhighlight lang="autohotkey">MsgBox % "" Next_highest_int(0)
. "`n" Next_highest_int(9)
. "`n" Next_highest_int(12)
. "`n" Next_highest_int(21)
. "`n" Next_highest_int(12453)
. "`n" Next_highest_int(738440)
. "`n" Next_highest_int(45072010)
. "`n" Next_highest_int(95322020)</syntaxhighlight>
{{out}}
<pre>0
0
21
0
12534
740348
45072100
95322200</pre>
===Scanning Version===
<syntaxhighlight lang="autohotkey">Next_highest_int(num){
Loop % StrLen(num){
i := A_Index
if (left := SubStr(num, 0-i, 1)) < (right := SubStr(num, 1-i, 1))
break
}
if !(left < right)
return 0
x := StrLen(num) - i
num := swap(num, x, x+1)
Rdigits := rSort(SubStr(num, 1-i))
return SubStr(num,1, StrLen(num)-StrLen(Rdigits)) . Rdigits
}
swap(str, l, i){
x := StrSplit(str), var := x[l], x[l] := x[i], x[i] := var
Loop, % x.count()
res .= x[A_Index]
return res
}
rSort(num){
Arr := []
for i, v in StrSplit(num)
Arr[v, i] := v
for i, obj in Arr
for k, v in obj
res .= v
return res
}</syntaxhighlight>
Examples:<syntaxhighlight lang="autohotkey">MsgBox % "" Next_highest_int(0)
. "`n" Next_highest_int(9)
. "`n" Next_highest_int(12)
. "`n" Next_highest_int(21)
. "`n" Next_highest_int(12453)
. "`n" Next_highest_int(738440)
. "`n" Next_highest_int(45072010)
. "`n" Next_highest_int(95322020)
. "`n" Next_highest_int("9589776899767587796600") ; pass long numbers as text (between quotes)</syntaxhighlight>
{{out}}
<pre>0
0
21
0
12534
780344
45072100
95322200
9589776899767587900667</pre>
 
=={{header|C}}==
<syntaxhighlight lang="c">#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
 
void swap(char* str, int i, int j) {
char c = str[i];
str[i] = str[j];
str[j] = c;
}
 
void reverse(char* str, int i, int j) {
for (; i < j; ++i, --j)
swap(str, i, j);
}
 
bool next_permutation(char* str) {
int len = strlen(str);
if (len < 2)
return false;
for (int i = len - 1; i > 0; ) {
int j = i, k;
if (str[--i] < str[j]) {
k = len;
while (str[i] >= str[--k]) {}
swap(str, i, k);
reverse(str, j, len - 1);
return true;
}
}
return false;
}
 
uint32_t next_highest_int(uint32_t n) {
char str[16];
snprintf(str, sizeof(str), "%u", n);
if (!next_permutation(str))
return 0;
return strtoul(str, 0, 10);
}
 
int main() {
uint32_t numbers[] = {0, 9, 12, 21, 12453, 738440, 45072010, 95322020};
const int count = sizeof(numbers)/sizeof(int);
for (int i = 0; i < count; ++i)
printf("%d -> %d\n", numbers[i], next_highest_int(numbers[i]));
// Last one is too large to convert to an integer
const char big[] = "9589776899767587796600";
char next[sizeof(big)];
memcpy(next, big, sizeof(big));
next_permutation(next);
printf("%s -> %s\n", big, next);
return 0;
}</syntaxhighlight>
 
{{out}}
<pre>
0 -> 0
9 -> 0
12 -> 21
21 -> 0
12453 -> 12534
738440 -> 740348
45072010 -> 45072100
95322020 -> 95322200
9589776899767587796600 -> 9589776899767587900667
</pre>
 
 
=={{header|C#}}==
{{trans|Java}}
<syntaxhighlight lang="C#">
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Numerics;
using System.Text;
 
public class NextHighestIntFromDigits
{
public static void Main(string[] args)
{
foreach (var s in new string[] { "0", "9", "12", "21", "12453", "738440", "45072010", "95322020", "9589776899767587796600", "3345333" })
{
Console.WriteLine($"{Format(s)} -> {Format(Next(s))}");
}
TestAll("12345");
TestAll("11122");
}
 
private static string Format(string s)
{
return BigInteger.Parse(s).ToString("N0", CultureInfo.InvariantCulture);
}
 
private static void TestAll(string s)
{
Console.WriteLine($"Test all permutations of: {s}");
var sOrig = s;
var sPrev = s;
int count = 1;
 
// Check permutation order. Each is greater than the last
bool orderOk = true;
var uniqueMap = new Dictionary<string, int>();
uniqueMap[s] = 1;
while ((s = Next(s)) != "0")
{
count++;
if (BigInteger.Parse(s) < BigInteger.Parse(sPrev))
{
orderOk = false;
}
if (uniqueMap.ContainsKey(s))
{
uniqueMap[s]++;
}
else
{
uniqueMap[s] = 1;
}
sPrev = s;
}
Console.WriteLine($" Order: OK = {orderOk}");
 
// Test last permutation
var reverse = Reverse(sOrig);
Console.WriteLine($" Last permutation: Actual = {sPrev}, Expected = {reverse}, OK = {sPrev == reverse}");
 
// Check permutations unique
bool unique = true;
foreach (var key in uniqueMap.Keys)
{
if (uniqueMap[key] > 1)
{
unique = false;
}
}
Console.WriteLine($" Permutations unique: OK = {unique}");
 
// Check expected count.
var charMap = new Dictionary<char, int>();
foreach (var c in sOrig)
{
if (charMap.ContainsKey(c))
{
charMap[c]++;
}
else
{
charMap[c] = 1;
}
}
BigInteger permCount = Factorial(sOrig.Length);
foreach (var c in charMap.Keys)
{
permCount /= Factorial(charMap[c]);
}
Console.WriteLine($" Permutation count: Actual = {count}, Expected = {permCount}, OK = {count == permCount}");
}
 
private static BigInteger Factorial(int n)
{
BigInteger fact = 1;
for (int num = 2; num <= n; num++)
{
fact *= num;
}
return fact;
}
 
private static string Next(string s)
{
var sb = new StringBuilder();
int index = s.Length - 1;
// Scan right-to-left through the digits of the number until you find a digit with a larger digit somewhere to the right of it.
while (index > 0 && s[index - 1] >= s[index])
{
index--;
}
// Reached beginning. No next number.
if (index == 0)
{
return "0";
}
 
// Find digit on the right that is both more than it, and closest to it.
int index2 = index;
for (int i = index + 1; i < s.Length; i++)
{
if (s[i] < s[index2] && s[i] > s[index - 1])
{
index2 = i;
}
}
 
// Found data, now build string
// Beginning of String
if (index > 1)
{
sb.Append(s.Substring(0, index - 1));
}
 
// Append found, place next
sb.Append(s[index2]);
 
// Get remaining characters
List<char> chars = new List<char>();
chars.Add(s[index - 1]);
for (int i = index; i < s.Length; i++)
{
if (i != index2)
{
chars.Add(s[i]);
}
}
 
// Order the digits to the right of this position, after the swap; lowest-to-highest, left-to-right.
chars.Sort();
foreach (var c in chars)
{
sb.Append(c);
}
return sb.ToString();
}
 
private static string Reverse(string s)
{
var charArray = s.ToCharArray();
Array.Reverse(charArray);
return new string(charArray);
}
}
</syntaxhighlight>
{{out}}
<pre>
0 -> 0
9 -> 0
12 -> 21
21 -> 0
12,453 -> 12,534
738,440 -> 740,348
45,072,010 -> 45,072,100
95,322,020 -> 95,322,200
9,589,776,899,767,587,796,600 -> 9,589,776,899,767,587,900,667
3,345,333 -> 3,353,334
Test all permutations of: 12345
Order: OK = True
Last permutation: Actual = 54321, Expected = 54321, OK = True
Permutations unique: OK = True
Permutation count: Actual = 120, Expected = 120, OK = True
Test all permutations of: 11122
Order: OK = True
Last permutation: Actual = 22111, Expected = 22111, OK = True
Permutations unique: OK = True
Permutation count: Actual = 10, Expected = 10, OK = True
 
</pre>
 
 
=={{header|C++}}==
{{trans|Factor}}
{{libheader|GMP}}
This solution makes use of std::next_permutation, which is essentially the same as Algorithm 2.
<syntaxhighlight lang="cpp">#include <algorithm>
#include <iostream>
#include <sstream>
 
#include <gmpxx.h>
 
using integer = mpz_class;
 
std::string to_string(const integer& n) {
std::ostringstream out;
out << n;
return out.str();
}
 
integer next_highest(const integer& n) {
std::string str(to_string(n));
if (!std::next_permutation(str.begin(), str.end()))
return 0;
return integer(str);
}
 
int main() {
for (integer n : {0, 9, 12, 21, 12453, 738440, 45072010, 95322020})
std::cout << n << " -> " << next_highest(n) << '\n';
integer big("9589776899767587796600");
std::cout << big << " -> " << next_highest(big) << '\n';
return 0;
}</syntaxhighlight>
 
{{out}}
<pre>
0 -> 0
9 -> 0
12 -> 21
21 -> 0
12453 -> 12534
738440 -> 740348
45072010 -> 45072100
95322020 -> 95322200
9589776899767587796600 -> 9589776899767587900667
</pre>
 
=={{header|D}}==
{{trans|Java}}
<syntaxhighlight lang="d">import std.algorithm;
import std.array;
import std.conv;
import std.stdio;
 
string next(string s) {
auto sb = appender!string;
auto index = s.length - 1;
 
// Scan right-to-left through the digits of the number until you find a digit with a larger digit somewhere to the right of it.
while (index > 0 && s[index - 1] >= s[index]) {
index--;
}
// Reached beginning. No next number.
if (index == 0) {
return "0";
}
 
// Find digit on the right that is both more than it, and closest to it.
auto index2 = index;
foreach (i; index + 1 .. s.length) {
if (s[i] < s[index2] && s[i] > s[index - 1]) {
index2 = i;
}
}
 
// Found data, now build string
// Beginning of String
if (index > 1) {
sb ~= s[0 .. index - 1];
}
 
// Append found, place next
sb ~= s[index2];
 
// Get remaining characters
auto chars = [cast(dchar) s[index - 1]];
foreach (i; index .. s.length) {
if (i != index2) {
chars ~= s[i];
}
}
 
// Order the digits to the right of this position, after the swap; lowest-to-highest, left-to-right.
chars.sort;
sb ~= chars;
 
return sb.data;
}
 
long factorial(long n) {
long fact = 1;
foreach (num; 2 .. n + 1) {
fact *= num;
}
return fact;
}
 
void testAll(string s) {
writeln("Test all permutations of: ", s);
string sOrig = s;
string sPrev = s;
int count = 1;
 
// Check permutation order. Each is greater than the last
bool orderOk = true;
int[string] uniqueMap = [s: 1];
while (true) {
s = next(s);
if (s == "0") {
break;
}
 
count++;
if (s.to!long < sPrev.to!long) {
orderOk = false;
}
uniqueMap.update(s, {
return 1;
}, (int a) {
return a + 1;
});
sPrev = s;
}
writeln(" Order: OK = ", orderOk);
 
// Test last permutation
auto reverse = sOrig.dup.to!(dchar[]).reverse.to!string;
writefln(" Last permutation: Actual = %s, Expected = %s, OK = %s", sPrev, reverse, sPrev == reverse);
 
// Check permutations unique
bool unique = true;
foreach (k, v; uniqueMap) {
if (v > 1) {
unique = false;
break;
}
}
writeln(" Permutations unique: OK = ", unique);
 
// Check expected count.
int[char] charMap;
foreach (c; sOrig) {
charMap.update(c, {
return 1;
}, (int v) {
return v + 1;
});
}
long permCount = factorial(sOrig.length);
foreach (k, v; charMap) {
permCount /= factorial(v);
}
writefln(" Permutation count: Actual = %d, Expected = %d, OK = %s", count, permCount, count == permCount);
}
 
void main() {
foreach (s; ["0", "9", "12", "21", "12453", "738440", "45072010", "95322020", "9589776899767587796600", "3345333"]) {
writeln(s, " -> ", next(s));
}
 
testAll("12345");
testAll("11122");
}</syntaxhighlight>
{{out}}
<pre>0 -> 0
9 -> 0
12 -> 21
21 -> 0
12453 -> 12534
738440 -> 740348
45072010 -> 45072100
95322020 -> 95322200
9589776899767587796600 -> 9589776899767587900667
3345333 -> 3353334
Test all permutations of: 12345
Order: OK = true
Last permutation: Actual = 54321, Expected = 54321, OK = true
Permutations unique: OK = true
Permutation count: Actual = 120, Expected = 120, OK = true
Test all permutations of: 11122
Order: OK = true
Last permutation: Actual = 22111, Expected = 22111, OK = true
Permutations unique: OK = true
Permutation count: Actual = 10, Expected = 10, OK = true</pre>
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{libheader| System.Generics.Collections}}
{{Trans|Go}}
<syntaxhighlight lang="delphi">
program Next_highest_int_from_digits;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils,
System.Generics.Collections;
 
function StrToBytes(str: AnsiString): TArray<byte>;
begin
SetLength(result, Length(str));
Move(Pointer(str)^, Pointer(result)^, Length(str));
end;
 
function BytesToStr(bytes: TArray<byte>): AnsiString;
begin
SetLength(Result, Length(bytes));
Move(Pointer(bytes)^, Pointer(Result)^, Length(bytes));
end;
 
function Commatize(s: string): string;
begin
var le := length(s);
var i := le - 3;
while i >= 1 do
begin
s := s.Substring(0, i) + ',' + s.Substring(i);
inc(i, -3);
end;
Result := s;
end;
 
function Permute(s: string): TArray<string>;
var
res: TArray<string>;
b: string;
 
procedure rc(np: Integer);
begin
if np = 1 then
begin
SetLength(res, Length(res) + 1);
res[High(res)] := b;
exit;
end;
 
var np1 := np - 1;
var pp := length(b) - np1;
rc(np1);
for var i := pp downto 1 do
begin
var tmp := b[i + 1];
b[i + 1] := b[i];
b[i] := tmp;
rc(np1);
end;
 
var w := b[1];
delete(b, 1, 1);
Insert(w, b, pp + 1);
end;
 
begin
if s.Length = 0 then
exit;
 
res := [];
b := s;
rc(length(b));
result := res;
end;
 
procedure Algorithm1(nums: TArray<string>);
begin
writeln('Algorithm 1');
writeln('-----------');
for var num in nums do
begin
var perms := permute(num);
var le := length(perms);
if le = 0 then
Continue;
 
TArray.Sort<string>(perms);
var ix := 0;
TArray.BinarySearch<string>(perms, num, ix);
 
var next := '';
if ix < le - 1 then
for var i := ix + 1 to le - 1 do
if perms[i] > num then
begin
next := perms[i];
Break;
end;
if length(next) > 0 then
writeln(format('%29s -> %s', [Commatize(num), Commatize(next)]))
else
writeln(format('%29s -> 0', [Commatize(num)]));
end;
writeln;
end;
 
procedure Algorithm2(nums: TArray<string>);
var
ContinueMainFor: boolean;
begin
 
writeln('Algorithm 2');
writeln('-----------');
 
for var num in nums do
begin
ContinueMainFor := false;
var le := num.Length;
if le = 0 then
Continue;
 
var b := StrToBytes(num);
 
var max := b[le - 1];
var mi := le - 1;
for var i := le - 2 downto 0 do
begin
if b[i] < max then
begin
var min := max - b[i];
for var j := mi + 1 to le - 1 do
begin
var min2 := b[j] - b[i];
if (min2 > 0) and (min2 < min) then
begin
min := min2;
mi := j;
end;
end;
var tmp := b[i];
b[i] := b[mi];
b[mi] := tmp;
var c := copy(b, i + 1, le);
TArray.Sort<byte>(c);
 
var next: string := BytesToStr(copy(b, 0, i + 1));
next := next + BytesToStr(c);
writeln(format('%29s -> %s', [Commatize(num), Commatize(next)]));
ContinueMainFor := true;
Break;
end
else if b[i] > max then
begin
max := b[i];
mi := i;
end;
end;
if ContinueMainFor then
Continue;
writeln(format('%29s -> 0', [Commatize(num)]));
end;
end;
 
begin
var nums: TArray<string> := ['0', '9', '12', '21', '12453', '738440',
'45072010', '95322020'];
algorithm1(nums); // exclude the last one
 
SetLength(nums, Length(nums) + 1);
nums[High(nums)] := '9589776899767587796600';
 
algorithm2(nums); // include the last one
{$IFNDEF UNIX}
readln; {$ENDIF}
end.</syntaxhighlight>
 
=={{header|EasyLang}}==
{{trans|C}}
<syntaxhighlight>
proc reverse i j . dig[] .
while i < j
swap dig[i] dig[j]
i += 1
j -= 1
.
.
proc next_perm . dig[] .
if len dig[] >= 2
for i = 2 to len dig[]
if dig[i] < dig[i - 1]
k = 1
while dig[i] >= dig[k]
k += 1
.
swap dig[i] dig[k]
reverse 1 i - 1 dig[]
return
.
.
.
dig[] = [ ]
.
func next_highest n .
while n > 0
digs[] &= n mod 10
n = n div 10
.
next_perm digs[]
for i = len digs[] downto 1
r = r * 10 + digs[i]
.
return r
.
nums[] = [ 0 9 12 21 12453 738440 45072010 95322020 ]
for n in nums[]
print n & " -> " & next_highest n
.
</syntaxhighlight>
 
 
=={{header|Factor}}==
This uses the <code>next-permutation</code> word from the <code>math.combinatorics</code> vocabulary. <code>next-permutation</code> wraps around and returns the smallest lexicographic permutation after the largest one, so additionally we must check if we're at the largest permutation and return zero if so. See the implementation of <code>next-permutation</code> [https://docs.factorcode.org/content/word-next-permutation%2Cmath.combinatorics.html here].
{{works with|Factor|0.99 2020-01-23}}
<langsyntaxhighlight lang="factor">USING: formatting grouping kernel math math.combinatorics
math.parser sequences ;
 
Line 71 ⟶ 1,014:
9589776899767587796600
}
[ dup next-highest "%d -> %d\n" printf ] each</langsyntaxhighlight>
{{out}}
<pre>
Line 84 ⟶ 1,027:
9589776899767587796600 -> 9589776899767587900667
</pre>
 
=={{header|FreeBASIC}}==
===algorithm 1===
{{trans|Python}}
<syntaxhighlight lang="vbnet">Function factorial(n As Integer) As Uinteger
Return Iif(n = 0, 1, n * factorial(n - 1))
End Function
 
Sub swap_(s As String, i As Integer, j As Integer)
Dim As String temp = Mid(s, i, 1)
Mid(s, i, 1) = Mid(s, j, 1)
Mid(s, j, 1) = temp
End Sub
 
Sub permute(s As String, l As Integer, r As Integer, perms() As String)
If l = r Then
Redim Preserve perms(Ubound(perms) + 1)
perms(Ubound(perms)) = s
Else
For i As Uinteger = l To r
swap_(s, l, i)
permute(s, l + 1, r, perms())
swap_(s, l, i) ' backtrack
Next i
End If
End Sub
 
Sub bubbleSort(arr() As String)
Dim As Integer i, j, n = Ubound(arr)
Dim As String temp
For i = 0 To n - 1
For j = 0 To n - i - 1
If arr(j) > arr(j + 1) Then
temp = arr(j)
arr(j) = arr(j + 1)
arr(j + 1) = temp
End If
Next j
Next i
End Sub
 
Function nextHigh1(Byref n As String) As String
Dim As String perms()
Dim As Uinteger i, idx
permute(n, 1, Len(n), perms())
bubbleSort perms()
Dim As Uinteger k = Ubound(perms)
For i = 0 To k
If perms(i) = n Then
idx = i
Exit For
End If
Next i
Return Iif(idx < k, perms(idx + 1), "0")
End Function
 
Dim As String tests1(7) = {"0", "9", "12", "21", "12453", "738440", "45072010", "95322020"}
Dim As Double t0 = Timer
For i As Uinteger = 0 To Ubound(tests1)
Print tests1(i); " => "; nextHigh1(tests1(i))
Next i
Print Chr(10); Timer - t0; "sec."</syntaxhighlight>
{{out}}
<pre>0 => 0
9 => 0
12 => 21
21 => 0
12453 => 12534
738440 => 738440
45072010 => 45072010
95322020 => 95322020
 
67.04065610002726sec.</pre>
===algorithm 2===
{{trans|Phix}}
<syntaxhighlight lang="vbnet">Function sort(s As String) As String
Dim As Uinteger i, j, n = Len(s)
Dim As String temp
For i = 1 To n
For j = i + 1 To n
If Asc(Mid(s, i, 1)) > Asc(Mid(s, j, 1)) Then
temp = Mid(s, i, 1)
Mid(s, i, 1) = Mid(s, j, 1)
Mid(s, j, 1) = temp
End If
Next j
Next i
Return s
End Function
 
Function rfind(c As String, s As String) As Uinteger
Return Instr(s, c)
End Function
 
Function nextHigh2(n As String) As String
Dim As Uinteger hi = Asc(Right(n, 1))
Dim As Uinteger i, ni, idx
Dim As String sr
For i = Len(n) - 1 To 1 Step -1
ni = Asc(Mid(n, i, 1))
If ni < hi Then
sr = sort(Mid(n, i))
idx = rfind(Chr(ni), sr) + 1
Mid(n, i, 1) = Mid(sr, idx, 1)
Mid(sr, idx, 1) = ""
Mid(n, i + 1) = sr
Return n
End If
hi = Iif(hi > ni, hi, ni)
Next i
Return "0"
End Function
 
Dim As String tests2(8) = { "0", "9", "12", "21", "12453", _
"738440", "45072010", "95322020", "9589776899767587796600" }
Dim As Double t1 = Timer
For i As Uinteger = 0 To Ubound(tests2)
Print tests2(i); " => "; nextHigh2(tests2(i))
Next i
Print Chr(10); Timer - t1; "sec."</syntaxhighlight>
{{out}}
<pre>0 => 0
9 => 0
12 => 21
21 => 0
12453 => 12534
738440 => 740344
45072010 => 45072000
95322020 => 95322000
9589776899767587796600 => 9589776899767587900667
 
0.004686999949626625sec.</pre>
 
=={{header|Go}}==
This uses a modified version of the recursive code in the [[https://rosettacode.org/wiki/Permutations#Go Permutations#Go]] task.
<langsyntaxhighlight lang="go">package main
 
import (
Line 201 ⟶ 1,285:
algorithm1(nums[:len(nums)-1]) // exclude the last one
algorithm2(nums) // include the last one
}</langsyntaxhighlight>
 
{{out}}
Line 235 ⟶ 1,319:
{{Trans|Python}}
(Generator version)
<langsyntaxhighlight lang="haskell">import Data.List (nub, permutations, sort)
import Data.Bool (bool)
 
digitShuffleSuccessors :: Integer -> [Integer]
Line 242 ⟶ 1,325:
(fmap . (+) <*> (nub . sort . concatMap go . permutations . show)) n
where
go ds =
let| delta0 >= (readdelta ds :: Integer) -= n[]
in| boolotherwise = [delta] [] (0 >= delta)
where
delta = (read ds :: Integer) - n
 
--------------------------- TEST- ---------------------------
main :: IO ()
main =
Line 258 ⟶ 1,343:
12
' '
(show (length harvest) ++<> " of " ++<> show (length xs) ++<> ": ") ++<>
show harvest)
digitShuffleSuccessors
[0, 9, 12, 21, 12453, 738440, 45072010, 95322020]
 
-------------------------- DISPLAY --------------------------
fTable :: String -> (a -> String) -> (b -> String) -> (a -> b) -> [a] -> String
fTable s xShow fxShow f xs =
unlines $
s : fmap (((++<>) . rjust w ' ' . xShow) <*> ((" -> " ++<>) . fxShow . f)) xs
where
w = maximum (length . xShow <$> xs)
 
rjust :: Int -> Char -> String -> String
rjust n c = drop . length <*> (replicate n c ++<>)</langsyntaxhighlight>
{{Out}}
<pre>Taking up to 5 digit-shuffle successors of a positive integer:
Line 290 ⟶ 1,375:
(The digit-swap approach makes it feasible to obtain successors of this kind for much larger numbers)
 
<langsyntaxhighlight lang="haskell">import Data.List (unfoldr)
 
------------------- MINIMAL DIGIT-SWAPS ------------------
digitShuffleSuccessors
 
:: Integral b
digitShuffleSuccessors :: Integral b => b -> [b]
digitShuffleSuccessors n =
unDigits <$> unfoldr nexts (go $ reversedDigits n)
let go = minimalSwap . splitBy (>)
where
in unDigits <$>
go = minimalSwap . splitBy (>)
unfoldr
nexts (\ds ->x
| null x = if null dsNothing
| otherwise = Just (((,) <*> go then. Nothingreverse) x)
 
else Just (ds, (go . reverse) ds))
 
(go (reversedDigits n))
minimalSwap :: Ord a => ([a], [a]) -> [a]
minimalSwap ([], x : y : xs) = reverse (y : x : xs)
:: Ord a
=> ([a], [a]) -> [a]
minimalSwap ([], x:y:xs) = reverse (y : x : xs)
minimalSwap ([], xs) = []
minimalSwap (_, []) = []
minimalSwap (reversedSuffix, pivot : prefix) =
letreverse (less, h :more prefix) =<> breakless (<> (pivot) reversedSuffix: more)
where
in reverse (h : prefix) ++ less ++ pivot : more
(less, h : more) = break (> pivot) reversedSuffix
 
---------------------------TEST----------------------------
 
--------------------------- TEST -------------------------
main :: IO ()
main = do
putStrLn $
fTable
( "Taking up to 5 digit-shuffle successors of a positive integer:\n"
<> "of a positive integer:\n"
)
show
( \xs ->
let harvest = take 5 xs
in rjust
12
' '
( show (length harvest) ++<> " of " ++ show (length xs) ++ ": ") ++
<> show harvest(length xs)
<> ": "
)
<> show harvest
)
digitShuffleSuccessors
[0, 9, 12, 21, 12453, 738440, 45072010, 95322020]
putStrLn $
fTable
"Taking up to 10 digit-shuffle successors of a larger integer:\n"
show
(('\n' :) . unlines . fmap ((" " ++<>) . show))
(take 10 . digitShuffleSuccessors)
[9589776899767587796600]
 
-------------------------- GENERIC-- ------------------------
reversedDigits :: Integral a => a -> [a]
:: Integral a
=> a -> [a]
reversedDigits 0 = [0]
reversedDigits n = go n
Line 349 ⟶ 1,436:
go 0 = []
go x = rem x 10 : go (quot x 10)
 
splitBy :: (a -> a -> Bool) -> [a] -> ([a], [a])
splitBy f xs = go $ break (uncurry f) $ zip xs (tail xs)
Line 356 ⟶ 1,443:
| null ys = ([], xs)
| otherwise = (fst (head ys) : map snd ys, map snd zs)
 
unDigits :: Integral a => [a] -> a
:: (Foldable t, Num a)
=> t a -> a
unDigits = foldl (\a b -> 10 * a + b) 0
 
-------------------------- DISPLAY-- ------------------------
fTable ::
fTable :: String -> (a -> String) -> (b -> String) -> (a -> b) -> [a] -> String
String ->
(a -> String) ->
(b -> String) ->
(a -> b) ->
[a] ->
String
fTable s xShow fxShow f xs =
unlines $
s :
s : fmap (((++) . rjust w ' ' . xShow) <*> ((" -> " ++) . fxShow . f)) xs
fmap
( ((<>) . rjust w ' ' . xShow)
<*> ((" -> " <>) . fxShow . f)
)
xs
where
w = maximum (length . xShow <$> xs)
 
rjust :: Int -> Char -> String -> String
rjust n c = drop . length <*> (replicate n c ++<>)</langsyntaxhighlight>
{{Out}}
<pre>Taking up to 5 digit-shuffle successors of a positive integer:
Line 417 ⟶ 1,513:
=={{header|Java}}==
Additional testing is performed, including a number with all unique digits and a number with duplicate digits. Included test of all permutations, that the order and correct number of permutations is achieved, and that each permutation is different than all others. If a library is not used, then this testing will provide a better proof of correctness.
<langsyntaxhighlight lang="java">
import java.math.BigInteger;
import java.text.NumberFormat;
Line 543 ⟶ 1,639:
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 568 ⟶ 1,664:
</pre>
 
 
=={{header|JavaScript}}==
<syntaxhighlight lang="javascript">const compose = (...fn) => (...x) => fn.reduce((a, b) => c => a(b(c)))(...x);
const toString = x => x + '';
const reverse = x => Array.from(x).reduce((p, c) => [c, ...p], []);
const minBiggerThanN = (arr, n) => arr.filter(e => e > n).sort()[0];
const remEl = (arr, e) => {
const r = arr.indexOf(e);
return arr.filter((e,i) => i !== r);
}
 
const nextHighest = itr => {
const seen = [];
let result = 0;
for (const [i,v] of itr.entries()) {
const n = +v;
if (Math.max(n, ...seen) !== n) {
const right = itr.slice(i + 1);
const swap = minBiggerThanN(seen, n);
const rem = remEl(seen, swap);
const rest = [n, ...rem].sort();
result = [...reverse(right), swap, ...rest].join('');
break;
} else {
seen.push(n);
}
}
return result;
};
 
const check = compose(nextHighest, reverse, toString);
 
const test = v => {
console.log(v, '=>', check(v));
}
 
test(0);
test(9);
test(12);
test(21);
test(12453);
test(738440);
test(45072010);
test(95322020);
test('9589776899767587796600');
</syntaxhighlight>
{{out}}
<pre>0 => 0
9 => 0
12 => 21
21 => 0
12453 => 12534
738440 => 740348
45072010 => 45072100
95322020 => 95322200
9589776899767587796600 => 9589776899767587900667</pre>
 
=={{header|jq}}==
<syntaxhighlight lang="jq"># Generate a stream of all the permutations of the input array
def permutations:
# Given an array as input, generate a stream by inserting $x at different positions
def insert($x):
range (0; length + 1) as $pos
| .[0:$pos] + [$x] + .[$pos:];
 
if length <= 1 then .
else
.[0] as $first
| .[1:] | permutations | insert($first)
end;
 
def next_highest:
(tostring | explode) as $digits
| ([$digits | permutations] | unique) as $permutations
| ($permutations | bsearch($digits)) as $i
| if $i == (($permutations|length) - 1) then 0
else $permutations[$i+1] | implode
end;
 
def task:
0,
9,
12,
21,
12453,
738440,
45072010,
95322020;
 
task | "\(.) => \(next_highest)"</syntaxhighlight>
{{out}}
<pre>
0 => 0
9 => 0
12 => 21
21 => 0
12453 => 12534
738440 => 740348
45072010 => 45072100
95322020 => 95322200
</pre>
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">using Combinatorics, BenchmarkTools
 
asint(dig) = foldl((i, j) -> 10i + Int128(j), dig)
Line 659 ⟶ 1,856:
@btime nexthighest_2(n)
println(" for method 2 and n $n.")
</langsyntaxhighlight>{{out}}
<pre>
N 1A 1B 2
Line 682 ⟶ 1,879:
for method 2 and n 7384440.
</pre>
 
=={{header|Kotlin}}==
{{trans|Java}}
<syntaxhighlight lang="scala">import java.math.BigInteger
import java.text.NumberFormat
 
fun main() {
for (s in arrayOf(
"0",
"9",
"12",
"21",
"12453",
"738440",
"45072010",
"95322020",
"9589776899767587796600",
"3345333"
)) {
println("${format(s)} -> ${format(next(s))}")
}
testAll("12345")
testAll("11122")
}
 
private val FORMAT = NumberFormat.getNumberInstance()
private fun format(s: String): String {
return FORMAT.format(BigInteger(s))
}
 
private fun testAll(str: String) {
var s = str
println("Test all permutations of: $s")
val sOrig = s
var sPrev = s
var count = 1
 
// Check permutation order. Each is greater than the last
var orderOk = true
val uniqueMap: MutableMap<String, Int> = HashMap()
uniqueMap[s] = 1
while (next(s).also { s = it }.compareTo("0") != 0) {
count++
if (s.toLong() < sPrev.toLong()) {
orderOk = false
}
uniqueMap.merge(s, 1) { a: Int?, b: Int? -> Integer.sum(a!!, b!!) }
sPrev = s
}
println(" Order: OK = $orderOk")
 
// Test last permutation
val reverse = StringBuilder(sOrig).reverse().toString()
println(" Last permutation: Actual = $sPrev, Expected = $reverse, OK = ${sPrev.compareTo(reverse) == 0}")
 
// Check permutations unique
var unique = true
for (key in uniqueMap.keys) {
if (uniqueMap[key]!! > 1) {
unique = false
}
}
println(" Permutations unique: OK = $unique")
 
// Check expected count.
val charMap: MutableMap<Char, Int> = HashMap()
for (c in sOrig.toCharArray()) {
charMap.merge(c, 1) { a: Int?, b: Int? -> Integer.sum(a!!, b!!) }
}
var permCount = factorial(sOrig.length.toLong())
for (c in charMap.keys) {
permCount /= factorial(charMap[c]!!.toLong())
}
println(" Permutation count: Actual = $count, Expected = $permCount, OK = ${count.toLong() == permCount}")
}
 
private fun factorial(n: Long): Long {
var fact: Long = 1
for (num in 2..n) {
fact *= num
}
return fact
}
 
private fun next(s: String): String {
val sb = StringBuilder()
var index = s.length - 1
// Scan right-to-left through the digits of the number until you find a digit with a larger digit somewhere to the right of it.
while (index > 0 && s[index - 1] >= s[index]) {
index--
}
// Reached beginning. No next number.
if (index == 0) {
return "0"
}
 
// Find digit on the right that is both more than it, and closest to it.
var index2 = index
for (i in index + 1 until s.length) {
if (s[i] < s[index2] && s[i] > s[index - 1]) {
index2 = i
}
}
 
// Found data, now build string
// Beginning of String
if (index > 1) {
sb.append(s.subSequence(0, index - 1))
}
 
// Append found, place next
sb.append(s[index2])
 
// Get remaining characters
val chars: MutableList<Char> = ArrayList()
chars.add(s[index - 1])
for (i in index until s.length) {
if (i != index2) {
chars.add(s[i])
}
}
 
// Order the digits to the right of this position, after the swap; lowest-to-highest, left-to-right.
chars.sort()
for (c in chars) {
sb.append(c)
}
return sb.toString()
}</syntaxhighlight>
{{out}}
<pre>0 -> 0
9 -> 0
12 -> 21
21 -> 0
12,453 -> 12,534
738,440 -> 740,348
45,072,010 -> 45,072,100
95,322,020 -> 95,322,200
9,589,776,899,767,587,796,600 -> 9,589,776,899,767,587,900,667
3,345,333 -> 3,353,334
Test all permutations of: 12345
Order: OK = true
Last permutation: Actual = 54321, Expected = 54321, OK = true
Permutations unique: OK = true
Permutation count: Actual = 120, Expected = 120, OK = true
Test all permutations of: 11122
Order: OK = true
Last permutation: Actual = 22111, Expected = 22111, OK = true
Permutations unique: OK = true
Permutation count: Actual = 10, Expected = 10, OK = true</pre>
 
=={{header|Lua}}==
Algorithm 2 with a reverse index of digit positions.
<syntaxhighlight lang="lua">unpack = unpack or table.unpack -- <=5.2 vs >=5.3 polyfill
function nexthighestint(n)
local digits, index = {}, {[0]={},{},{},{},{},{},{},{},{},{}}
for d in tostring(n):gmatch("%d") do digits[#digits+1]=tonumber(d) end
for i,d in ipairs(digits) do index[d][#index[d]+1]=i end
local function findswap(i,d)
for D=d+1,9 do
for I=1,#index[D] do
if index[D][I] > i then return index[D][I] end
end
end
end
for i = #digits-1,1,-1 do
local j = findswap(i,digits[i])
if j then
digits[i],digits[j] = digits[j],digits[i]
local sorted = {unpack(digits,i+1)}
table.sort(sorted)
for k=1,#sorted do digits[i+k]=sorted[k] end
return table.concat(digits)
end
end
end
 
tests = { 0, 9, 12, 21, 12453, 738440, 45072010, 95322020, -- task
"9589776899767587796600", -- stretch
"123456789098765432109876543210", -- stretchier
"1234567890999888777666555444333222111000" -- stretchiest
}
for _,n in ipairs(tests) do
print(n .. " -> " .. (nexthighestint(n) or "(none)"))
end</syntaxhighlight>
{{out}}
<pre>0 -> (none)
9 -> (none)
12 -> 21
21 -> (none)
12453 -> 12534
738440 -> 740348
45072010 -> 45072100
95322020 -> 95322200
9589776899767587796600 -> 9589776899767587900667
123456789098765432109876543210 -> 123456789098765432110023456789
1234567890999888777666555444333222111000 -> 1234567891000011222333444555666777888999</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">ClearAll[NextHighestIntFromDigits]
NextHighestIntFromDigits[n_Integer?NonNegative]:=Module[{digs},
digs=IntegerDigits[n];
digs=FromDigits/@Permutations[digs];
digs=Select[digs,GreaterEqualThan[n]];
If[Length[digs]==1,First[digs],RankedMin[digs,2]]
]
NextHighestIntFromDigits/@{0,9,12,21,12453,738440,45072010,95322020}</syntaxhighlight>
{{out}}
<pre>{0, 9, 21, 21, 12534, 740348, 45072100, 95322200}</pre>
 
=={{header|Nim}}==
Using the scanning algorithm.
<syntaxhighlight lang="nim">import algorithm
 
type Digit = range[0..9]
 
func digits(n: Natural): seq[Digit] =
## Return the list of digits of "n" in reverse order.
if n == 0: return @[Digit 0]
var n = n
while n != 0:
result.add n mod 10
n = n div 10
 
func nextHighest(n: Natural): Natural =
## Find the next highest integer of "n".
## If none is found, "n" is returned.
var d = digits(n) # Warning: in reverse order.
var m = d[0]
for i in 1..d.high:
if d[i] < m:
# Find the digit greater then d[i] and closest to it.
var delta = m - d[i] + 1
var best: int
for j in 0..<i:
let diff = d[j] - d[i]
if diff > 0 and diff < delta:
# Greater and closest.
delta = diff
best = j
# Exchange digits.
swap d[i], d[best]
# Sort previous digits.
d[0..<i] = sorted(d.toOpenArray(0, i - 1), Descending)
break
else:
m = d[i]
# Compute the value from the digits.
for val in reversed(d):
result = 10 * result + val
 
 
when isMainModule:
for n in [0, 9, 12, 21, 12453, 738440, 45072010, 95322020]:
echo n, " → ", nextHighest(n)</syntaxhighlight>
 
{{out}}
<pre>0 → 0
9 → 9
12 → 21
21 → 21
12453 → 12534
738440 → 740348
45072010 → 45072100
95322020 → 95322200</pre>
 
=={{header|Perl}}==
{{trans|Raku}}
<langsyntaxhighlight lang="perl">use strict;
use warnings;
use feature 'say';
Line 715 ⟶ 2,178:
for (0, 9, 12, 21, 12453, 738440, 45072010, 95322020, 9589776899767587796600, 3345333) {
printf "%30s -> %s\n", comma($_), comma next_greatest_integer $_;
}</langsyntaxhighlight>
{{out}}
<pre> 0 -> 0
Line 730 ⟶ 2,193:
=={{header|Phix}}==
===algorithm 1===
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function nigh(string n)
<span style="color: #008080;">function</span> <span style="color: #000000;">nigh</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
sequence p = repeat("",factorial(length(n)))
<span style="color: #004080;">sequence</span> <span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">factorial</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)))</span>
for i=1 to length(p) do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
p[i] = permute(i,n)
<span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">permute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
p = sort(p)
<span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
integer k = rfind(n,p)
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rfind</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
return iff(k=length(p)?"0",p[k+1])
<span style="color: #008080;">return</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)?</span><span style="color: #008000;">"0"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
constant tests = {"0","9","12","21","12453",
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"0"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"9"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"12"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"21"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"12453"</span><span style="color: #0000FF;">,</span>
"738440","45072010","95322020"}
<span style="color: #008000;">"738440"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"45072010"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"95322020"</span><span style="color: #0000FF;">}</span>
-- (crashes on) "9589776899767587796600"}
<span style="color: #000080;font-style:italic;">-- (crashes on) "9589776899767587796600"}</span>
atom t0 = time()
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
for i=1 to length(tests) do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
string t = tests[i]
<span style="color: #004080;">string</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
printf(1,"%22s => %s\n",{t,nigh(t)})
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%22s =&gt; %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nigh</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">)})</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
?elapsed(time()-t0)</lang>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 762 ⟶ 2,227:
</pre>
===algorithm 2===
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function nigh(string n)
<span style="color: #008080;">function</span> <span style="color: #000000;">nigh</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
integer hi = n[$]
<span style="color: #004080;">integer</span> <span style="color: #000000;">hi</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">[$]</span>
for i=length(n)-1 to 1 by -1 do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
integer ni = n[i]
<span style="color: #004080;">integer</span> <span style="color: #000000;">ni</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
if ni<hi then
<span style="color: #008080;">if</span> <span style="color: #000000;">ni</span><span style="color: #0000FF;"><</span><span style="color: #000000;">hi</span> <span style="color: #008080;">then</span>
string sr = sort(n[i..$])
<span style="color: #004080;">string</span> <span style="color: #000000;">sr</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">..$])</span>
integer k = rfind(ni,sr)+1
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rfind</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ni</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sr</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span>
n[i] = sr[k]
<span style="color: #000000;">n</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span>
sr[k..k] = ""
<span style="color: #000000;">sr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">..</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
n[i+1..$] = sr
<span style="color: #000000;">n</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sr</span>
return n
<span style="color: #008080;">return</span> <span style="color: #000000;">n</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
hi = max(hi,ni)
<span style="color: #000000;">hi</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">hi</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ni</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
return "0"
<span style="color: #008080;">return</span> <span style="color: #008000;">"0"</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
constant tests = {"0","9","12","21","12453",
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"0"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"9"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"12"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"21"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"12453"</span><span style="color: #0000FF;">,</span>
"738440","45072010","95322020",
<span style="color: #008000;">"738440"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"45072010"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"95322020"</span><span style="color: #0000FF;">,</span>
"9589776899767587796600"}
<span style="color: #008000;">"9589776899767587796600"</span><span style="color: #0000FF;">}</span>
atom t0 = time()
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
for i=1 to length(tests) do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
string t = tests[i]
<span style="color: #004080;">string</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
printf(1,"%22s => %s\n",{t,nigh(t)})
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%22s =&gt; %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nigh</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">)})</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
?elapsed(time()-t0)</lang>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 805 ⟶ 2,272:
===Python: Algorithm 2===
Like Algorithm 2, but digit order is reversed for easier indexing, then reversed on return.
<langsyntaxhighlight lang="python">def closest_more_than(n, lst):
"(index of) closest int from lst, to n that is also > n"
large = max(lst) + 1
Line 829 ⟶ 2,296:
for x in [0, 9, 12, 21, 12453, 738440, 45072010, 95322020,
9589776899767587796600]:
print(f"{x:>12_d} -> {nexthigh(x):>12_d}")</langsyntaxhighlight>
 
{{out}}
Line 845 ⟶ 2,312:
===Python: Algorithm 1===
I would not try it on the stretch goal, otherwise results as above.
<langsyntaxhighlight lang="python">from itertools import permutations
 
 
Line 856 ⟶ 2,323:
if perm != this:
return int(''.join(perm))
return 0</langsyntaxhighlight>
 
===Python: Generator===
Line 862 ⟶ 2,329:
A variant which defines (in terms of a concatMap over permutations), a generator of '''all''' digit-shuffle successors for a given integer:
 
<langsyntaxhighlight lang="python">'''Digit-shuffleNext highest int from successorsdigits'''
 
from itertools import chain, islice, permutations, tee
 
 
# --------------- LAZY STREAM OF SUCCESSORS ----------------
 
# digitShuffleSuccessors :: Int -> [Int]
def digitShuffleSuccessors(n):
'''GeneratorIterator stream of all digit-shuffle
successors of n, where 0 <= n.
'''
Line 875 ⟶ 2,344:
delta = int(''.join(ds)) - n
return [] if 0 >= delta else [delta]
return map(
for x in sorted(set(concatMap(go)(
permutations(stradd(n)),
))): sorted(
yield n + x set(concatMap(go)(
permutations(str(n))
))
)
)
 
 
# TEST -------------------------- TEST --------------------------
# main :: IO ()
def main():
Line 891 ⟶ 2,364:
harvest = take(n)(ys)
return (
repr(len(harvest)) + ' of ' + repr(len(list(zs))) + ': '
repr(len(list(zs))) + ': '
)
).rjust(12, ' ') + repr(harvest)
return lambda xs: go(xs)
 
print(
Line 911 ⟶ 2,386:
 
 
# GENERIC ------------------------ GENERIC -------------------------
 
# add (+) :: Num a => a -> a -> a
def add(a):
'''Curried addition.'''
def go(b):
return a + b
return go
 
 
# concatMap :: (a -> [b]) -> [a] -> [b]
def concatMap(f):
'''The concatenation of a mapping.
'''A concatenated list or string over which a function f
The list monad can be derived by using a function f
has been mapped.
Thewhich listwraps monadits canoutput bein deriveda bylist, using an (a -> [b])empty
list to represent computational failure).
function which wraps its output in a list (using an
empty list to represent computational failure).
'''
def go(xs):
return lambda xs: chain.from_iterable(map(f, xs))
return chain.from_iterable(map(f, xs))
return go
 
 
Line 927 ⟶ 2,411:
# (b -> String) -> (a -> b) -> [a] -> String
def fTable(s):
'''Heading -> x display function -> fx display function ->
fx display function -> f -> xs -> tabular string.
'''
def gogox(xShow, fxShow, f, xs):
ysdef = [xShowgofx(xfxShow) for x in xs]:
w = max(map(len, ys) def gof(f):
return s + '\n' + '\n'.join(map def goxs(xs):
lambda x, y: y.rjust(w, ' ') + ' ->ys '= + fxShow(f[xShow(x)), for x in xs]
xs w = max(map(len, ys))
 
))
def arrowed(x, y):
return lambda xShow: lambda fxShow: lambda f: lambda xs: go(
return y.rjust(w, ' ') + (
xShow, fxShow, f, xs
' -> ' + fxShow(f(x))
)
)
return s + '\n' + '\n'.join(
map(arrowed, xs, ys)
)
return goxs
return gof
return gofx
return gox
 
 
Line 948 ⟶ 2,440:
or xs itself if n > length xs.
'''
return lambdadef go(xs): (
xs[0:n]return (
if isinstance(xs, (list, tuple)) xs[0:n]
else list(islice if isinstance(xs, n(list, tuple))
else list(islice(xs, n))
)
)
return go
 
 
# MAIN ---
if __name__ == '__main__':
main()</langsyntaxhighlight>
{{Out}}
<pre>Taking up to 5 digit-shuffle successors for each:
Line 969 ⟶ 2,463:
45072010 -> 5 of 1861: [45072100, 45100027, 45100072, 45100207, 45100270]
95322020 -> 1 of 1: [95322200]</pre>
 
=={{header|Quackery}}==
 
<code>nextperm</code> is defined at [[Permutations with some identical elements#Quackery]].
 
<syntaxhighlight lang="Quackery"> [ [] swap
[ 10 /mod
rot join swap
dup 0 = until ]
drop ] is ->digits ( n --> [ )
 
[ 0 swap
witheach
[ swap 10 * + ] ] is digits-> ( [ --> n )
 
[ dup ->digits
nextperm
digits->
tuck < not if
[ drop 0 ] ] is task ( n- -> n )
' [ 0 9 12 21 12453 738440 45072010
95322020 9589776899767587796600 ]
witheach [ task echo sp ]</syntaxhighlight>
 
{{out}}
 
<pre>0 0 21 0 12534 740348 45072100 95322200 9589776899767587900667</pre>
 
=={{header|Raku}}==
Line 975 ⟶ 2,498:
Minimal error trapping. Assumes that the passed number is an integer. Handles positive or negative integers, always returns next largest regardless (if possible).
 
<syntaxhighlight lang="raku" perl6line>use Lingua::EN::Numbers;
 
sub next-greatest-index ($str, &op = &infix:«<» ) {
Line 1,007 ⟶ 2,530:
printf "%30s -> %s%s\n", .&comma, .&next-greatest-integer < 0 ?? '' !! ' ', .&next-greatest-integer.&comma for
flat 0, (9, 12, 21, 12453, 738440, 45072010, 95322020, 9589776899767587796600, 3345333,
95897768997675877966000000000000000000000000000000000000000000000000000000000000000000).map: { $_, -$_ };</langsyntaxhighlight>
{{out}}
<pre>Next largest integer able to be made from these digits, or zero if no larger exists:
Line 1,033 ⟶ 2,556:
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/*REXX program finds the next highest positive integer from a list of decimal digits. */
parse arg n /*obtain optional arguments from the CL*/
if n='' | n="," then n= 0 9 12 21 12453 738440 45072010 95322020 /*use the defaults? */
w= length( commas( word(n, words(n) ) ) ) /*maximum width number (with commas). */
 
Line 1,051 ⟶ 2,574:
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
commas: parse arg _; do c?=length(_)-3 to 1 by -3; _= insert(',', _, c?); end; return _
/*──────────────────────────────────────────────────────────────────────────────────────*/
mask: parse arg z, $; @.= 0 /* [↓] build an unsorted digit mask. */
Line 1,057 ⟶ 2,580:
end /*k*/
do m=0 for 10; if @.m==0 then iterate; $= $ || copies(m, @.m)
end /*m*/; return $ /* [↑] build a sorted digit mask.*/</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
Line 1,068 ⟶ 2,591:
for 45,072,010 ─── the next highest integer is: 45,072,100
for 95,322,020 ─── the next highest integer is: 95,322,200
</pre>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
load "stdlib.ring"
 
nhi = [0,9,12,21,12453,738440,45072010,95322020]
 
for p2 = 1 to len(nhi)
permut = []
num2 = nhi[p2]
nextHighestInt(num2)
next
 
func nextHighestInt(num)
 
list = []
numStr = string(num)
lenNum = len(numStr)
 
if lenNum = 1
see "" + num + " => " + "0" + nl
return
ok
 
for n = 1 to len(numStr)
p = number(substr(numStr,n,1))
add(list,p)
next
 
lenList = len(list)
calmo = []
 
permut(list)
 
for n = 1 to len(permut)/lenList
str = ""
for m = (n-1)*lenList+1 to n*lenList
str = str + string(permut[m])
next
if str != ""
strNum = number(str)
add(calmo,strNum)
ok
next
 
for n = len(calmo) to 1 step -1
lenCalmo = len(string(calmo[n]))
if lenCalmo < lenNum
del(calmo,n)
ok
next
 
calmo = sort(calmo)
 
for n = len(calmo) to 2 step -1
if calmo[n] = calmo[n-1]
del(calmo,n)
ok
next
 
ind = find(calmo,num)
if ind = len(calmo)
see "" + num + " => " + "0" + nl
else
see "" + num + " => " + calmo[ind+1] + nl
ok
 
func permut(list)
for perm = 1 to factorial(len(list))
for i = 1 to len(list)
add(permut,list[i])
next
perm(list)
next
func perm(a)
elementcount = len(a)
if elementcount < 1 then return ok
pos = elementcount-1
while a[pos] >= a[pos+1]
pos -= 1
if pos <= 0 permutationReverse(a, 1, elementcount)
return ok
end
last = elementcount
while a[last] <= a[pos]
last -= 1
end
temp = a[pos]
a[pos] = a[last]
a[last] = temp
permReverse(a, pos+1, elementcount)
func permReverse(a,first,last)
while first < last
temp = a[first]
a[first] = a[last]
a[last] = temp
first += 1
last -= 1
end
</syntaxhighlight>
Output:
<pre>
0 => 0
9 => 0
12 => 21
21 => 0
12453 => 12534
738440 => 740348
45072010 => 45072100
95322020 => 95322200
</pre>
 
=={{header|RPL}}==
{{works with|HP|48G}}
{| class="wikitable" ≪
! RPL code
! Comment
|-
|
≪ '''IF''' DUP SIZE 1 == '''THEN''' DROP 1 GET '''ELSE''' STREAM '''END'''
≫ '<span style="color:blue">REDUCE</span>' STO
'''IF''' DUP 9 > '''THEN'''
DUP MANT IP SWAP →STR DUP SIZE 0 → digit num size pos
≪ { } digit +
2 size '''FOR''' j
num j DUP SUB STR→
'''IF''' DUP digit > '''THEN''' j 1 - ‘pos’ STO '''END'''
DUP ‘digit’ STO +
'''NEXT'''
'''IF''' pos '''THEN'''
DUP pos GET ‘digit’ STO
DUP pos 1 + size SUB
DUP digit - DUP 0 ≤ 100 * ADD
≪ MIN ≫ <span style="color:blue">REDUCE</span> digit + POS pos +
DUP2 GET ROT pos ROT PUT SWAP digit PUT
DUP ‘pos’ INCR size SUB SORT pos SWAP REPL
≪ SWAP 10 * + ≫ <span style="color:blue">REDUCE</span>
'''ELSE''' DROP num STR→ '''END'''
≫ '''END'''
≫ '<span style="color:blue">NEXTHI</span>' STO
|
<span style="color:blue">REDUCE</span> ''( { list } ≪ func ≫ → func(list) ) ''
<span style="color:blue">NEXTHI</span> ''( int → next_highest_int ) ''
if int > 9 then
initialize variables
initialize list of digits with digit #1
for j = 2 to last digit index
get digit
if higher than previous digit, store position
store digit as previous and append to list
end loop
if there is an highest int
get d1 = first digit to swap
take the rest of list
look for d2 = lowest digit being greater than d1
swap d1 and d2
sort all digits at right of d1
turn the list of digits into a number
else return the initial number
|}
{0 9 12 21 12453 738440 45072010 95322020} 1 ≪ <span style="color:blue">NEXTHI</span> ≫ DOLIST
{{out}}
<pre>
1: { 0 9 21 21 12534 740348 45072100 95322200 }
</pre>
 
=={{header|Ruby}}==
<syntaxhighlight lang="ruby">def next_perm(ar)
ar = ar.dup
rev_ar = ar.reverse
(a, pivot), i = rev_ar.each_cons(2).with_index(1).detect{|(e1, e2),i| e1 > e2}
return [0] if i.nil?
suffix = ar[-i..]
min_dif = suffix.map{|el|el-pivot }.reject{|el|el <= 0}.min
ri = ar.rindex{|el| el == min_dif + pivot}
ar[-(i+1)], ar[ri] = ar[ri], ar[-(i+1)]
ar[-i..] = ar[-i..].reverse
ar
end
 
tests = [0, 9, 12, 21, 12453, 738440, 45072010, 95322020, 9589776899767587796600]
tests.each{|t| puts "%25d -> %d" % [t, next_perm(t.to_s.chars.map(&:to_i)).join]}
</syntaxhighlight>
 
{{out}}
<pre> 0 -> 0
9 -> 0
12 -> 21
21 -> 0
12453 -> 12534
738440 -> 740348
45072010 -> 45072100
95322020 -> 95322200
9589776899767587796600 -> 9589776899767587900667
</pre>
=={{header|Rust}}==
<syntaxhighlight lang="rust">fn next_permutation<T: PartialOrd>(array: &mut [T]) -> bool {
let len = array.len();
if len < 2 {
return false;
}
let mut i = len - 1;
while i > 0 {
let j = i;
i -= 1;
if array[i] < array[j] {
let mut k = len - 1;
while array[i] >= array[k] {
k -= 1;
}
array.swap(i, k);
array[j..len].reverse();
return true;
}
}
false
}
 
fn next_highest_int(n: u128) -> u128 {
use std::iter::FromIterator;
let mut chars: Vec<char> = n.to_string().chars().collect();
if !next_permutation(&mut chars) {
return 0;
}
String::from_iter(chars).parse::<u128>().unwrap()
}
 
fn main() {
for n in &[0, 9, 12, 21, 12453, 738440, 45072010, 95322020, 9589776899767587796600] {
println!("{} -> {}", n, next_highest_int(*n));
}
}</syntaxhighlight>
 
{{out}}
<pre>
0 -> 0
9 -> 0
12 -> 21
21 -> 0
12453 -> 12534
738440 -> 740348
45072010 -> 45072100
95322020 -> 95322200
9589776899767587796600 -> 9589776899767587900667
</pre>
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">func next_from_digits(n, b = 10) {
 
var a = n.digits(b).flip
Line 1,091 ⟶ 2,868:
) {
printf("%30s -> %s\n", n, next_from_digits(n))
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,106 ⟶ 2,883:
982765431 -> 983124567
9589776899767587796600 -> 9589776899767587900667
</pre>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-sort}}
{{libheader|Wren-fmt}}
{{libheader|Wren-str}}
<syntaxhighlight lang="wren">import "./sort" for Sort, Find
import "./fmt" for Fmt
import "./str" for Str
 
var permute = Fn.new { |s|
var res = []
if (s.count == 0) return res
var bytes = s.bytes.toList
var rc // recursive closure
rc = Fn.new { |np|
if (np == 1) {
res.add(bytes.map { |b| String.fromByte(b) }.join())
return
}
var np1 = np - 1
var pp = bytes.count - np1
rc.call(np1)
var i = pp
while (i > 0) {
var t = bytes[i]
bytes[i] = bytes[i-1]
bytes[i-1] = t
rc.call(np1)
i = i - 1
}
var w = bytes[0]
for (i in 1...pp+1) bytes[i-1] = bytes[i]
bytes[pp] = w
}
rc.call(bytes.count)
return res
}
 
var algorithm1 = Fn.new { |nums|
System.print("Algorithm 1")
System.print("-----------")
for (num in nums) {
var perms = permute.call(num)
var le = perms.count
if (le > 0) { // ignore blanks
Sort.quick(perms)
var ix = Find.all(perms, num)[2].from
var next = ""
if (ix < le-1) {
for (i in ix + 1...le) {
if (Str.gt(perms[i], num)) {
next = perms[i]
break
}
}
}
if (next.count > 0) {
Fmt.print("$,29s -> $,s", num, next)
} else {
Fmt.print("$,29s -> 0", num)
}
}
}
System.print()
}
 
var algorithm2 = Fn.new { |nums|
System.print("Algorithm 2")
System.print("-----------")
for (num in nums) {
var bytes = num.bytes.toList
var le = bytes.count
var outer = false
if (le > 0) { // ignore blanks
var max = num[-1].bytes[0]
var mi = le - 1
var i = le - 2
while (i >= 0) {
if (bytes[i] < max) {
var min = max - bytes[i]
var j = mi + 1
while (j < le) {
var min2 = bytes[j] - bytes[i]
if (min2 > 0 && min2 < min) {
min = min2
mi = j
}
j = j + 1
}
var t = bytes[i]
bytes[i] = bytes[mi]
bytes[mi] = t
var c = bytes[i+1..-1]
Sort.quick(c)
var next = bytes[0...i+1].map { |b| String.fromByte(b) }.join()
next = next + c.map { |b| String.fromByte(b) }.join()
Fmt.print("$,29s -> $,s", num, next)
outer = true
break
} else if (bytes[i] > max) {
max = num[i].bytes[0]
mi = i
}
i = i - 1
}
}
if (!outer) Fmt.print("$29s -> 0", num)
}
}
 
var nums = ["0", "9", "12", "21", "12453", "738440", "45072010", "95322020", "9589776899767587796600"]
algorithm1.call(nums[0...-1]) // exclude the last one
algorithm2.call(nums) // include the last one</syntaxhighlight>
 
{{out}}
<pre>
Algorithm 1
-----------
0 -> 0
9 -> 0
12 -> 21
21 -> 0
12,453 -> 12,534
738,440 -> 740,348
45,072,010 -> 45,072,100
95,322,020 -> 95,322,200
 
Algorithm 2
-----------
0 -> 0
9 -> 0
12 -> 21
21 -> 0
12,453 -> 12,534
738,440 -> 740,348
45,072,010 -> 45,072,100
95,322,020 -> 95,322,200
9,589,776,899,767,587,796,600 -> 9,589,776,899,767,587,900,667
</pre>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">fcn nextHightest(N){ // N is int, BigInt or string -->String. Algorithm 2
// ds:=N.split().copy(); // mutable, int
ds:=N.toString().split("").apply("toInt").copy(); // handle "234" or BigInt
Line 1,125 ⟶ 3,042:
}
"0"
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">ns:=T(0, 9, 12, 21, 12453, 738440, 45072010, 95322020);
foreach n in (ns){ println("%,d --> %,d".fmt(n,nextHightest(n))) }
 
n:="9589776899767587796600"; // or BigInt(n)
println("%s --> %s".fmt(n,nextHightest(n)));</langsyntaxhighlight>
{{out}}
<pre>
2,122

edits