Mario có thể đi đến cuối bản đồ này không


13

Tạo một chương trình xác định, đưa ra một đầu vào của đường dẫn, liệu Mario có thể đi đến cuối, được biểu thị bởi E, từ đầu, được ký hiệu bởi S.

Một đường dẫn sẽ trông giống như thế này:

S = E
=====

Trong một đường dẫn, các biểu tượng khác nhau và những gì chúng đại diện là:

  • =: tường / sàn / trần. Mario không thể đi xuyên tường và không thể ngã qua sàn nhà, hoặc nhảy qua trần nhà (anh ta sẽ đập đầu mình)
  • (không gian): không khí. Mario có thể đi qua cái này, và nhảy qua nó, và rơi qua nó
  • S: không khí, ngoại trừ hiển thị nơi Mario bắt đầu. Điều này sẽ luôn xuất hiện trong cột ngoài cùng bên trái của đầu vào, ở mức mặt đất.
  • E: không khí, ngoại trừ hiển thị nơi Mario muốn nhận. Điều này sẽ luôn xuất hiện trong cột ngoài cùng bên phải của đầu vào, ở mức mặt đất.

Đầu vào sẽ có không gian ở mọi nơi mà Mario có thể đi bộ.

Mario chỉ có thể tiến lên; trong ví dụ này Mario không thể đạt được mục tiêu

S
===

 ===
   E
====

anh ta cũng không thể

    E
   ==
== 
  #==
==
   ==
==
S  ==
======

Tuy nhiên, anh ta có thể đạt đến không gian được biểu thị bởi #(sẽ không xuất hiện trong đầu vào), bởi vì anh ta có thể nhảy lên cao đến bốn ô; Mario là siêu nhân. Một ví dụ khác về siêu nhân của anh ta:

S
=
=
=
=
=
= #
= =
=
=
=
=     E
=======

Mario có thể đến được Ebằng cách rơi khoảng cách lớn, sống sót và bình tĩnh bước tới E. Lưu ý rằng anh ta không thể với tới #, vì Mario rơi thẳng xuống.

Mario có thể nhảy rất cao, nhưng không quá xa về phía trước bằng cách so sánh.

S   E
== ==
 = =

Mario có thể cố gắng để nhảy khoảng cách, nhưng anh ta sẽ thất bại, và rơi thẳng vào. Anh ta không thể đi đến cuối cùng.

Mario có thể đạt được mục tiêu trong tất cả các ví dụ sau:

 E
 =
 =
 =
S=
==

 =
 =   E
S=   =
==   =
 =   =
 =====

S
=






=  E
====

Đây là mã golf, vì vậy ít byte nhất sẽ thắng!


2
Trong ví dụ rơi xuống, bạn đề cập rằng "anh ta không thể với tới #, vì Mario rơi thẳng xuống". Nếu tôi đang xem chính xác điều này, liệu anh ta có rơi thẳng xuống #không? Ngoài ra, các bước nhảy được xác định là tối đa 4 khoảng trắng lên và tối đa là 1 khoảng trống phải không?
GuitarPicker

4
@IdeosPicker Tôi nghĩ rằng lúc đầu cũng như vậy nhưng nếu nhìn kỹ bạn có thể thấy có một cột không gian khác trước cột có #. Đối với câu hỏi thứ hai: Tôi không phải OP nhưng tôi đoán bạn đúng. (đó là những gì tôi giả định trong giải pháp của mình)
KarlKastor

1
Trong ví dụ thứ ba (thể hiện chiều cao nhảy của Mario), Ekhông xuất hiện ở cột ngoài cùng bên phải vì tầng trệt kéo dài một bên phải từ phần còn lại của bản đồ.
Taylor Lopez

1
@Janan: Mario cannot walk through wall , and cannot fall past a floor, or jump past a ceiling
Tít

1
@Titus Tôi đang nghĩ về việc Mario nhảy lên không trung và có nhiều lựa chọn tầng khác nhau để hạ cánh - anh ta có thể xuống tầng thấp hơn không?
Joffan

Câu trả lời:


11

Trượt , 38 27 25 byte

S>(`=<<`P{1,5}>`P>`P*)+#E

