Gravity Guy có thể làm điều đó?


27

Gravity Guy là một trò chơi trong đó đầu vào duy nhất của người dùng là một phím duy nhất lật hướng trọng lực. Đưa ra một mức độ nghệ thuật ASCII, xác định xem liệu Gravity Guy có thể đi đến cuối cùng hay không.


Quy tắc

  • Hướng ban đầu của trọng lực là xuống .
  • Cột đầu tiên của đầu vào sẽ luôn chỉ chứa một # , mà Gravity Guy bắt đầu ở trên cùng.
  • Mỗi lần lặp lại, anh ta di chuyển đến nhân vật trực tiếp bên phải .
  • Nếu đường dẫn của anh ta bị chặn và anh ta di chuyển vào a #, người chơi sẽ thua .
  • Sau khi di chuyển, người chơi có thể tùy ý chuyển trọng lực từ xuống lên hoặc xuống.
  • Gravity Guy sau đó rơi vào tiếp theo# (theo hướng trọng lực hiện tại).
  • Nếu không có #rơi vào và anh ta rơi ra khỏi lưới , người chơi sẽ thua .
  • Nếu Gravity Guy di chuyển khỏi phía bên phải của lưới đầu vào, người chơi sẽ thắng .

Thí dụ

Nếu đây là lưới đầu vào:

  ### 

#  # #
 ###  

Gravity Guy sẽ bắt đầu tại xvà ở các vị trí này sau mỗi lần lặp. ^= chuyển trọng lực lên và v= chuyển trọng lực xuống.

v                        ^                               v
-------------------------------------------------------------
  ###   |    ###   |    ###   |    ###   |    ###   |    ### 
x       |          |    x     |     x    |      x   |        
#  #    |  #x #    |  #  #    |  #  #    |  #  #    |  #  # x
 ### #  |   ### #  |   ### #  |   ### #  |   ### #  |   ### #

Như bạn có thể thấy, bằng cách chuyển trọng lực vào những thời điểm này, Gravity Guy đạt đến điểm cuối, do đó, đầu vào này sẽ trả về giá trị trung thực.

Thông số kỹ thuật

  • Lưới đầu vào có thể ở bất kỳ định dạng "lưới" thích hợp nào (chuỗi nhiều dòng được đệm bằng khoảng trắng, mảng chuỗi dòng, mảng mảng ký tự, v.v.).
  • Nếu nó là tốt cho các cầu thủ để giành chiến thắng cấp độ, sản lượng một truthygiá trị. Nếu không, xuất ra một falseygiá trị.
  • Chiều rộng và chiều cao của lưới sẽ là các 50ký tự nhiều nhất.
  • Đây là , có thể mã ngắn nhất tính bằng byte sẽ thắng!

Các trường hợp thử nghiệm

(mỗi trường hợp cách nhau bởi ----------, bất kỳ dòng trống nào cũng cần được đệm bằng khoảng trắng)

Thật

 #########   ########      ######     ######    
          #  #       #    #      #   #      #   
###    #   # #    #   #  #       #  #        #  
  #    ##  # #    ##  # #     # #  #      ##    
  #    #   # #    #   # #    #     #     #######
  #       #  #       #  #     ###  #          # 
  #    ##    #    ##     #       #  #         # 
  #    #          #              #        #   # 
  #    ####################################   # 
  #                                           # 
  ############################################# 

----------


###

----------

   #####

####    

----------

 #####
 # # #

# # # 
 #####

----------

   ############   

######      ######

   ############   

----------

  ###   ###  
     # #     
####  #  ####
    #   #    
     # #     
      #      

----------

    ######  
   #        
 ##         
     #######
###     #   
   #    #   
    #####   


----------

    #####   
   #    #   
 ##     #   
     #######
###         
   #        
    ######  

----------

  ### 

#  # #
 ###  

----------

  ###  ###

###     ##
   #    # 
    ##### 

----------

  #        
     #   # 
       #   
#   #     #
        #  
   #       
      #    
 #         

----------

    ##### ####   
   #     #    #  
  #   # #  ##  # 
             #  #
