Consider an oddly-shaped box containing 29 numbered cells as shown in Fig. 1 below.
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
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.
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
. . ..... .o... xo.@. *ooo.. 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. ;)