Yêu cầu đầu vào phải được đệm vào một hình chữ nhật sao cho có khoảng trắng trong mỗi ô mà Mario cần phải đi qua (có khả năng với một dòng hàng đầu có đầy khoảng trắng). In hoặc là một chuỗi đại diện cho đường dẫn hợp lệ (trong đó bao gồm S, Evà tất cả các =bước trên, ngoại trừ người cuối cùng) hoặc không có gì nếu không có con đường tồn tại.

Kiểm tra nó ở đây.

Giải trình

Trượt là mục nhập của Sp3000 đối với thử thách thiết kế ngôn ngữ phù hợp với mẫu 2D của chúng tôi. Nó giống như một phần mở rộng regex 2D trong đó bạn có thể đưa ra hướng dẫn cho con trỏ của động cơ khi được phép hoặc bắt buộc phải rẽ trái hoặc phải. Nó cũng có một tính năng tiện lợi, nơi bạn có thể ngăn con trỏ tiến lên, cho phép bạn khớp một vị trí hai lần liên tiếp (với các mẫu khác nhau).

Trượt không có cái gì đó tương đương với nhìn trong regex, nhưng vì bạn có thể di chuyển qua bất kỳ vị trí nào nhiều lần, người ta chỉ cần kiểm tra điều kiện và sau đó quay lại. Chúng tôi sử dụng điều này để đảm bảo rằng chúng tôi chỉ nhảy khi ở trên mặt đất bằng cách di chuyển vào gạch đất sau mỗi bước.

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.

9

Java 234 230 221 216 208 207 205 179 byte

Hãy nhìn xem, tôi đã đánh C và trăn? Tôi đã đạt được sự siêu việt thực sự giữa những người phàm! Tất cả những trò đùa qua một bên, đây là một thử thách thú vị. Hàm sau lấy đầu vào là một mảng của các chuỗi cột mỗi chuỗi có cùng độ dài. Nếu điều này là trái với quy tắc xin vui lòng cho tôi biết. Nó xuất ra 1 nghĩa là chạy mario thành công và bất kỳ giá trị nào khác ngụ ý chạy mario thất bại.

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;}

Đây là logic cũ hơn (tương tự như phiên bản hiện tại) với ví dụ sử dụng và đầu ra. Cộng với một số ý kiến ​​giải thích 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=");

    }

}



@KarlKastor, bạn đã hiểu tôi, nhưng trường hợp thử nghiệm đã cho là chính xác. Vấn đề là op không xác định được liệu có nhiều cách để mario đi theo từng bước hay không
Rohan Jhunjhunwala

Chà, tôi cho rằng sẽ có bởi vì tôi sẽ luôn giả sử phiên bản thể loại nhiều hơn nếu không chỉ định bổ sung.
KarlKastor

@KarlKastor yeah bạn đúng
Rohan Jhunjhunwala

7

Python, 260 239 222 215 209 206 byte,

thử nó trên ideone (với các trường hợp thử nghiệm)

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))

gọi như: f([' S=', ' E='])

ghi chú:

Bây giờ, giống như một số giải pháp khác, giả sử đầu vào là một chuỗi các chuỗi coloumn, mỗi chuỗi bắt đầu bằng dấu ""

Wrapper cho mẫu đầu vào cũ: g=lambda x:f(map("".join,zip(*([" "*x.index("\n")]+x.split("\n")))))

Ngoài ra, tôi đã sửa một lỗi mà Mario có thể nhảy qua các khối phía trên anh ta.

phiên bản không có lời giải thích:

fđệ quy gọi chính nó theo mọi hướng mà Mario có thể di chuyển đến từ đó y,x. Nó trả về Truekhi đến "E"nd, sau đó quay trở lại qua tất cả các lệnh gọi hàm cho đến khi gcuối cùng trả về 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

Nếu nhảy không giúp đỡ, bạn sẽ ngã xuống đất. Thêm một elsetrước trận chung kết return?
Tít

5

Ốc sên , 41 37 29 byte

Cảm ơn frageum vì một số trợ giúp để tránh các đường dẫn chồng chéo và để lưu 4 byte.

=\S(^=d=\=u\ ,4(r!\=d.),r),\E

Yêu cầu đầu vào phải được đệm vào một hình chữ nhật sao cho có khoảng trắng trong mỗi ô mà Mario cần phải đi qua (có khả năng với một dòng hàng đầu có đầy khoảng trắng).

