Dự đoán đá rơi


18

Trong thử thách này, bạn được cung cấp một bản đồ về địa hình hai chiều, nhìn từ bên cạnh. Thật không may, một số phần của địa hình đang trôi nổi trong không khí, điều đó có nghĩa là chúng sẽ rơi xuống. Công việc của bạn là dự đoán nơi họ hạ cánh.

Đầu vào

Đầu vào của bạn là một hoặc nhiều chuỗi phân tách dòng mới có độ dài bằng nhau, chỉ chứa các ký tự #(ký hiệu số, biểu thị một tảng đá) hoặc .(một khoảng thời gian, biểu thị không gian trống).

Đầu ra

Đầu ra của bạn có cùng định dạng với đầu vào, nhưng với sửa đổi sau. Chúng ta hãy xem chuỗi đầu vào như một lưới đá hai chiều. Mỗi tảng đá trong đầu vào được kết nối với đáy của lưới bằng một đường dẫn của các tảng đá liền kề là chắc chắn ; đá khác lỏng lẻo . Đá liền kề theo đường chéo không được coi là liền kề. Tất cả các tảng đá lỏng lẻo sẽ rơi thẳng xuống, và kết thúc như một chồng trên đỉnh của một tảng đá vững chắc hoặc hàng dưới cùng. Các tảng đá lỏng lẻo không được gắn với nhau, vì vậy chúng rơi riêng lẻ, không phải là hình thành lớn. Đầu ra là lưới kết quả.

Ví dụ

  • Đầu vào

    ..###.
    .##.#.
    .#....
    .##.#.
    

    không chứa đá lỏng lẻo, vì vậy đầu ra giống hệt với nó.

  • Đầu vào

    ...#..
    .#..#.
    .#..##
    .#...#
    .#####
    .#...#
    

    chứa một tảng đá lỏng lẻo ở trên đỉnh, rơi xuống tảng đá vững chắc dưới nó. Đầu ra là

    ......
    .#..#.
    .#..##
    .#.#.#
    .#####
    .#...#
    
  • Đầu vào

    .#####....
    .#....####
    ###.###..#
    #.#...##..
    .####..#.#
    ......###.
    ..#...#..#
    ..#...#..#
    

    có một nhóm lớn đá lỏng lẻo bên trái. Nhóm bị phá vỡ khi các tảng đá rơi xuống, vì vậy đầu ra là

    ..........
    ....######
    ..#.###..#
    . #...##..
    .##....#..
    .##...####
    ####..#..#
    #####.#..#
    

Làm rõ

  • Bạn có thể lấy đầu vào từ STDIN và xuất ra STDOUT hoặc viết hàm.
  • Đây là môn đánh gôn, vì vậy chương trình ngắn nhất (tính bằng byte) là người chiến thắng.
  • Sơ hở tiêu chuẩn là không được phép.

Câu trả lời:


12

CJam, 180 ... 133 101 ... 94 90 87 byte

qN/~'#/S*_,):L;]N*_,_,*{:A1$='#={[W1LL~)]Af+{W>},1$f=S&,{ASct}*}*}/N/z{S/{$W%}%'#*}%zN*

Chắc chắn có rất nhiều môn đánh gôn có thể, nhưng tôi muốn đăng nó trước sau khi nó hoạt động hoàn toàn.

Nhìn ma đi! Không có thanh cuộn!

Lấy lưới đá (bao gồm .#không có dòng mới) từ STDIN và in đầu ra sang STDOUT

CẬP NHẬT : Sử dụng công cụ lấp lũ một phần không hiệu quả nhưng ngắn hơn để tìm ra đá vững chắc.

CẬP NHẬT 2 : Thay đổi thuật toán để làm cho đá rơi xuống. Bây giờ ngắn hơn nhiều!

CẬP NHẬT 3 : Đã thực hiện một số tối ưu hóa nhỏ và cuối cùng tôi đã có thể giảm số byte xuống một nửa mã ban đầu!

Cách thức hoạt động :

qN/~'#/S*_,):L;]N*             "Preparations";
qN/~                           "Read the input, split by new line and expand the array";
    '#/S*                      "In the last row, replace # by space";
         _,):L                 "Copy the last row and store length + 1 in L";
              ;]N*             "Pop the length, wrap everything in array and join by \n";

