Pages

The Josephus Problem

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;
  }
}