Hãy thử trực tuyến!

Giải trình

Ốc sên đã tham gia thử thách thiết kế ngôn ngữ phù hợp với mô hình 2D của chúng tôi. Giống như Trượt, nó cũng tương tự như regex, nhưng điểm khác biệt chính là a) cái này hỗ trợ các xác nhận (nhìn) và b) ngoài các xác nhận này, không thể đi qua bất kỳ ô nào trong lưới hai lần. Điều đó làm cho vấn đề này trở nên khó khăn một chút, vì có những trường hợp Mario cần phải rơi vào một cái hố và nhảy ra ngoài, ví dụ:

S E
= =
===

Ngoài những khác biệt này, cú pháp của hai ngôn ngữ cũng khác nhau khá nhiều.

Để khắc phục vấn đề chúng ta không thể đi qua một ô hai lần, chúng ta luôn xen kẽ một bước ngang với một bước dọc. Tuy nhiên, điều này có nghĩa là chúng ta cần phải xử lý một cú ngã trước khi chúng ta bước qua gờ đá. Vì vậy, về mặt kỹ thuật sẽ thực sự đi qua gạch mặt đất nhưng chúng tôi sẽ đảm bảo rằng chúng chỉ xảy ra bên cạnh không gian mở.

=\S        Ensure that the match starts on an S, without actually matching it.
(          This group matches zero or more steps to the right (with a potential
           vertical step after each one).
  ^=         Match a non-ground cell, stepping right (on the first iteration,
             there is no step yet, so this matches the S).
  d=\=       Ensure that there's a ground tile below, so that the step ends on
             a valid position.
  u\ ,4      Match 0 to 4 spaces going up. This the optional jump.
  (          This group matches zero or more steps down, if a fall is valid here.
    r!\=       Ensure that there is no ground-tile right of the current cell.
    d.         Take one step down onto any character.
  ),
  r          Reset the direction to right for the next iteration.
),
\E        Match the exit.

4

C, 256 236 213 197 byte

20 byte được lưu bởi "Điều này sẽ luôn xuất hiện ở cột ngoài cùng bên trái của đầu vào"
23 byte được lưu nhờ hệ thống dựa trên cột của @ RohanJhunjhunwala

Hãy thử nó trên ideone, với các trường hợp thử nghiệm ...

k,y,x,h;f(v,l)char**v;{h=strlen(*v);x=strcspn(*v,"S");while(y<l&x<h)if(v[y][x]==69)return 0;else if(v[y][x+1]^61)x++;else{if(v[y+1][x]==61)while(k<4)if(v[y+1][x-++k]^61){x-=k;break;}y++;}return 1;}

Sử dụng:

$ ./mario "S=" " =" " =" " =" "E="
main(c,v)char**v;{printf("%s",f(v+1,c-1)==0?"true":"false");}

Ung dung với lời giải thích:

k,y,x,h; //omitting int for saving 4 bytes, global variables initialize as 0 by default
f(v,l)char**v;{ //saving 2 bytes
    h=strlen(v[0]); //get height of map
    x=strcspn(v[0],"S"); //where is start point?
    while(y<l&&x<h) //while not out of bounds
        if(v[y][x]==69)return 0; //if we hit end return 0 (69 is ASCII E)
        else if(v[y][x+1]!=61)x++; //we fall one block if there isn't floor underneath us (61 is ASCII =)
        else{
            if(v[y+1][x]==61) //if there is a wall in front of us
                while(k<4) //start counting
                    if(v[y+1][x-++k]!=61){ //if found a way
                        x-=k; //go to there
                        break; //we don't want to jump multiple times
                    }
            y++; //finally, walk one block forwards
        }
    return 1; //if out of bounds
}

Ideone nói rằng có một lỗi thời gian chạy
TuxCrafting

6
Đợi đã, bạn đang mã hóa trên thiết bị di động
ಠ_ಠ

4
Các bạn ơi, tôi đã đổ than cốc vào máy tính xách tay của mình: P
betseg 24/07/2016

1
(Không có nghĩa là đặt cược , chỉ để đảm bảo tính công bằng) @ TùxCräftîñg: Giải pháp này có phù hợp với thách thức của bạn không vì nó có một chuỗi Chuỗi (đã được phân tách trên "\ n") và cũng có đầu vào là chiều dài và chiều rộng của bản đồ (không phải là một phần của đầu vào trong thử thách của bạn)?
KarlKastor


