임의의 아이스 큐브 트레이 채우기


27

이 공간과 공간이 X이상한 모양의 빈 아이스 큐브 트레이 의 단면을 나타냅니다 .

   X     X X        
X  X X  XX X  XX   X
XXXXXX XXXXXXXXXXXXX

이없는 열 X은 물을 담을 수없는 트레이의 구멍이나 틈을 나타내며 무한한 용량 싱크로 배출됩니다. 그리드의 가장 왼쪽 또는 가장 오른쪽 가장자리에서 떨어지는 물도이 끝없는 싱크대로 들어갑니다.

트레이 위에 수도꼭지를 배치하고 모든 구획의 수위가 안정적으로 유지 될 때까지 물을 채우도록하려면 채워지는 정확한 구획은 수류가 트레이 위에 위치한 위치에 따라 달라집니다. (튀지 않고 얇고 꾸준한 물 흐름을 가정하십시오.)


예를 들어 수도꼭지 F가 가장 왼쪽 그리드 기둥 위에있는 경우

F                   
   X     X X        
X  X X  XX X  XX   X
XXXXXX XXXXXXXXXXXXX

물은 X해당 컬럼 에서 가장 위로 떨어지고 왼쪽과 오른쪽으로 퍼지고 왼쪽 절반은 아래 싱크대에 쏟아지고 오른쪽 절반은 2x1 구획을 채 웁니다. 구획이 채워지면, 수류의 오른쪽 절반은 아무데도 흐르지 않고 싱크대로 흘러 들어가고 수위는 기본적으로 안정적입니다.

수도꼭지를 끄면 트레이는 다음과 같이 보입니다. ( ~물)

   X     X X        
X~~X X  XX X  XX   X
XXXXXX XXXXXXXXXXXXX

마찬가지로 수도꼭지를 다음과 같이 배치하면 :

   F                
   X     X X        
X  X X  XX X  XX   X
XXXXXX XXXXXXXXXXXXX

두 개의 가장 왼쪽 구획을 채우지 만 나머지 물은 배수됩니다.

   X     X X        
X~~X~X  XX X  XX   X
XXXXXX XXXXXXXXXXXXX

수도꼭지를 다음과 같이 배치하면 :

         F          
   X     X X        
X  X X  XX X  XX   X
XXXXXX XXXXXXXXXXXXX

스트림의 왼쪽 절반은 싱크대로 흘러 들어가지만 오른쪽 절반은 물이 평평한 표면에서 수평으로 얼마나 멀리 이동할 수 있는지에 대한 제한이 없기 때문에 3 개의 가장 오른쪽 구획을 채 웁니다.

   X     X~X        
X  X X  XX~X~~XX~~~X
XXXXXX XXXXXXXXXXXXX

그러나 다음과 같이 배치되었습니다.

        F           
   X     X X        
X  X X  XX X  XX   X
XXXXXX XXXXXXXXXXXXX

모든 물이 배수되고 구획이 채워지지 않습니다.

   X     X X        
X  X X  XX X  XX   X
XXXXXX XXXXXXXXXXXXX

도전

공간의 직사각형 그리드에 걸리는 프로그램이나 함수 작성 X의 및 하나 F. 맨 윗줄에는 항상 F공백이 포함되고 그렇지 않으면 공백 만 포함됩니다. X각 열에서의이 (임의있는 경우) 계통의베이스에서 실선까지 연장되며, 즉 어떠한 동굴이나 돌출 없을 것이다.

수도꼭지 F~위에 설명 된대로 물로 가능한 것을 채운 후 그리드를 인쇄하거나 반환하십시오 . F출력 에서 맨 위 행을 비워 두십시오 .

  • 수도꼭지 줄을 제외한 그리드는 최소 1 × 1이되므로

    F
    X
    

    지원해야하는 가장 작은 입력입니다.

  • 입력은 완전한 텍스트 사각형으로 나타납니다. 선행 및 후행 공백은 입력 및 출력에 중요합니다. 예를 들어 입력

        F     
      X  X    
      XXXX    
    

    결과

      X~~X    
      XXXX    
    

    (앞뒤 공백 참고)

  • 입력 또는 출력에 단일 후행 줄 바꿈이 있으면 좋습니다.

  • 당신은 어떤 뚜렷한 사용할 수있는 인쇄 가능한 ASCII 공간 대신에 문자를, X, F, ~.

바이트 단위의 가장 짧은 코드가 이깁니다.


큰 예 :

입력:

                F                                 
              X             X                     
              X             X X                   
X            XXX       X    X X           X    X  
X   X     XXXXXXX      X    XXX     XXXXXXX X  X  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXX

산출:

              X~~~~~~~~~~~~~X                     
              X~~~~~~~~~~~~~X~X                   
X~~~~~~~~~~~~XXX~~~~~~~X~~~~X~X~~~~~~~~~~~X    X  
X~~~X~~~~~XXXXXXX~~~~~~X~~~~XXX~~~~~XXXXXXX X  X  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXX

오, 그래, 내가 사랑하는 zip()<3
cjfaure

2
이것은 답이 필요합니다 : / 나는 그것을 할 것입니다.
TheNumberOne

이것을 시뮬레이트하는 셀룰러 오토 마톤을 만드는 것은 비교적 쉽지만, 나는 그것을 끝내는 방법을 생각할 수 없습니다.
DanTheMan