_,_,*{ ... }/                  "Flood fill";
_,                             "Copy the array and calculate its length";
  _,                           "Copy the length and calculate [0 - length] array";
    *                          "Repeat the above array, length times";
     { ... }/                  "Run the code block on each element of the array";

:A1$='#={ ... }*               "Process only #";
:A1$                           "Store the number in A and copy the input array to stack";
    =                          "Get Ath index element from input array";
     '#={ ... }*               "Run the code block if Ath element equals #";

[W1LL~)]Af+{W>},1$f=S&,{ASct}* "Flood fill spaces";
[W1LL~)]Af+                    "Get the indexes of the 4 elements on the cross formed by"
                               "the Ath index";
           {W>},               "Filter out the negative values";
                1$f=           "For each of the index, get the char from input string";
                    S&,        "Check if space is one of the 4 chars from above step";
                       {    }* "Run the code block if space is present";
                        ASct   "Make the Ath character of input string as space";

N/z{S/{$W%}%'#*}%zN*           "Let the rocks fall";
N/z                            "Split the resultant string by newlines and"
                               "transpose the matrix";
   {           }%              "Run the code block for each row (column of original)";
    S/{   }%                   "Split by space and run the code block for each part";
       $W%                     "Sort and reverse. This makes # come down and . to go up";
            '#*                "Join by 3, effectively replacing back spaces with #";
                 zN*           "Transpose to get back final matrix and join by newline";

Đối với bãi chôn lấp, chúng tôi lặp lại qua toàn bộ chiều dài lưới (lưới) lần. Trong mỗi lần lặp, chúng tôi được đảm bảo chuyển đổi ít nhất 1 lần #chạm trực tiếp vào khoảng trắng thành (khoảng trắng). Không gian ở đây đại diện cho một nhóm nhạc rock vững chắc. Do đó, khi kết thúc các bước lặp dài (lưới), chúng tôi được đảm bảo có tất cả các khối đá vững chắc được biểu thị bằng các khoảng trắng.

Dùng thử trực tuyến tại đây


15

Perl 5: 98

98 bao gồm 2 cờ dòng lệnh.

#!perl -p0
1while/
/,($x="($`)")=~y!#!.!,s/#(.*
$)/%$1/+s/#$x?%|%$x?#/%$1$2%/s;1while s/#$x\./.$1#/s;y!%!#!

Giải trình:

#!perl -p0 #read entire input to $_ and print at the end
/\n/;($x="($`)")=~y!#!.!; #calculate pattern matching space
                          #between two characters in the same column
                          #looks like "(......)" 
1 while s/#(.*\n$)/%$1/+s/#$x?%|%$x?#/%$1$2%/s;
                          #flood fill solid rock with %
1 while s/#$x\./.$1#/s;   #drop loose rock
y!%!#!                    #change % back to #

@Optimizer Tôi dựa vào dòng đầu vào cuối cùng được hoàn thành đúng cách xem: ideone.com/7E3gQh Nếu không có sự phụ thuộc này, nó sẽ là một người cô đơn (hoặc một người phụ thuộc ngắn hơn vào điều ngược lại - thiếu EOL cuối cùng).
nutki

1
Đánh bại CJam gần 30%? Kinh ngạc. Tôi chúc mừng bạn.
DLosc

@DLosc Không còn nữa: P
Trình tối ưu hóa

Đánh bại các ngôn ngữ mệnh lệnh khác bằng 100-300%? Kinh ngạc. Tôi chúc mừng bạn. ;)
DLosc

@DLosc Nhìn vào câu trả lời trên, tôi sẽ không đưa Perl vào danh sách các ngôn ngữ bắt buộc nữa: P
Trình tối ưu hóa

5

JavaScript (ES6) 232

s=>{for(s=[...s+'1'.repeat(r=1+s.search('\n'))];s=s.map((c,p)=>c=='#'&(s[p+1]|s[p-1]|s[p-r]|s[p+r])?f=1:c,f=0),f;);for(;s.map((c,p)=>c=='#'&s[p+r]=='.'&&(s[p]='.',f=s[p+r]=c),f=0),f;);return s.join('').replace(/1/g,rok).slice(0,-r)}