2

PHP, 399 338 284 265 251 byte

<?function w($m,$p){$w=strpos($m,"
")+1;if($p>strlen($m)|($p%$w)>$w-2|$p<0|'='==$m[$p])return 0;if('E'==$m[$p])die(1);if('='!=$m[$p+$w])return w($m,$p+$w);else for(;$z<5&'='!=$m[$q=$p-$w*$z];$z++)if(w($m,$q+1))die(1);}die(w($m=$argv[1],strpos($m,S)));

mong đợi đầu vào là đối số dòng lệnh với ngắt dòng unix và dấu cách trong mỗi dòng, trả về mã thoát 1để thành công, 0cho thất bại

sự cố để hoạt động

function w($m,$p) // function walk
{
    $w=strpos($m,"\n")+1;
    if($p<0|$p>strlen($m)|($p%$w)>$w-2  // too high / too low / too far right
        | '='==$m[$p]                   // or inside a wall
    )return 0;
    if('E'==$m[$p])return 1;            // Exit found
    if('='!=$m[$p+$w])return w($m,$p+$w); // no wall below: fall down
    else for($z=0;$z<5                  // else: jump
        & '='!=$m[$q=$p-$w*$z]          // do not jump through walls
        ;$z++)
        if(w($m,$q+1))                  // try to walk on from there
            return 1;
    // no success, return failure (NULL)
}
function m($i){$argv=[__FILE__,$i];
    return w($m=$argv[1],strpos($m,S));     // walk through map starting at position of S
}

kiểm tra (trên chức năng m)

$cases=[
    // examples
    "S = E\n=====",0,
    "S   \n=== \n    \n ===\n   E\n====",0,
    "    E \n   == \n==    \n   == \n==    \n   == \n==    \nS  == \n======",0,
    "S      \n=      \n=      \n=      \n=      \n=      \n=      \n= =    \n=      \n=      \n=      \n=     E\n=======",1,
    "S   E\n== ==\n = = ",0,
    " E\n =\n =\n =\nS=\n==",1,
    "      \n =    \n =   E\nS=   =\n==   =\n =   =\n =====",1,
    "S   \n=   \n    \n    \n    \n    \n    \n    \n=  E\n====",1,
    // additional cases
    "S \n= \n=E",1,
    " == \n == \n    \nS==E\n==  ",1
];
echo'<table border=1><tr><th>input</th><th>output</th><th>expected</th><th>ok?</th></tr>';
while($cases)
{
    $m=array_shift($cases);
    $e=array_shift($cases);
    $y=m($m);
    $w=strpos($m,"\n");
    echo"<tr><td><div style=background-color:yellow;width:",$w*8,"px><pre>$m</pre></div>width=$w</td>
        <td>$y</td><td>$e</td><td>",$e-$y?'N':'Y',"</td></tr>";
}
echo'</table>';

1
cho bất cứ ai: Sẽ cho phép bạn cho tôi biết lý do tại sao bạn đánh giá thấp điều này?
Tít

2

Hồng ngọc 153 147 byte

Xin lỗi, Java ... vị trí của bạn là người không chơi golf tốt nhất cho công việc đang được tiếp quản!

Đầu vào là một danh sách các chuỗi cột, được thêm vào một khoảng trống theo kiểu cách các giải pháp Trượt và Ốc yêu cầu đầu vào của chúng được đệm bằng một hình chữ nhật của không gian trống.

Hãy thử trực tuyến!

f=->m,j=0,s=p{c,n=m[j,2]
s||=c=~/S/
e=c=~/E/
s+=1 while(k=c[s+1])&&k!=?=
s==e||(0..4).any?{|i|k&&s>=i&&c[s-i,i]!~/=/&&n&&n[s-i]!=?=&&f[m,j+1,s-i]}}

nooooo .... nhưng bạn đã "mượn" phương pháp chuỗi cột của tôi
Rohan Jhunjhunwala

1
Ý tôi là, tất cả những đứa trẻ tuyệt vời đã làm điều đó rồi. Có thể tạo một giải pháp dựa trên hàng sau, thực hiện "sửa nhanh" để sửa đổi các hàng thành các cột để giữ cho mã hiện tại của tôi mất Java của bạn thêm 10 byte, nhưng một giải pháp thực tế có thể ngắn hơn bất kể
Ink Ink

2

Grime, 46 byte (không cạnh tranh)

A=\E|[S ]&<\ {,-4}/0/./* \ /*/A/\=/./*>
n`\S&A

Tôi đã cập nhật Grime vài lần sau khi thử thách này được đăng, vì vậy câu trả lời này không đủ điều kiện để chiến thắng. Một số thay đổi mới đến mức tôi chưa thể đưa chúng vào TIO, nhưng một khi tôi làm, bạn có thể dùng thử chương trình . Trong mọi trường hợp, kho lưu trữ của tôi chứa một phiên bản xử lý mã này một cách chính xác.

Chương trình in 1nếu Mario có thể đạt được mục tiêu, và 0nếu không. Đầu vào phải chứa khoảng trắng ở tất cả những nơi Mario cần ghé thăm. Đối với đầu vào chung, tôi có giải pháp 57 byte sau:

A=\E|[ \bS]&<[ \b]{,-4}/0/[]/* [ \b]/*/A/\=/[]/*>
nb`\S&A

Giải trình

Giải thích cấp cao là nonterminal A, được xác định trên dòng đầu tiên, khớp với hình chữ nhật phụ 1 × 1 của đầu vào nơi Mario có thể đạt được mục tiêu. Ađược định nghĩa là chữ E(Mario đã có trong mục tiêu) hoặc là mẫu 1 × 1 nằm trên cột bên trái của một số hình chữ nhật 2 × n có chứa Mario nhảy hợp lệ Asang cột khác trên cột bên phải. Dòng thứ hai đếm số lượng các trận đấu Acũng chứa ký tự bắt đầuS và in ra.

Đây là một sự cố về mã:

A=\E|[ S]&<\ {,-4}/0/./* \ /*/A/\=/./*>
A=                                       Define A as
  \E|                                    a literal E, or
     [ S]&                               a literal space or S
          <                           >  contained in a larger rectangle
                                         that this bracketed expression matches.
           \ {,-4}/0/./*                 Left half of the bracketed expression:
           \ {,-4}                        Rectangle of spaces with height 0-4,
                  /                       below that
                   0                      the 1x1 rectangle we're currently matching,
                    /.                    below that any 1x1 rectangles
                      /*                  stacked any number of times vertically.
                         \ /*/A/\=/./*   Right half of the bracketed expression:
                         \ /*             Spaces stacked vertically,
                             /A           below that another match of A,
                               /\=        below that a literal =,
                                  /./*    below that 1x1 rectangles stacked vertically.

Ý tưởng là \ {,-4}phần bên trái khớp với không gian mà Mario nhảy lên, và \ /*phần bên phải khớp với máng không gian mà sau đó anh ta rơi xuống. Chúng tôi yêu cầu anh ta phải tham gia một trận đấu A(vì chúng tôi muốn đạt được mục tiêu) đó là trên đỉnh của một =. Các ngăn xếp thẳng đứng bên dưới cả hai cột sẽ chỉ đảm bảo rằng các cột có cùng chiều cao, vì vậy chúng ta có thể nối chúng (đó là không gian duy nhất ở giữa). Đây là sơ đồ nghệ thuật ASCII của một bước nhảy ví dụ, được chia thành các hình chữ nhật đã nói ở trên và với các khoảng trắng được thay thế bằng *s:

Left column:     Right column:   +---+---+
a = \ {,-4}      d = \ /*        | * | * |
b = 0            e = A           +   +   + d
c = ./*          f = \=          | * | * |
                 g = ./*       a +   +---+
                                 | * | * | e
                                 +   +---+
                                 | * | = | f
                                 +---+---+
                               b | S | = |
                                 +---+   | g
                               c | = | * |
                                 +---+---+

Trên dòng thứ hai, tùy chọn nkích hoạt đếm tất cả các trận đấu, thay vì tìm trận đấu đầu tiên. Trong giải pháp chung, các khoảng trắng cũng có thể là các ký tự ngoài đầu vào đặc biệt và tùy chọn blàm cho đầu vào được đệm bằng các ký tự ngoài đầu vào.

Tôi hy vọng tất cả điều này có ý nghĩa!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.