#####  ####   #  
               # 
     #########   

----------

 ########################### 
 #   #   #   #     #   #   # 
 # # # #   #   # #   #   # # 
 # # # ######### ########### 
 # # # #  #       #     #  # 
   # # # ## ##### ### #      
## #   #    #          ## ###
 # ##### #### ###########  # 
 # #     #  #     #     ## # 
 # # #####  ### # # # # #  # 
 #              #   # #   ## 
 ########################### 

Sai

 ###
   #
####

----------


### ###

----------

    #   
 ### ###

#### ###
    #   

----------

  ###     ###  
     # # #     
####  # #  ####
    #     #    
     #   #     
      # #      
       #       

----------

  ####### 
  #     # 
 ## ##### 

### ######
  #     # 
  ####### 

----------

 ########################### 
 #   #   #   #  #  #   #   # 
 # # # #   #   # #   #   # # 
 # # # ######### ########### 
 # # # #  #       #     #  # 
   # # # ## ##### ### #      
## #   #    #          ## ###
 # ##### #### ###########  # 
 # #     #  #     #     ## # 
 # # #####  ### # # # # #  # 
 #              #   # #   ## 
 ########################### 

Chúng tôi có cho phép lưới ở định dạng cột không?
Neil

@Neil Bạn có nghĩa là một mảng chuyển / xoay? Tôi sẽ nói không, vì nó làm thay đổi đầu vào. Nhưng nếu ngôn ngữ của bạn có một columnloại đặc biệt , tôi đoán sẽ ổn khi sử dụng.
dùng81655

Có thể cho #cột đầu tiên ở hàng đầu tiên không?
frageum

@feersum Không, bạn có thể giả sử lưới sẽ bao gồm không gian để Gravity Guy "đứng".
user81655

Xấu hổ; chuyển vị làm tăng số byte của tôi thêm 20%.
Neil

Câu trả lời:


19

Ốc , 15 byte

Dùng thử trực tuyến?

^
\ n\ ,=\#r}+~

0. ^là một tùy chọn yêu cầu mẫu bắt đầu ở phía trên bên trái.

  1. \ ​: không gian phù hợp

  2. n: Xoay 90 độ theo hai hướng

  3. \ ,​: khớp không gian bằng 0 lần trở lên

  4. =\#kiểm tra xem có một #trước mặt chúng tôi

  5. r: đặt hướng sang phải

  6. }+: làm tất cả các lần trước một hoặc nhiều lần

  7. ~ phù hợp với một ô nằm ngoài giới hạn lưới


Điều này cho 0 cho hầu hết các trường hợp thử nghiệm thực sự
Bassdrop Cumberwubwubwub

@Bas Bạn đã đệm các dòng trống với khoảng trắng chưa?
Martin Ender

@ MartinBüttner Tôi đã sao chép trực tiếp một số đầu vào, làm như vậy thực sự đã loại bỏ một số khoảng trắng. Nó thực sự hoạt động sau khi thêm khoảng trắng
Bassdrop Cumberwubwubwub

5
Vì chưa ai nói điều này: Điều này thật tuyệt vời!
DLosc

9

Perl, 93 89 81 77 76 75 74 byte

Bao gồm +2 cho -0p

Chạy với mẫu đầu vào (với tất cả không gian dòng được đệm cùng chiều dài) trên STDIN:

gravity.pl < gravity.txt

gravity.pl:

#!/usr/bin/perl -0p
/
/;$n=".{@-}";s/#$n\K( $n)*\b |(^|w)([w ]$n)*\K $n#/w|$&/es&&redo;$_=m;w

Phiên bản dựa trên tệp này cần dòng mới cuối cùng, vì vậy đó thực sự là 75 byte. Nhưng phiên bản dựa trên dòng lệnh không cần thêm dòng mới để số này được tính là 74 byte:

perl -0pe '/
/;$n=".{@-}";s/#$n\K( $n)*\b |(^|w)([w ]$n)*\K $n#/w|$&/es&&redo;$_=m;w' < gravity.txt

Giải trình:

Điều này sẽ xây dựng một chuỗi với một wvị trí mà anh chàng có thể đạt được. Vì vậy, đối với ví dụ trung thực thứ hai đến cuối cùng, nó sẽ xây dựng:

     #########   
    ##### ####   
   #wwwww#wwww#  
  #w  # #w ##ww# 
wwwww wwwwwww#ww#
#####  ####  w#ww
     wwwwwwwwww# 
     #########   

Vì vậy, anh chàng trọng lực có thể làm cho nó nếu và chỉ khi có một wtrong cột cuối cùng. Chuỗi sẽ được xây dựng bằng cách thay thế một không gian có thể tiếp cận bằng wtrong mỗi vòng.

Mỗi sự thay thế sẽ có dạng

s/prefix \K space postfix/ w | $& /e

sẽ yêu cầu không gian được đi trước bởi tiền tố và tiếp theo là hậu tố nhưng chỉ thay thế không gian bằng cách wkhông cần nhiều nhóm nâng cao.

Giả sử $nchứa một biểu thức chính quy sẽ tiến triển vừa đủ để hai bên trái và phải chính xác nằm bên dưới nhau. Sau đó, các biểu thức liên quan là:

/^( $n)*\K $n#/       From the first position drop down as long as you
                      encounter spaces until you encounter a #. 
                      This puts gravity guy on his starting platform

/#$n\K( $n)*\b /      A space immediately below a # and if you (optionally)
                      go down further from there (as as the descent is
                      over spaces) you get to a space that follows a word
                      boundary. The only way to get a word boundary is if 
                      there is a w in front of that space. This selects the
                      position gravity guy ends up on if starting from that
                      w and gravity is up
/w([w ]$n)*\K $n#/    A w followed by a space (or w) and if you go down from
                      there as long as it is over spaces (or w) you finally
                      end up on a space directly above a #. This handles the
                      gravity down case. The test uses "space or w" instead
                      of just space to handle this case:

                       #
                      ww
                      #x  
                       #

                      Position x is currently a space and must be replaced by a
                      w but the gravity up regex has already put a w directly
                      after the w gravity guy takes off from. So for gravity
                      down we must handle w as if it is still a space. This
                      is not needed for gravity up because regex always matches
                      starting at the earliest possible character, so 
                      gravity up matches before gravity down

Với cách đó, chương trình rất dễ dàng:

#!/usr/bin/perl -0p   Slurp all of STDIN into $_, at the end print $_

/\n/                  Match the first newline (needed to measure the row
                      length)
$n=".{@-}"            $n effectively becomes rowlength-1 times ".". This
                      will be the regex that goes one step down a column

s/#$n\K( $n)*\b |(^|w)([w ]$n)*\K $n#/w|$&/es

                     This is the 3 regexes shown above combined. The s 
                     modifier is needed so the . in $n also matches newline

    &&redo           Keep looping as long as w's keep getting added

$_=m;w\n;            Check if the last column contains a w: He made it!
                     The \n; at the end is not written. These 2 bytes sneakily
                     come from the -p option for the ; and the -e option
                     for the \n

3

JavaScript (ES6), 174 byte

a=>[...a[0]].map((_,i)=>[...t].map(x=>s[x]<'#'&&g(s.indexOf('#',x),-1)&&g(s.lastIndexOf('#',x),1),s=a.map(s=>s[i]),t=new Set),t=new Set([0]),g=(i,d)=>i<0||t.add(i+d))&&t.size

Lấy một chuỗi các chuỗi ngang và trả về số lượng điểm thoát. Chuyển mảng có giá 29 byte. Ung dung:

function gravity(array) {
    var set = new Set;
    set.add(0); // starting point
    for (var i = 0; i < array[0].length; i++) {
        var s = array.map(s => s[i]); // transpose array
        var old = set;
        set = new Set;
        for (var x of old) {
            if (s[x] == '#') continue; // hit wall
            var j = s.indexOf('#', x); // try downward gravity
            if (j >= 0) set.add(j - 1);
            j = s.lastIndexOf('#', x); // try upward gravity
            if (j >= 0) set.add(j + 1);
        }
    }
    return set.size;
}

3