Là một hàm với một tham số chuỗi và trả về một chuỗi.

Đầu tiên, thêm một hàng dưới cùng '1' để xác định đường mặt đất.
Tìm kiếm vòng lặp đầu tiên cho các tảng đá cố định (gần '1') và cũng đánh dấu chúng là '1'. Tìm kiếm được lặp lại cho đến khi không tìm thấy đá cứng hơn.
Vòng lặp thứ hai di chuyển các ký tự '#' còn lại về phía hàng dưới cùng. Một lần nữa, điều này được lặp lại cho đến khi không có đá có thể được di chuyển.
Cuối cùng, thay thế '1' bằng '#' một lần nữa và cắt hàng dưới cùng.

Ít chơi gôn

s=>{
  r = 1+s.search('\n');
  s = [...s+'1'.repeat(r)];
  for (; s = s.map((c,p) => c=='#' & (s[p+1]|s[p-1]|s[p-r]|s[p+r])?f=1:c,f=0),f; );
  for (; s.map((c,p) => c=='#' & s[p+r]=='.'&& (s[p] ='.', s[p+r]=c, f=1),f=0),f; );
  return s.join('')
    .replace(/1/g,'#')
    .slice(0,-r)
}

Kiểm tra (Bạn có thể có bằng chứng về những gì đá cứng và những gì đã rơi)

F=
s=>{for(s=[...s+'1'.repeat(r=1+s.search('\n'))];s=s.map((c,p)=>c=='#'&(s[p+1]|s[p-1]|s[p-r]|s[p+r])?f=1:c,f=0),f;);for(;s.map((c,p)=>c=='#'&s[p+r]=='.'&&(s[p]='.',f=s[p+r]=c),f=0),f;);return s.join('').replace(/1/g,rok).slice(0,-r)}

var rok // using rok that is 3 chars like '#'

function update() {
  rok = C.checked ? '@' : '#';
  O.textContent=F(I.textContent)
}

