Problem: Reorder the digits of a number, in order to get the next number which is the least one that is greater than the input number. For example, the number 34724126 is the next number of 34722641 when reordering digits.
/* Copyleft: Ming Lin <minggr@gmail.com> */
#include <stdio.h>
void reverse(int *data, int n)
{
int *s, *e;
s = data;
e = data + (n-1);
while (s < e) {
int tmp;
tmp = *s;
*s = *e;
*e = tmp;
s++;
e--;
}
}
/*
* 34722641 -> swap 2 and 4
* 34724621 -> reverse "621"
* 34724126
*/
int least_greater_number(int *data, int n)
{
int tmp;
int i, j;
i = n-1;
tmp = data[i--];
while (i >= 0) {
if (data[i] < tmp)
break;
tmp = data[i--];
}
if (i < 0)
return 0;
j = n;
while (j--) {
if (data[j] > data[i])
break;
}
tmp = data[i];
data[i] = data[j];
data[j] = tmp;
reverse(&data[i+1], n-i-1);
return 1;
}
void print_data(int *data, int n)
{
int i;
for (i = 0; i < n; i++)
printf("%d", data[i]);
printf("\n");
}
int main()
{
int data[] = {3, 4, 7, 2, 2, 6, 4, 1};
int n = 8;
print_data(data, n);
if (least_greater_number(data, n))
print_data(data, n);
return 0;
}