떨어지는 바위를 예측


18

이 도전에서는 측면에서 본 2 차원 지형지도가 제공됩니다. 불행하게도, 지형의 일부는 공중에 떠 있습니다. 당신의 임무는 그들이 어디로 착륙하는지 예측하는 것입니다.

입력

입력은 문자 #(숫자 부호, 바위를 나타냄) 또는 .(공백을 나타내는 마침표 ) 만 포함하는 길이가 같은 하나 이상의 줄 바꾸기로 구분 된 문자열입니다 .

출력

출력은 입력과 동일한 형식이지만 다음과 같이 수정됩니다. 입력 문자열을 2 차원 바위 격자로 보자. 인접한 암석의 경로에 의해 그리드의 바닥에 연결된 입력의 모든 암석은 견고합니다 . 다른 바위는 느슨하다 . 대각선으로 인접한 암석은 인접한 것으로 간주되지 않습니다. 느슨한 바위는 모두 똑바로 떨어지고 단단한 바위 또는 맨 아래 줄 위에 쌓입니다. 느슨한 바위는 서로 붙어 있지 않으므로 큰 형성이 아니라 개별적으로 떨어집니다. 출력은 결과 그리드입니다.

  • 입력

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

    느슨한 암석이 없으므로 출력이 동일합니다.

  • 입력

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

    상단에 느슨한 바위가 하나 있는데, 그 밑에 단단한 바위가 있습니다. 출력은

    ......
    .#..#.
    .#..##
    .#.#.#
    .#####
    .#...#
    
  • 입력

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

    왼쪽에 느슨한 암석 그룹이 많이 있습니다. 암석이 떨어지면 그룹이 무너 지므로 출력은

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

설명

  • STDIN에서 입력을 가져 와서 STDOUT으로 출력하거나 함수를 작성할 수 있습니다.
  • 이것은 코드 골프이므로 가장 짧은 프로그램 (바이트)이 승자입니다.
  • 표준 허점은 허용되지 않습니다.

답변:


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에서 후행 개행없이)를 표준 출력으로 출력을 인쇄

업데이트 : 비효율적이지만 짧은 부분 홍수 채우기를 사용하여 견고한 암석을 알아냅니다.

업데이트 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 개 이상 을 (공간)으로 변환해야합니다. 여기의 공간은 확고한 록 그룹을 나타냅니다. 따라서 길이 (그리드) 반복이 끝나면 모든 단단한 암석이 공백으로 표시됩니다.

여기에서 온라인으로 사용해보십시오


15

펄 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

1
CJam을 거의 30 % 앞당겼습니까? 놀랄 만한. 축하합니다
DLosc

@DLosc 더 이상은 : P
최적화

다른 명령형 언어를 100-300 % 이겼습니까? 놀랄 만한. 축하합니다 ;)
DLosc

위의 대답에 @DLosc 찾고, 더 이상 명령형 언어 목록에 펄이 포함되지 않습니다 : P
최적화

5

자바 스크립트 (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합니다. 그런 다음 각 기둥을 "견고한 바위 사이의 공간"으로 분할하고 각 파티션을 정렬하여 느슨한 바위가 공기에 "떨어지도록"합니다.

Edit1 : 다른 홍수 채우기 알고리즘을 사용하여 골프를 쳤습니다.


시운전

실행 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

파이썬 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).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.