12
\$\begingroup\$

The most recognizable sliding puzzle is the fifteen puzzle. It has a 4 by 4 grid, 15 tiles, and one empty grid space. The tiles can only move into the empty space and must always be in line with the grid.

Let's define a generalized sliding puzzle as a two-dimensional W wide by H high grid (W, H both positive integers) that contains some number of identical unmarked tiles (between 0 and W×H of them) snapped to the grid, arranged in any way (without overlapping), with empty grid spaces filling the rest of the area.

For example if W and H are 3 and a tile is T and an empty space is E one of many possible siding puzzle arrangements is

TTT
TET
EET

For these puzzles there are 4 possible moves: shove everything up, shove everything down, shove everything left, or shove everything right. 'Shoving' in some direction makes all the tiles travel in that direction as far as possible until they hit another tile or the grid boundary. Sometimes shoving will not change the layout of the grid,

If the example grid is shoved right the result is

TTT
ETT
EET

Shoved left the result is

TTT
TTE
TEE

Shoved down the result is

EET
TET
TTT

(notice that both the leftmost T's moved)

Shoving up does not change the grid layout in this case.

Note that since the tiles are indistinguishable these puzzles do not have 'solved' states. Also note that a puzzle may start in a layout that is impossible to get back to once a shove has been made (e.g. one tile in the middle of a 3 by 3 grid).

Challenge

Using only printable ASCII write two rectangular blocks of code, both M characters wide and N characters tall (for any positive integers M, N). One code block will represent a tile of a sliding puzzle, the other code block will represent an empty grid space.

Arranging these two code blocks into a W by H grid will create a code-represented sliding puzzle which can be saved as a text file and run as a normal program. When run, these kind of programs should prompt the user via stdin for a number from 1 to 4; 1 is for up, 2 down, 3 left, 4 right. When the user types in their number and hits enter, the program calculates how to shove its source code tiles in that direction and saves the new puzzle layout in a file (either a new file or in the same file), then terminates.

This process can be repeated indefinitely with the new sliding puzzle code file generated after each shove.

Example

Suppose my tile code block looks like this

//   my
// tile

and my empty grid space code block looks like this

//empty
//space

(M = 7, N = 2, this is of course not actual code)

Any valid sliding puzzle arrangement of these two blocks should create a program in the language I'm using that can be run to let the user shove in some direction.

The code representation of the example grid is:

//   my//   my//   my
// tile// tile// tile
//   my//empty//   my
// tile//space// tile
//empty//empty//   my
//space//space// tile

So running this and pressing 2 (for down) then Enter would write this to another file (or the same file):

//empty//empty//   my
//space//space// tile
//   my//empty//   my
// tile//space// tile
//   my//   my//   my
// tile// tile// tile

That file could then be run and shoved in the same exact way.

Notes

  • Any code-representation of a W by H sliding puzzle should be runnable and be able to shove itself properly. This includes all grid sizes from 1 by 1 to some reasonable maximum (216 by 216 or more).

  • A program may read its own source code. There are no quine-based restrictions. Comments of any sort are also fine.

  • The program must prompt for a direction to shove in even if there are no tiles to shove or no tiles can be shoved. The prompt is simply a place to type in a number, no message is required.

  • You may assume the input is always valid (1, 2, 3, or 4).

  • Padding your code blocks with spaces is fine. Remember that they can only be printable ASCII, this mean no tabs and no newlines (besides the newlines that help form the code blocks).

  • If your language does not support stdin use whatever input method seems closest.

  • You can require that a newline be at the end of your code-puzzle files. (Or require that it not be there.)

  • How you name new files is not important. f.txt or just f is fine.

  • The two code blocks may not be identical.

Scoring

The goal is to do this with the smallest code size (which is why this is tagged code-golf). The submission with the smallest code block area (M×N) is the winner. Tie-breaker goes to the highest voted answer.

Related: Code that runs the Game of Life on itself

\$\endgroup\$
  • \$\begingroup\$ So the program needs to work when there are only empty spaces and no tile blocks (and vice versa)? \$\endgroup\$ – grc Jan 4 '15 at 12:07
  • \$\begingroup\$ @grc Yes to your first question, and remember it still needs to prompt for a shove value even if totally empty or full. No the blocks can't be identical. I guess if they were you could claim to have a fairly trivial answer. So I'll mention that. \$\endgroup\$ – Calvin's Hobbies Jan 4 '15 at 12:25
  • \$\begingroup\$ Can I specify the name of the original source file? \$\endgroup\$ – feersum Jan 4 '15 at 14:53
  • \$\begingroup\$ @feersum Like can you assume it is always f.txt? Yes. \$\endgroup\$ – Calvin's Hobbies Jan 4 '15 at 14:58
  • \$\begingroup\$ Aren't codeblocks always going to be 1 line? Multi-line codeblocks seem really complex to me and 2D esolanguages probably don't have support for writing files. \$\endgroup\$ – Def Jan 4 '15 at 16:24
5
\$\begingroup\$

TECO, 153

Empty block:

0T@^Ux#EBx#27@:^Ux##MxA1^QUq^T%d/51%w"G153UsZ/QqUlQq/153Un|Qq%s/153UlZ/QqUn'Qd&1UhQl<.UpQn<Qh-\"F%c'TRQs:C>QpJQn<D-%c"L%c1-Qh\|Qh\'RQs:C>Qw"GC|153%pJ'>EX

Tile block:

1T@^Ux#EBx#27@:^Ux##MxA1^QUq^T%d/51%w"G153UsZ/QqUlQq/153Un|Qq%s/153UlZ/QqUn'Qd&1UhQl<.UpQn<Qh-\"F%c'TRQs:C>QpJQn<D-%c"L%c1-Qh\|Qh\'RQs:C>Qw"GC|153%pJ'>EX

The program, which modifies itself in place, must be saved in a file named x. It can be run via the command tecoc mung x.. The dot is important; without it, TECO attempted to find a file named x.tec. The trailing newline must be present.

The printable ASCII restriction was a bit of a pain for this one, as the language utilizes many unprintable characters. Most of them can be replaced by a two-byte sequence beginning with a caret, but "Escape" (ASCII 27) is the one character that is 'inescapable', so to get it I had to put its ASCII value into a string and exec it. Thus, the 4-byte EBx<Esc> exploded into @^Ux#EBx#27@:^UX##Mx.

This could be reduced greatly, especially by splitting the program into two parts, storing them as strings and running only if both are present.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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