Задача сводится к генерации последовательности: 0, 1, 2, 3, 10, 20, 21, 30, 31, 32, 210, ...
- она состоит из всех возможных перестановок, идущих в возрастающем порядке, таких что каждая старшая цифра в числе больше младшей. Первым N (в нашем случае N = 4) поставим в соответствие степени двойки:0001 0010 0100 1000
. Остальные элементы будут являться суммой соответствующих первых элементов (смотрим, какие цифры входят в число из вспомогательной последовательности и суммируем соответствующие цифры. Если N > 10, то, чтобы эта схема работала, при построении вспомогательной последовательности нужно перейти к N-ричной системе счисления. Возможно, что двоичное представление чисел из вспомогательной последовательности действительно как-то связанно с кодами Хемминга - но этим заморачиваться сейчас не готов :)
Вот работающий код (на C#):
const int digitCount = 4;
int[] GetNextIndexArray(int[] indexArray)
{
int[] newIndexArray = new int[0];
int length = indexArray.Length;
for (int i = 0; i < length; i++)
{
if ((i == length - 1 || indexArray[i] + 1 < indexArray[i + 1]) &&
indexArray[i] < digitCount - 1)
{
newIndexArray = new int[length];
Array.Copy(indexArray, newIndexArray, length);
newIndexArray[i]++;
for (int j = 0; j < i; j++)
{
newIndexArray[j] = j;
}
break;
}
else if (i == length - 1 && indexArray[i] >= digitCount - 1)
{
newIndexArray = new int[length + 1];
for (int j = 0; j <= length; j++)
{
newIndexArray[j] = j;
}
break;
}
}
return newIndexArray;
}
int GetNext(int n)
{
List<int> indexArray = new List<int>();
for (int i = 0; i < digitCount; i++)
{
if ((n & (int)Math.Pow(2, i)) != 0)
{
indexArray.Add(i);
}
}
int[] newIndexArray = GetNextIndexArray(indexArray.ToArray());
int result = 0;
foreach (int index in newIndexArray)
{
result += (int)Math.Pow(2, index);
}
return result;
}