预测落石


18

在此挑战中,您将获得从侧面看的二维地形图。不幸的是,地形的某些部分漂浮在空中,这意味着它们会坠落。您的工作是预测它们的降落位置。

输入

您的输入是一个或多个等长的换行符分隔的字符串,仅包含以下字符#(数字符号,表示一块岩石)或.(一个句点,表示空白)。

输出

您的输出具有与输入相同的格式,但具有以下修改。让我们将输入字符串视为岩石的二维网格。输入中通过相邻岩石的路径连接到网格底部的每个岩石都是牢固的 ; 其他岩石松动。对角相邻的岩石不视为相邻。所有松散的岩石都将直线下落,最后以一堆堆叠的形式固定在坚硬的岩石或底行上。松散的岩石彼此不相连,因此它们是单独坠落的,而不是大地层。输出是结果网格。

例子

  • 输入

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

    不含松散的岩石,因此输出与此相同。

  • 输入

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

    顶部包含一块松散的岩石,然后掉落在其下方的坚硬岩石上。输出是

    ......
    .#..#.
    .#..##
    .#.#.#
    .#####
    .#...#
    
  • 输入

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

    左侧有一大堆松动的岩石。该组随着岩石的下落而分解,因此输出为

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

澄清说明

  • 您可以从STDIN接收输入并输出到STDOUT,也可以编写函数。
  • 这是代码高尔夫球,因此最短的程序(以字节为单位)是赢家。
  • 不允许出现标准漏洞。

Answers:


12

CJam,180 ... 133101 ... 94 90 87字节

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

肯定有很多打高尔夫球的可能,但是我想在完全使用它之后首先发布它。

快看 没有滚动条!

取岩石格(由向上.#从STDIN没有尾随换行),并打印输出到STDOUT

更新:使用低效但较短的局部洪水填充来确定坚硬的岩石。

更新2:更改了使岩石掉落的算法。现在要短得多!

更新3:做了几次小的优化,最后我将字节数减少到原始代码的一半!

运作方式

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

对于泛洪,我们遍历整个网格长度(网格)时间。在每次迭代中,我们保证将至少1个#直接与一个空间接触的空间转换为(空间)。这里的空间代表着坚硬的岩石群。因此,在length(grid)迭代结束时,我们保证将所有坚硬的岩石用空间表示。

在这里在线尝试


15

Perl 5:98

98,包括2个命令行标志。

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

说明:

#!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我依赖正确完成输入的最后一行,请参见:ideone.com/7E3gQh如果没有这种依赖,它将是一个字符(或更短的一个依赖于相反的字符-缺少最终EOL)。
nutki 2014年

1
比CJam快30%?惊人。我祝贺你。
DLosc

@DLosc不再:P
Optimizer

击败其他命令式语言100-300%?惊人。我祝贺你。;)
DLosc

@DLosc看上面的答案,我不再将Perl包含在命令式语言列表中:P
Optimizer

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

作为带有字符串参数并返回字符串的函数。

首先,在底部添加“ 1”以标识接地线。
第一个循环搜索固定的岩石(接近'1')并将它们也标记为'1'。重复搜索直到找不到更多的坚硬岩石为止。
第二个循环将其余的“#”字符移到底部一行。同样,重复此操作直到没有岩石可以移动为止。
最后,再次将“ 1”替换为“#”,然后切下一行。

少打高尔夫球

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

测试 (您可以证明哪些岩石坚硬而哪些掉落了)

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←⎕]

由于提示输入时不可能(据我所知)输入换行符,因此该程序将字符矩阵作为输入。

所使用的算法是先转换为二进制矩阵(0是空气,1是岩石),然后从底行进行洪水填充,将坚硬的岩石标记为2。然后将每一列划分为“坚硬岩石之间的空间”,并对每个分区进行分类,以使松散的岩石“掉入”空气。

编辑1:使用其他的洪水填充算法打高尔夫球


试运行

运行1

定义一个字符矩阵A并打印:

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

然后A输入程序:

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

运行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字节

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,"#")};

洪水从底部填充岩石,然后将未洪水填充的岩石降落。在泛洪填充中使用大量递归,因此可能会使浏览器滞后一段时间。

这是一个函数-用 g("input")

JSFiddle:http : //jsfiddle.net/mh66xge6/1/

Ungolfed JSFiddle:http//jsfiddle.net/mh66xge6/


1

Python 3,364个字节

我敢肯定,可以从中榨取更多……但是无论如何它永远不会与CJam和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,"#")

与其他答案类似。一个怪癖是,它首先使网格上下颠倒(以使循环索引更方便),并增加了额外的行和列.(以避免环绕-1索引的问题)。通过调用运行P(string)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.