views:

1135

answers:

4

The Challenge

  • Reach the end of the level!
  • Bonus points if you hit each of the (C)oin blocks exactly 2 times.

Disallowed

  • Hard coding the command sequence in any way.
  • Your favorite "One character language" that happens to do exactly one thing, which is solving this golf.

How To

Your program receives the level below(without line breaks) via standard input.
It then has to print out a commands which are needed to successfully complete the level.

The Level

  • S is your starting position.
  • E the position you need to be in to complete the level.
  • C is a coin block with 2 coins in it, you'll never have to skip one of these in order to be able to complete the level.
  • Both C and _ count as ground, there's only solid ground no floating platforms.
  • | is a wall, all the walls you'll need to jump up in order to complete the level are at maximum 1 wall tall, everything that's higher you can consider an abyss you can't get out of in any way.
  • x are spikes, guess what happens if you touch'em. Spikes will always be one level below the ground that is surrounding them.

All levels are 4 lines height, with each of the lines 63 chars wide. That makes a total of 252 characters per level.

>                       ______  ____       ________  ___        <
>    C            ______|    |  |  |  C  __|      |  | |   ____E<
>S______  __  ____|          |  |  |_____|        |__| |___|    <
>       xx  xx                xx                                <

Notes: The >< are just to illustrate the borders, they are NOT included in the input to your program. Also watch out for your text editor, as mine screwed up the whitespace a number of times

The Commands

  • M = Moves you 1 to the right, if there's no ground beneath you, you will fall until you hit it. You cannot move while you are falling.
  • J = Jump, moves you up by 1 for the next 3 commands or until you hit a (C)oin Block. After that, you will fall until you reach the ground. You can only jump when on the ground. If an M brings you on the same level as the ground, the jump gets canceled.
  • O = NOP, will make you wait/do nothing. This way you can jump holes and spikes which a only 1 block wide(You don't need this for the level above, but you'll earn extra points if you can solve levels which need this).

The Solution(With Coin Blocks)

