The Setup

Consider an oddly-shaped box containing 29 numbered cells as shown in Fig. 1 below.

shubbles and smoles

Inside this 2D box are two species of square-shaped animals: shubbles and smoles. Fig. 1 (a) shows some shubbles in blue, and some smoles in red. Each creature occupies exactly one grid cell. The box may contain anywhere between 0 and 26 shubbles, but will always contain exactly two smoles.

Being subject to gravity, shubbles and smoles sit on the bottom of the box, stacking on top of anything below them. Both species are exceptionally lazy and remain perpetually motionless.

The box also contains a stot, depicted as a black square, that occupies exactly one grid cell. The stot is not subject to gravity.

The box has one opening located at the bottom of cell 28, as depicted in the figure.

To represent the configuration of shubbles, smoles, and the stot in the box textually, we use a 29-character string, one character per grid cell, in the enumerated order, with . representing an empty cell, o representing a shubble, x representing a smole, and @ representing the stot. For example, the configuration of Fig. 1 (a) is represented by the string [email protected]....


The box can be rotated by any multiple of 90°. While the box is being rotated, the shubbles and smoles remain stationary within their grid cells. As soon as a rotation is complete, they fall directly downward until either i) they are blocked by a wall below, ii) they are blocked by a shubble, smole, or stot below, or iii) they fall through the hole in cell 28 and exit the box. The stot does not fall; it stays fixed in its current cell, even if creatures rest on top of it.

The box cannot be rotated again until the creatures are done falling and have reached a new stable configuration.

Textually, box rotations are denoted by + for a 90° clockwise rotation, | for a 180° rotation, and - for a 90° counterclockwise rotation.

Additionally, the stot can be moved in the four compass directions in increments of one grid cell. A move may not: i) cause a collision between the stot and a creature (i.e. the destination grid cell must be empty), ii) cause a collision between the stot and a wall, nor iii) cause the stot to exit the box through the hole in cell 28.

Also, the stot may not move if it has any creatures resting on top of it (with respect to current gravity).

Textually, stot moves are denoted by < for left, > for right, ^ for up, and v for down. Stot moves are always specified with respect to the "standard" (non-rotated) frame depicted in the figures. That is, if the stot is in cell 10, the move ^ will always move it to cell 5, and the move > will always move it to cell 11. The orientation of the box does not affect the direction of the move.

Sequences of manipulations are encoded using left-to-right character strings. For example, the string +<<^- indicates the box is rotated clockwise 90°, then the stot is moved left twice and up once (with respect to the standard frame), then the box is rotated 90° counterclockwise back into its original orientation.

The Challenge

For perfectly good reasons (that I cannot disclose), we wish to extricate all shubbles from the box without extricating a single smole. To accomplish this, we can use the manipulations specifically described above.

Before solving this problem, it behooves us to simulate how our various manipulations will affect the contents of the box, which is the focus of this challenge.

You must write a program that accepts two arguments from stdin (or equivalent):

  • a string describing the initial state of the box
  • a sequence of manipulations

You may assume that both arguments are syntactically valid, that the box starts in the standard orientation, and that the initial state of the box is stable and legal.

The program must output to stdout (or equivalent) either:

  • (case 1) the final state of the box, expressed as a string, if the sequence of moves is legal (it does not violate the stot move rules) and does not cause any smoles to exit the box. The final orientation of the box is unimportant.

  • (case 2) a single exclamation mark, !, if the sequence of moves is illegal or causes any smoles to exit the box


The winning program is the shortest program by byte count, subject to some extremely lucrative bonus multipliers:

  • claim a multiplier of 0.65 if instead of printing the encoded output for case 1, the program outputs an ASCII picture of the box in its final state and orientation, using the spec characters for shubbles, smoles, stots, and empty cells, and placing a * in the cell just outside the hole in cell 28. Leading and trailing whitespace is ignored.

    For example, if Fig. 1 (a) is rotated 90°, the output would be

       .  .
      x  .
  • claim a multiplier of 0.22 if instead of printing encoded output for case 1, the program outputs an image file or displays a GUI window with a picture of the box in its final state and orientation. The picture should be in the style of Fig. 1 (a), showing the grid cells, walls, and creatures/stot using coloured boxes.

  • claim a multiplier of 0.15 if instead of printing encoded output for case 1, the program outputs an animated .gif or animated GUI window showing all intermediate states in the simulation at 1 sec intervals. The same picture rules as for the 0.22 multiplier apply. The first frame of the animation should depict the initial state of the simulation. Additionally, the animation should show "hidden" intermediate states, which are

    • the shubbles/smoles falling into a stable configuration by one cell per animation frame after a rotation

    • the intermediate 90°-rotated state of the box in a 180° rotation

  • claim a multiplier of 0.12 if the program produces an animated .gif or animated GUI window of the above style, but runs at 20 fps and shows

    • smooth, continuous animations of the box rotating

    • smooth, continuous animations of the stot moving, and of the shubbles/smoles falling into a stable configuration

    Shubbles falling through the hole in cell 28 should be shown exiting the box, and should disappear once totally outside. You may choose your own timing for the animation so long as no more than 1 manipulation/sec is performed.