Pip , 85 68 62 59 + 1 = 60 byte

Sử dụng -rcờ để đọc tất cả các dòng của stdin.

FcZg{YlFxiIc@xQsyPB(Jc@<x@?`# *$`)+1PB(c@>x@?'#)+x-1i:UQy}i

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

Giải thích ngắn gọn

Chiến lược này thực chất là một tìm kiếm đầu tiên. Chúng tôi hoán chuyển đầu vào và vòng lặp qua các dòng (cột), giữ một danh sách các vị trí y mà người chơi có thể đạt được trong cột đó. Đầu ra sau cột cuối cùng là danh sách không trống nếu người chơi có thể giành chiến thắng hoặc danh sách trống (in dưới dạng dòng mới) nếu người chơi thua.

Giải thích đầy đủ

Biến tích hợp được sử dụng trong chương trình này: i == 0, l == [], s == " ".

Các -rlá cờ đặt một danh sách các dòng đầu vào g. FcZg{...}khóa gvà vòng trên mỗi cột c. (Unary Z, khi được áp dụng cho một danh sách các lần lặp, hoạt động như Python zip(*g), hoán chuyển gọn gàng một mảng 2D.) Lưu ý rằng đó csẽ là một danh sách, không phải là một chuỗi.

Trong vòng lặp cột, chúng tôi đặt lại yvào danh sách trống bằng cách Yanking l. Fxivòng lặp qua i. Trong các lần lặp lại sau, isẽ là một danh sách các tọa độ y mà người chơi có thể đạt được trong cột trước đó. Lần đầu tiên thông qua, chúng tôi muốn bắt đầu chỉ với 0(góc trên bên trái). Biến này được khởi tạo trước thành vô hướng 0, không phải là Danh sách [0], nhưng Pip lặp đi lặp lại theo cách đó.

Đối với mỗi vị trí hợp lệ trong cột cuối cùng, hãy Ic@xQskiểm tra xem có khoảng trắng ở vị trí đó trong cột hiện tại không. Nếu không, người chơi chỉ cần chạy vào một bức tường và chúng tôi tiếp tục thử khả năng tiếp theo. Nếu vậy, thì chúng tôi muốn tìm các vị trí mà người chơi sẽ rơi vào cột này cho mỗi hướng trọng lực và thêm chúng vào danh sách ybằng cách sử dụng toán tử ack Push B.

Trọng lực đi lên (trái, trong phiên bản chuyển đổi):

(Jc@<x@?`# *$`)+1
  c@<x             Slice everything left of x in the column
 J                 Join into a string so we can do a regex search on it
      @?`# *$`     Find index of the last # in this string
(             )+1  The player's index is the space below/to the right of this #

Trọng lực đi xuống (phải, trong phiên bản chuyển đổi):

(c@>x@?'#)+x-1
 c@>x              Slice everything right of x in the column
     @?'#          Find index of the first # in this list (no need to join into string)
(        )+x       Translate to index number in entire column
            -1     The player's index is the space above/to the left of this #

Nếu người chơi rơi khỏi lưới theo một hướng cụ thể, @?thao tác tương ứng sẽ không tìm thấy #và sẽ cung cấp cho con số không. Đây không phải là một chỉ mục hợp lệ và sẽ tạo ra một số cảnh báo trong lần lặp tiếp theo - tuy nhiên, không thể nhìn thấy nếu không có -wcờ. Đối với mục đích của chúng tôi, những trường hợp này về cơ bản được loại bỏ khỏi xem xét.

Sau vòng lặp bên trong, i:UQylấy danh sách ycác vị trí chúng tôi đã tạo, loại bỏ trùng lặp và gán nó vào i. (Loại bỏ trùng lặp là cần thiết bởi vì nếu không thì danh sách bóng theo cấp số nhân.) Sau đó chúng tôi đi đến cột tiếp theo. Khi chúng tôi đã lặp qua tất cả các cột, nếu có một đường dẫn hợp lệ đi qua, isẽ là một danh sách các vị trí không trống (tính trung thực); nếu không, nó sẽ là một danh sách trống (falsey).

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.