Successive commands are stacked on top of each other.
F indicates where you will fall(remember you can't do anything while falling),

                            MMMF                 MMMF            
    M                 MMMMMMJ  MMMMF M   MMMMMMMMJ  MMMF        
M   J MMMFMMMF  MMMMMMJ|    |  |  |F J MMJ|      |  | |F MMMMME
SMMMJMJ  MJ  MMMJ|          |  |  |MMJMJ|        |__| |MMJ|    
       xx  xx                xx                                

Resulting command sequence, 75 characters long:

MMMMJJMMJMMMMJMMMMMMJMMMMMMJMMMMMMJMMMMMMMMMJJMMJMMJMMMMMMMMJMMMMMMMMJMMMMM

Hope this yields some interesting results... and not tons of flames :O

EDIT

OK, there are way more possibilities than I initially thought of, I apologize for all the edits.

+12  A: 

Javascript:

Short Version (334 280 256 240 238 236 233 223 207 205 196 184 182 characters)

a=prompt();j=i=0;while(a[++j*63]<(o="M"));while(++i<62){while(a[h=j*63+i]<"_")j++;if(a[h-63]>"B")o+="JJ";if(a[h+1]>"z")o+="J",j--;if(a[h+3]+a[h+1]=="_ ")o+="JMM",i+=2;o+="M"}alert(o)

Note: The Javascript method prompt tends to remove space on some browser (ex.: Google Chrome). It might not work as expected for that reason for those browsers. On others (ex.: Firefox), it will work fine.

Commented Version

a=prompt(); // Read the input //
j=i=0;
while(a[++j*63]<(o="M")); // Place the cursor at the "S" //
while(++i<62){ // While we are not at the end point //
 while(a[h=j*63+i]<"_")j++; // If we are on a space, we fall //
 if(a[h-63]>"B")o+="JJ";// We jump for coins //
 if(a[h+1]>"z")o+="J",j--; // We jump when we reach a wall //
 if(a[h+3]+a[h+1]=="_ ")o+="JMM",i+=2; // We jump on gap //
 o+="M" // We add the movemment in the output
}
alert(o) // Output
HoLyVieR
Equality is a long operator. =="|" could be >"z". Your last if statement could be a[j*v+i+1]+a[j*v+i+3]==" _" -- do you even need to test for a floor tile there? Even better would be to move the increment to a[++i+j*v]. If you can't do that, changing j*v+(++i) to ++i+j*v would still save a couple of bytes.
Nabb
@Nabb For ++i+j*v, it's invalid synthax, I tried it on Firefox and it just throws a synthax error. We need to test for a floor title, look at the end we need to drop, not jump.
HoLyVieR
Uh nearly forget about the whole thing here, sorry. I'm going to accept this one, since the Python Version, even though it's shorter, is basically the same approach just with different syntax.
Ivo Wetzel
@Ivo Wetzel It is now shorter than Python.
HoLyVieR
+9  A: 

Python 2.6 318 - 302 - 300 - 284 - 277 - 206 - 203 - 191 - 184 characters

Basically the same approach as HoLyVieR (I wonder if there can be lots of radically different directions solution-wise). Reads from stdin.

Update 1 (318 -> 302): don't check for E but assume it is on position 63 (as asked in a comment).
Update 2 (302 -> 300): changed range(0,252,63) to (0,63,126,189) (two whole characters) Update 3 (300 -> 284): seems raw_input also fetches stdin so import sys etc can be dropped. Update 4 (284 -> 277): [y][x+3]=="_"and p[y][x+1]==" " to p[y][x:x+4]==list("_ _") Update 5 (277 -> 206): went for string instead of 2-dimensional list processing, big save...
Update 6 (206 -> 203): implemented suggestions in a comment on HoLyVieR's answer (by Nabb) Update 7 (203 -> 191): breaking the 200 char-limit by using boolean string building...
Update 8 (191 -> 184): minor tweaks

All comments or suggestions welcome!

Note: I added an (unneeded) \ and newline in the code below (EOL 5->6) (to avoid scrollbars here)

l=raw_input()
x,y,o=0,l.index('S')//63,''
while x<62:
 while l[y*63+x]==" ":y+=1
 b=y*63+x;g=l[b+1]>"z";h=l[b:b+4]=="_  _";o+=(l[b-63]>"A")*"JJ"+g*"J"+h*"JMM"+\
"M";y-=g;x+=1+h*2
print o

Usage: python 2dplatform.py < level.txt

ChristopheD
Nice, *1* character shorter than the JavaScript version :D
Wallacoloo
You can still reduce it of 1 character (y-1)*63+x is the same as y*63-63+x
HoLyVieR
@HoLyVieR: thanks for the catch, but my version got updated ;-)
ChristopheD
+2  A: 

Ruby - 231 226 218 198 197 characters

It can handle one-character gaps and blindly jumps off any cliffs. Falls off if it tries to get a coin immediately to the left of a pit.

l=?\s*63+gets
c=l=~/S/
r=->{c-=62;'JM'}
(print l[c-63]==?C?r[]:(l[c+1]>?\s&&l[c+1]<?x?(c+=1;?M):(l[c+1]<?C&&l[c]>?\s?(c-=61;'JMM'+(l[c+63]<?C?(c+=1;?M):?O)):r[]))
c+=63 while l[c]<?C)while l[c]!=?E
Lowjacker
Any reason you use `?\s` instead of shorter `32`?
Chubas
@Chubas I'm using Ruby 1.9, so ?\s returns " ".
Lowjacker
I see. Wasn't aware of it, thanks for the tip
Chubas
+1  A: 

C - 275 bytes (DOS line endings)

#define A(B,C)!memcmp(p+1,B,C)
#define P printf
char*p,l[318],k=63;f(){P("M");++p;while(*p<33)p+=k;}main(){read(0,l+k,4*k);p=strchr(l+k,83);while(*p!=69)p[-k]==67?(P("JJM"),++p):(p[1-k]>94?(P("JM"),p+=1-k):(A("  _",3)?(P("JMMM"),p+=3):(A(" _",2)?(P("JMMO"),p+=2):f())));}

This caters for 1-char gaps, and the case where the player is walking across the very top line of the level. You could save a bit if you didn't care about those 2 cases.

brone