public class Josephus
{
public static String[] permute(String[] rebels)
{
final int j = rebels.length - 1;
for (int i = 0; i < j; i++)
Cycle.shiftLeft(rebels, i, j);
return rebels;
}
public static String[] permute(String[] rebels, int passoverCount)
{
final int j = rebels.length - 1;
for (int i = 0; i < j; i++)
Cycle.shiftLeft(rebels, i, j, passoverCount % (1 + j - i));
return rebels;
}
public static void main(String[] args)
{
final int maxRebels = 16;
final String delimiter = " ";
final char numPadChar = ' ';
final int minNumWidth = 2;
String output = "";
for (Integer n = 1; n <= maxRebels; n++)
{
String label = ToString.fromNum(n, numPadChar, minNumWidth) + ": ";
String[] a = new String[n];
for (Integer i = 1; i <= n; i++)
a[i - 1] = ToString.fromNum(i, numPadChar, minNumWidth);
output += ToString.fromArray(permute(a), delimiter, label) + "\n";
}
System.out.print(output);
}
}
class Cycle
{
public static void shiftLeft(String[] array, int i, int j)
{
for (int k = j - 1; k >= i; k--)
Sequence.swap(array, j, k);
}
public static void shiftLeft(String[] array, int i, int j, int n)
{
// 1. Reverse first n elements of array between indices i and j inclusive.
// 2. Reverse remaining elements of array between indices i and j inclusive.
// 3. Reverse all elements of array between indices i and j inclusive.
Sequence.reverse(array, i, i + n - 1); // 1. Reverse first n
Sequence.reverse(array, i + n, j); // 2. Reverse remaining
Sequence.reverse(array, i, j); // 3. Reverse all
}
}
class Sequence
{
public static void swap(String[] array, int i, int j)
{
String tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
public static void reverse(String[] array, int i, int j)
{
while (i < j)
swap(array, i++, j--);
}
}
class ToString
{
public static String fromNum(Integer n, char padChar, int minWidth)
{
String s = n.toString();
while (s.length() < minWidth)
s = padChar + s;
return s;
}
public static String fromArray(String[] a, String delim, String label)
{
String delimiter = "";
String s = label;
for (String element : a)
{
s += delimiter + element;
delimiter = delim;
}
return s;
}
}