여전히 경쟁 할 사람이 없습니까? 너무 귀여운 도전. 나 자신을 이길 것 같습니다 :)
Jakuje

답변:


1

펄 -p0, 204 + 2 바이트

생각

  • F 아래의 섬 양쪽이 같은 높이이면 해당 섬의 모든 X *Xes를 X~*Xes 로 바꿉니다.
  • 한쪽이 더 높은 경우 , 아래쪽의 배수구와 아래쪽의 상단보다 높은 F에 가장 가까운 지점 사이의 모든 X *Xes를 X~*Xes로 교체하십시오 .

F 바로 아래의 토지는 여기 양쪽의 일부로 계산됩니다.

골프

s/.*(F).*
//;$f=@-[1];($%,$r)=map{y///c}/(.{0,$f})\bX+?\b(.*)$/;($a,$b)=map{y///c}/[^~]*^(?(?=(.{$%,$f}X)).{$f} *|.{$f} *X(.*)).{$r}
/m;$a=$%if!$a||$b;$b+=$r;s/(?<=.{$a})\b *\b(?=.{$b})/"~"x length($&)/ge

노트

perl -p0e ' # slurp stdin, print the result

s/.*(F).*\n//; # remove the first line, record the index of F
$f=@-[1]; # get the index of F

($l,$r)=map{length}m/(.{0,$f})\bX+?\b(.*)$/;
# gets the distance from either side to the drains closest to F
($a,$b)=map{length}m/[^~]*^(?(?=(.{$l,$f}X)).{$f} *|.{$f} *X(.*)).{$r}\n/m;
# tries to find the lowest line that has at least one X on
# one side of the island, but none on the other
$a=$l if !$a||$b;
$b+=$r; # use the captured groups to calculate the left and right bounds
s/(?<=.{$a})\b *\b(?=.{$b})/"~" x length($&)/ge;
# replace all pools within those bounds
'

Perl은 가변 길이의 lookbehinds를 지원하지 않으므로이 구현에서 원래 알고리즘을 인식하기 어려울 수 있습니다.


6

루아 5.2, 581 바이트

다시 말하지만, 골프에는 비효율적 인 언어와 비효율적 인 알고리즘으로 시작하십시오. 그러나 나는 향상시킬 것이다 :)

r=io.read w=io.write F=r()f=F:find("F")o={[1]=F}W=#F i=2 
repeat s=r()if s==nil then break end o[i]={}for j=1,W do o[i][j]=s:sub(j,j)end i=i+1 until false
function e(i,j)
local k,l,b,c=j+1,j-1,false
if i>=#o or(o[i+1][j]==" "and e(i+1,j)==0)then return 0 end
while k<=W do
b=b or o[i][k]=="X"
if b or(o[i+1][k]==" "and e(i+1,k)==0)then break end
k=k+1 end
while l>0 do
c=c or o[i][l]=="X"
if c or(o[i+1][l]==" "and e(i+1,l)==0)then break end
l=l-1 end
if b and c then for m=l+1,k-1 do o[i][m]="~"end return 1 end
return 0 end
e(1,f)for i=2,#o do for j=1,W do w(o[i][j])end w"\n"end

테스트 사례 (수원 포함) :

---------
    F    
  X~~X   
  XXXX   
--------------------
         F          
   X     X~X        
X  X X  XX~X~~XX~~~X
XXXXXX XXXXXXXXXXXXX
--------------------
   F                
   X     X X        
X~~X~X  XX X  XX   X
XXXXXX XXXXXXXXXXXXX
--------------------------------------------------
                F                                 
              X~~~~~~~~~~~~~X                     
              X~~~~~~~~~~~~~X~X                   
X~~~~~~~~~~~~XXX~~~~~~~X~~~~X~X~~~~~~~~~~~X    X  
X~~~X~~~~~XXXXXXX~~~~~~X~~~~XXX~~~~~XXXXXXX X  X  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXX

bash 에서이 방법을 테스트 할 수는 있지만 그렇게 좋지는 않습니다.

$ echo "    F     
  X  X    
  XXXX   " | lua f.lua

here-docs 를 사용 하여 이것을 쉽게 테스트하십시오! 이것처럼 .
ravron

1

자바 스크립트, 460 바이트

온라인 데모 (콘솔에서 현재 Chrome 및 Firefox에서 테스트)

function e(i,j){var k=j+1,l=j-1,b=0,c=0,I=i+1
if(i>(O-2)||(o[I][j]==" "&&e(I,j)==0))return 0
while(k<W){b=b||(o[i][k]=="X")
if(b||(o[I][k]==" "&&e(I,k)==0))break
k++}while(l>=0){c=c||(o[i][l]=="X")
if(c||(o[I][l]==" "&&e(I,l)==0))break
l--}if(b&&c){for(m=l+1;m<k;m++)o[i][m]="~"
return 1}return 0}function f(d){o=d.split("\n")
F=o[0];s=F.indexOf("F");W=F.length;O=o.length
for(i=0;i<O;i++)o[i]=o[i].split("")
e(0,s);for(i=1;i<O;i++)console.log(o[i].join(""))}

나 자신에게 도전하는 것은 그리 재미 있지는 않지만 여전히 가능합니다. 이제 자바 스크립트에서 Lua 알고리즘과 동일한 알고리즘을 사용합니다.

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