update()
td { padding: 5px }
pre { border: 1px solid #000; margin:0 }
<table><tr><td>Input</td><td>Output</td></tr>
<tr><td><pre id=I>.#####....
.#....####
###.###..#
#.#...##..
.####..#.#
......###.
..#...#..#
..#...#..#</pre></td>
<td><pre id=O></pre>
</td></tr></table>
<input type='checkbox' id=C oninput='update()'>Show firm rocks


3

APL, 130 119

'.##'[1+⊖1↓⍉↑↑{,/{⍵[⍒⍵]}¨x⊂⍨2=x←2,⍵}¨↓ ⍉⊃⌈/(1,¨⍳⍴⊃↓x){x←⍵⋄(⍺⌷x)∧←2⋄x≡⍵:x⋄⊃⌈/((⊂⍴⍵)⌊¨1⌈(,∘-⍨↓∘.=⍨⍳2)+⊂⍺)∇¨⊂x}¨⊂⊖'#'=x←⎕]

Vì không thể (theo như tôi biết) để nhập dòng mới khi đầu vào được nhắc, chương trình này lấy ma trận ký tự làm đầu vào.

Thuật toán được sử dụng trước tiên là chuyển đổi thành ma trận nhị phân ( 0là không khí và 1là đá) sau đó lấp đầy từ hàng dưới cùng để đánh dấu các tảng đá vững chắc như 2. Sau đó phân vùng từng cột thành "khoảng trống giữa các tảng đá vững chắc" và sắp xếp từng phân vùng để làm cho tảng đá lỏng lẻo "rơi" vào không khí.

Chỉnh sửa1: Đánh gôn một số bằng thuật toán lấp lũ khác


Chạy thử

Chạy 1

Xác định một ma trận ký tự Avà in nó:

      A←↑('.#####....') ('.#....####') ('###.###..#') ('#.#...##..') ('.####..#.#') ('......###.') ('..#...#..#') ('..#...#..#')
      A
.#####....
.#....####
###.###..#
#.#...##..
.####..#.#
......###.
..#...#..#
..#...#..#

Sau đó Ađưa vào chương trình:

      '.##'[1+⊖1↓⍉↑↑{,/{⍵[⍒⍵]}¨x⊂⍨2=x←2,⍵}¨↓⍉(1,¨⍳⊃⌽⍴x){⍵≡y←⊃⌈/x←⍺{x←⍵⋄(⍺⌷x)∧←2⋄x}¨⊂⍵:y⋄((⊂⍴⍵)⌊¨1⌈,(,∘-⍨↓∘.=⍨⍳2)∘.+⍺/⍨x≢¨⊂⍵)∇y}⊖'#'=x←⎕]
⎕:
      A
..........
....######
..#.###..#
..#...##..
.##....#..
.##...####
####..#..#
#####.#..#

Chạy 2

      A←↑('#######')('#.....#')('#.#.#.#')('#.....#')('#######')
      A
#######
#.....#
#.#.#.#
#.....#
#######
      '.##'[1+⊖1↓⍉↑↑{,/{⍵[⍒⍵]}¨x⊂⍨2=x←2,⍵}¨↓⍉(1,¨⍳⊃⌽⍴x){⍵≡y←⊃⌈/x←⍺{x←⍵⋄(⍺⌷x)∧←2⋄x}¨⊂⍵:y⋄((⊂⍴⍵)⌊¨1⌈,(,∘-⍨↓∘.=⍨⍳2)∘.+⍺/⍨x≢¨⊂⍵)∇y}⊖'#'=x←⎕]
⎕:
      A
#######
#.....#
#.....#
#.#.#.#
#######

2

JS - 443 byte

function g(b){function f(b,c,e){return b.substr(0,c)+e+b.substr(c+1)}function e(d,c){"#"==b[c][d]&&(b[c]=f(b[c],d,"F"),1<d&&e(d-1,c),d<w-1&&e(d+1,c),1<c&&e(d,c-1),c<h-1&&e(d,c+1))}b=b.split("\n");w=b[0].length;h=b.length;for(i=0;i<w;i++)"#"==b[h-1][i]&&e(i,h-1);for(j=h-2;-1<j;j--)for(i=0;i<w;i++)if(k=j+1,"#"==b[j][i]){for(;k<h&&"F"!=b[k][i]&&"#"!=b[k][i];)k++;k--;b[j]=f(b[j],i,".");b[k]=f(b[k],i,"#")}return b.join("\n").replace(/F/g,"#")};

Lũ lấp đầy những tảng đá từ dưới lên, sau đó mang những tảng đá không bị ngập xuống. Sử dụng rất nhiều đệ quy với vùng lũ để nó có thể làm chậm trình duyệt của bạn một chút.

Đó là một chức năng - gọi nó với g("input")

Mã thông báo: http://jsfiddle.net/mh66xge6/1/

Mã hóa khó hiểu: http://jsfiddle.net/mh66xge6/


1

Python 3, 364 byte

Tôi chắc chắn nhiều hơn có thể bị vắt kiệt từ điều này ... nhưng dù sao nó cũng sẽ không bao giờ cạnh tranh với CJam và Perl.

z="%";R=range
def F(r,c,g):
 if z>g[r][c]:g[r][c]=z;[F(r+d%2*(d-2),c+(d%2-1)*(d-1),g)for d in R(4)]
def P(s):
 t=s.split()[::-1];w=len(t[0]);g=[list(r+".")for r in t+["."*w]];[F(0,c,g)for c in R(w)]
 for c in R(w):
  for r in R(len(g)):
   while g[r][c]<z<g[r-1][c]and r:g[r][c],g[r-1][c]=".#";r-=1
 return"\n".join(''.join(r[:w])for r in g[-2::-1]).replace(z,"#")

Tương tự như các câu trả lời khác. Một điều khó hiểu là nó lật ngược lưới trước (để làm cho các chỉ số vòng lặp thuận tiện hơn) và thêm một hàng & cột bổ sung .(để tránh các vấn đề với -1các chỉ số gói ). Chạy bằng cách gọi P(string).

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.