Can Mario go to the end of this map
Slip, 38 27 25 bytes
S>(`=<<`P{1,5}>`P>`P*)+#E
Requires input to be padded to a rectangle such that there are spaces in every cell Mario needs to traverse (potentially with a leading line full of spaces). Prints either a string representing the valid path (which includes S
, E
and all the =
walked on except the last) or nothing if no path exists.
Test it here.
Explanation
Slip was Sp3000's entry to our 2D pattern matching language design challenge. It's a bit like a 2D-extension of regex where you can give instructions to the engine's cursor when it's allowed or required to make left or right turns. It also has a convenient feature where you can prevent the cursor from advancing, allowing you to match a single position twice in a row (with different patterns).
Slip doesn't have something comparable to lookarounds in regex, but since you can move over any position multiple times, one can just test the condition and then return. We use this to ensure that we only jump when on the ground by moving into the ground tile after each step.
S Match the starting position S.
> Turn right, so that the cursor points south.
( One or more times... each repetition of this group represents
one step to the right.
`= Match a = to ensure we've ended up on ground level before.
<< Turn left twice, so that the cursor points north.
`P{1,5} Match 1 to 5 non-punctuation characters (in our case, either space,
S or E, i.e. a non-ground character). This is the jump.
> Turn right, so that the cursor points east.
`P Match another non-ground character. This is the step to the right.
> Turn right, so that the cursor points south.
`P* Match zero or more non-ground characters. This is the fall.
)+
# Do not advance the cursor before the next match.
E Match E, ensuring that the previous path ended on the exit.
Java 234 230 221 216 208 207 205 179 Bytes
Look, I beat C and python? I have acheived true transcendence among mortals! All jokes aside, this was a fun challenge. The following function takes input as an array of column strings each with the same length. If this is against the rules please do let me know. It outputs 1 meaning a successful mario run, and any other value implying a failed mario run.
int m(String[]a){int l=a.length-1,z=a[l].indexOf(69),m=a[0].indexOf(83),i=1,x;a[l]=a[l].replace("E"," ");for(;i<=l;m=x,i++){if(m-(x=a[i].indexOf('='))>3|x<1)return-1;}return m-z;}
Here is the older logic (which is similar to the current version) with example use and output. Plus some comments explaining the logic
/**
*
* @author Rohans
*/
public class Mario {
int m(String[] a) {
//declare variables for the finish the location of mario and the length
int z, l = a.length - 1, m = a[0].indexOf("S");
//treat the exit as a space
z = a[l].indexOf("E");
a[l] = a[l].replaceAll("E", " ");
//go through the map
for (int i = 1, x, r = 1; i <= l; i++) {
//if mario can safely jump to the next platform (it picks the highest one)
if (((x = a[i].indexOf("=")) != 0 && (x = a[i].indexOf(" =")) == -1) || m - x > 4) {
return 0;
}
//adjust marios y location
m = x;
}
//make sure mario made it to the end of the level
return m == z ? 1 : 0;
}
public static void MarioTest(String... testCase) {
System.out.println(new Mario().m(testCase) == 1 ? "Mario made it" : "Mario did not make it");
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
MarioTest(" S=", "=====", " =", " =", "= =", " E=");
}
}
Python, 260 239 222 215 209 206 Bytes,
try it on ideone (with test cases)
f=lambda m,y=-1,x=0:f(m,m[0].find("S"))if y<0else y<len(m[0])-1and x<len(m)and m[x][y]!="="and(m[x][y]=="E"or m[x][y+1]=="="and any(f(m,y-i,x+1)for i in range(5)[:(m[x][y::-1]+"=").find("=")])or f(m,y+1,x))
call like: f([' S=', ' E='])
patch notes:
Now, like some of the other solutions, assumes input is an array of coloumn strings, each starting with a " "
Wrapper for old input form: g=lambda x:f(map("".join,zip(*([" "*x.index("\n")]+x.split("\n")))))
Also, I fixed a bug where Mario could jump through blocks above him.
ungolfed version with explanations:
f
recursivly calls itself in all directions Mario can move to from y,x
. It returns True
when it reaches the "E"nd
, which then goes back through all the function calls until g
finally returns True
.
def g(x):
#create a array of strings which are the rows of the input
global m
m=x.split("\n")
m=[" "*len(m[0])]+m # because Mario can jump over sometimes
#Mario starts at the S
return f([i for i,a in enumerate(m) if a[0]=="S"][0],0)
def f(y,x):
#print y,x
if y>len(m)-2 or x>=len(m[0]) or y<0: return False #out of bounds
if m[y][x]=="E":return True #Reached the goal
if m[y][x]=="=":return False #We got stuck inside a wall
if m[y+1][x]=="=": #if you have ground under your feet
for i in range(5): #jump max 4
if f(y-i,x+1): #go one forward and try to go further from there
return True
return f(y+1,x) ##fall down