, bools. , Next() (n = 5, k = 3).
1 1 1 . . Move last 1 right once.
1 1 . 1 . Move last 1 right once.
1 1 . . 1 Move last 1 right once.
1 . 1 1 . Move the second last 1 right once and all 1s from the right back.
1 . 1 . 1 Move last 1 right once.
1 . . 1 1 Move the second last 1 right once (and all 1s from the right back.)
. 1 1 1 . Move the third last 1 right once and all 1s from the right back.
. 1 1 . 1 Move last 1 right once.
. 1 . 1 1 Move the second last 1 right once (and all 1s from the right back.)
. . 1 1 1 Move the third last 1 right once (and all 1s from the right back.)
.
.
public static Boolean[] Initialize(Int32 n, Int32 k)
{
return Enumerable.Concat(Enumerable.Repeat(true, k),
Enumerable.Repeat(false, n - k)).ToArray();
}
().
public static Boolean Next(this Boolean[] list)
{
Int32 lastOneIndex = Array.LastIndexOf(list, true);
if (lastOneIndex == -1)
{
return false;
}
else if (lastOneIndex < list.Length - 1)
{
list.MoveBlock(lastOneIndex, lastOneIndex, lastOneIndex + 1);
}
else
{
Int32 lastZeroIndex = Array.LastIndexOf(list, false, lastOneIndex);
if (lastZeroIndex == -1)
{
return false;
}
else
{
Int32 blockEndIndex = Array.LastIndexOf(list, true, lastZeroIndex);
if (blockEndIndex == -1)
{
list.MoveBlock(lastZeroIndex + 1, lastOneIndex, 0);
return false;
}
else
{
list.MoveBlock(blockEndIndex, blockEndIndex, blockEndIndex + 1);
list.MoveBlock(lastZeroIndex + 1, lastOneIndex, blockEndIndex + 2);
}
}
}
return true;
}
, .
public static void MoveBlock(this Boolean[] list, Int32 oldStart, Int32 oldEnd, Int32 newStart)
{
list.ClearBlock(oldStart, oldEnd);
list.SetBlock(newStart, newStart + oldEnd - oldStart);
}
public static void SetBlock(this Boolean[] list, Int32 start, Int32 end)
{
list.SetBlockToValue(start, end, true);
}
public static void ClearBlock(this Boolean[] list, Int32 start, Int32 end)
{
list.SetBlockToValue(start, end, false);
}
public static void SetBlockToValue(this Boolean[] list, Int32 start, Int32 end, Boolean value)
{
for (int i = start; i <= end; i++)
{
list[i] = value;
}
}
, .
var sequence = "ABCDE";
var state = Initialize(sequence.Count(), 5);
do
{
Console.WriteLine(new String(sequence.Where((_, idx) => state[idx]).ToArray()));
}
while (state.Next());