import java.util.Stack;
import java.util.Queue;
import java.util.HashMap;
import java.util.LinkedList;

/* Riddle statement: There is a peasant with a goat, wolf, and cabbagehead on one
 * side of a river. The peasant wants to get to the other side, but unfortunately,
 * his boat can take only 2 passengers at once, otherwise it goes under water.
 * Moreover he just cannot take an arbitrary animal/item with him, because if he
 * was to leave behind the goat with the wolf, you can image what would happen,
 * and similar case would be with the goat and the cabbage.
 *
 * Your goal is to devise a plan for the peasant which will get him with
 * everything on the other side of the river in the shortest number of steps.
 */
public class riddle
{
    /* Global constants used for encoding the states of the World.
     * For example, the integer encoding the state (GOAT, BOAT) | (WOLF, CABBAGE)
     * is 9 (1001 in binary) alias GOAT_LEFT | BOAT_LEFT.
     */
    public static final int GOAT_LEFT    = 1;
    public static final int WOLF_LEFT    = 2;
    public static final int CABBAGE_LEFT = 4;
    public static final int BOAT_LEFT    = 8;

    public static Queue<Integer> queue = new LinkedList<Integer>();
    public static HashMap<Integer, Integer> predecessor = new HashMap<Integer, Integer>();

    public static boolean isValid(int state)
    {
        /* Wolf eats Goat on the left bank. */
        if (((state & GOAT_LEFT) != 0) && ((state & WOLF_LEFT) != 0) && ((state & BOAT_LEFT) == 0))
            return false;

        /* Wolf eats Goat on the right bank. */
        if (((state & GOAT_LEFT) == 0) && ((state & WOLF_LEFT) == 0) && ((state & BOAT_LEFT) != 0))
            return false;

        /* Goat eats Cabbage on the left bank. */
        if (((state & GOAT_LEFT) != 0) && ((state & CABBAGE_LEFT) != 0) && ((state & BOAT_LEFT) == 0))
            return false;

        /* Goat eats Cabbage on the right bank. */
        if (((state & GOAT_LEFT) == 0) && ((state & CABBAGE_LEFT) == 0) && ((state & BOAT_LEFT) != 0))
            return false;

        return true;
    }

    public static void tryEnqueueState(Integer nextState, Integer prevState)
    {
        if (isValid(nextState) && !predecessor.containsKey(nextState))
        {
            queue.add(nextState);
            predecessor.put(nextState, prevState);
        }
    }

    public static void expandState(int state)
    {
        /* First, try to move the boat alone. */
        tryEnqueueState(state ^ BOAT_LEFT, state);

        if ((state & BOAT_LEFT) != 0) 
        {          
            /* If the boat is on the left bank, try to take the goat 
             * or wolf or cabbage with it (of course, it must be on
             * the left bank as well).
             */

            if ((state & GOAT_LEFT) != 0)
                tryEnqueueState(state ^ (GOAT_LEFT | BOAT_LEFT), state);

            if ((state & WOLF_LEFT) != 0)
                tryEnqueueState(state ^ (WOLF_LEFT | BOAT_LEFT), state);

            if ((state & CABBAGE_LEFT) != 0)
                tryEnqueueState(state ^ (CABBAGE_LEFT | BOAT_LEFT), state);
        }
        else
        {
            /* If the boat is on the right bank, try to take the goat 
             * or wolf or cabbage with it (of course, it must be on
             * the right bank as well).
             */

            if ((state & GOAT_LEFT) == 0)
                tryEnqueueState(state ^ (GOAT_LEFT | BOAT_LEFT), state);

            if ((state & WOLF_LEFT) == 0)
                tryEnqueueState(state ^ (WOLF_LEFT | BOAT_LEFT), state);

            if ((state & CABBAGE_LEFT) == 0)
                tryEnqueueState(state ^ (CABBAGE_LEFT | BOAT_LEFT), state);
        }
    }

    public static String stateDescription(int state)
    {
        String s = "";

        s += ((state & GOAT_LEFT) != 0)    ? "G" : "";
        s += ((state & WOLF_LEFT) != 0)    ? "W" : "";
        s += ((state & CABBAGE_LEFT) != 0) ? "C" : "";
        s += ((state & BOAT_LEFT) != 0)    ? "B" : "";
        s += "][";
        s += ((state & BOAT_LEFT) == 0)    ? "B" : "";
        s += ((state & CABBAGE_LEFT) == 0) ? "C" : "";
        s += ((state & WOLF_LEFT) == 0)    ? "W" : "";
        s += ((state & GOAT_LEFT) == 0)    ? "G" : "";

        return s;
    }

    public static void main(String[] arguments)
    {
        /* The starting state. */
        Integer state = GOAT_LEFT | WOLF_LEFT | CABBAGE_LEFT | BOAT_LEFT;
        
        /* Add the starting state (situation) into the queue... */
        tryEnqueueState(state, null);

        /* ... and until the queue gets emptied or the solution was found... */
        while ((state = queue.poll()) != null && state != 0)
        {
            /* ... look for the possible evolutions of the current situation
             * and if they have not been encountered, add them to the queue.
             */
            expandState(state);
        }

        if (state == null)
        {
            /* This should not happen, but bear in mind that in general
             * the problem might not have a solution.
             */
            System.out.println("The riddle has no solution!");
        }
        else
        {
            Stack<Integer> solution = new Stack<Integer>();

            while (state != null)
            {
                solution.push(state);
                state = predecessor.get(state);
            }

            while (!solution.empty())
                System.out.println(stateDescription(solution.pop()));
        }
    }
}