Total score is floor( base score * multiplier ). Only one multiplier may be claimed.

It's a smole world after all. ;)

  • 2
    \$\begingroup\$ +1 for the spec, but I won't be participating, probably. \$\endgroup\$ Commented Oct 8, 2014 at 13:32
  • \$\begingroup\$ This sounds like fun. Just to make sure: the shape of the box is entirely fixed, yes? So we don't have to account for any other shapes? \$\endgroup\$
    – Ingo Bürk
    Commented Oct 8, 2014 at 16:13
  • \$\begingroup\$ @IngoBürk: Correct. The box shape is fixed. \$\endgroup\$
    – COTO
    Commented Oct 8, 2014 at 18:31
  • \$\begingroup\$ For the image output, can we use your image as a resource (or any kind of resource) or do we have to draw it entirely in the code? If we can use it, how does it count? I'll try to give this a go, but I'm on vacation right now. \$\endgroup\$
    – Ingo Bürk
    Commented Oct 8, 2014 at 23:41
  • 1
    \$\begingroup\$ You can use external graphic resources (e.g. images, SVG markup) as long as you include their byte counts in the total for the program. The basic image doesn't have to be terribly complicated. 12 lines making up the grid; the wall; and the coloured boxes inside the box. If you prefer, a coloured box can fill an entire grid cell, and the wall can trace exactly along the border of the outermost cells. Thus the whole picture can be defined by drawing rectangles, lines, and a polyline on a 6x6 square coordinate grid. \$\endgroup\$
    – COTO
    Commented Oct 8, 2014 at 23:51

1 Answer 1


MATLAB, as yet ungolfed * 0.15

It would be great if someone could hazard a guess as to whether this works right.

n = @()input('', 's');
E = @()fprintf('!');
M = zeros(7,9);
G = M;
I = [9:7:44 17:7:52 18:7:46 12:7:47 20:7:55];
M0 = M;
M0(I) = 1;
M([I 49]) = 1;
G(I) = n()-46;
trot = 0;
Xtr = [0 1-10i 11-7i 8+i];
X0 ='c66++66++oozzoozzn'-i*'YYNNAA--  ++88LLYY'-22+22i;
for a = [97 n()]
    a = find('-|+a^<v>'==a);
    if a<5
        R = @(m) rot90(m, a);
        G = R(G);
        [nr,nc] = size(G);
        M = R(M);
        M0 = R(M0);
        trot = mod(trot+a,4);
        X = exp(i*pi*trot/2)*X0 + 11*Xtr(trot+1);
        z = find(G==18);
        J = z + [-nr,1]*[0,-1;1,0]^(trot+a)*[1;0];
        if ~M0(J) | G(J) | G(z+1)
        G(z) = 0;
        G(J) = 18;
    fall = 1; 
    while fall
        for x = 2:nc; for y = 2:nr
             ch = G(y,x);
             if M0(y,x) 
                 rectangle('Po',[x,-y,1,1],'F',~ch|ch==[74 1 65]);
        G2 = G;
        for r = nr-1:-1:2
            s = G2 > 30;
            f = G2(r,:) .* (s(r,:) & ~s(r+1,:) & M(r+1,:) & G(r+1,:)~=18);
            if r==size(G,1)-1 & any(f==74)
            G2(r:r+1,:) = G2(r:r+1,:) + [-f;f];
        G2 = G2 .* M0;
        fall = any(any(G2 ~= G));
        G = G2;

Sample end result for some random moves:

[email protected]...

enter image description here

  • 1
    \$\begingroup\$ Could you actually show a GIF of the animation? \$\endgroup\$ Commented Oct 9, 2014 at 13:18
  • \$\begingroup\$ Cool! I'll check it out these evening (and post a few test cases). \$\endgroup\$
    – COTO
    Commented Oct 9, 2014 at 14:20
  • \$\begingroup\$ The program isn't require to output an animated .gif, but if you want to generate one, feersum, this article explains how to do so easily. \$\endgroup\$
    – COTO
    Commented Oct 9, 2014 at 14:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.