Làm đầy khay đá khối tùy ý


27

Giả sử lưới không gian này và X's đại diện cho mặt cắt ngang của một số khay đá rỗng có hình dạng kỳ lạ :

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

Các cột không có Xlỗ đại diện cho các lỗ hoặc khoảng trống trong các khay không thể chứa nước, chảy vào một bể chứa dung lượng vô hạn. Nước rơi ra từ rìa ngoài cùng bên phải hoặc bên phải của lưới cũng đi vào bồn rửa vô tận này.

Nếu chúng ta đặt một vòi bên trên các khay và để chúng đổ đầy nước cho đến khi mực nước trong tất cả các ngăn vẫn ổn định, các ngăn chính xác được đổ đầy sẽ phụ thuộc vào chính xác vị trí của dòng nước bên trên các khay. (Giả sử một dòng nước mỏng, đều đặn mà không bị bắn tung tóe.)


Ví dụ: nếu vòi của chúng tôi Fở trên cột lưới bên trái

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

nước sẽ rơi xuống đỉnh cao nhất Xtrong cột đó và lan sang trái và phải, nửa bên trái tràn vào bồn rửa bên dưới và nửa bên phải lấp đầy khoang 2 × 1. Khi khoang chứa đầy, một nửa dòng nước bên phải không có nơi nào chảy nhưng vào bồn và mực nước ở mọi nơi về cơ bản là ổn định.

Tắt vòi, khay bây giờ trông như thế này: (với ~nước)

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

Tương tự, nếu chúng ta định vị vòi như thế này:

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

Nó sẽ lấp đầy hai ngăn ngoài cùng bên trái nhưng phần còn lại của nước sẽ chảy ra:

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

Nếu chúng ta định vị vòi như thế này:

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

Nửa bên trái của dòng chảy sẽ chảy vào bồn nhưng nửa bên phải cuối cùng sẽ lấp đầy ba khoang ngoài cùng bên phải vì không có giới hạn về việc nước có thể di chuyển theo chiều ngang trên một mặt phẳng:

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

Định vị như thế này, tuy nhiên:

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

Tất cả các nước thoát ra và không có ngăn chứa đầy:

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

Thử thách

Viết chương trình hoặc hàm có trong một lưới hình chữ nhật gồm các khoảng trắng X, và một F. Hàng trên cùng sẽ luôn chứa Fvà nếu không chỉ chứa khoảng trắng. Các Xcột trong mỗi cột (nếu có) sẽ kéo dài thành một đường liền mạch từ gốc của lưới, tức là sẽ không có hang hoặc phần nhô ra.

In hoặc trả lại lưới sau khi vòi Fđã đổ đầy nước có thể ~như mô tả ở trên. Để hàng trên cùng Fra khỏi đầu ra.

  • Lưới ngoài hàng vòi sẽ tối thiểu 1 × 1

    F
    X
    

    là đầu vào nhỏ nhất bạn cần hỗ trợ.

  • Các đầu vào sẽ đi vào như một hình chữ nhật văn bản hoàn chỉnh. Không gian hàng đầu và dấu làm quan trọng trong đầu vào và đầu ra. ví dụ đầu vào

        F     
      X  X    
      XXXX    
    

    nên dẫn đến

      X~~X    
      XXXX    
    

    (lưu ý các không gian hàng đầu và dấu)

  • Có một dòng mới duy nhất trong đầu vào hoặc đầu ra là tốt.

  • Bạn có thể sử dụng bất kỳ bốn biệt ASCII in ký tự ở vị trí của không gian, X, F, ~.

Mã ngắn nhất tính bằng byte thắng.


Ví dụ lớn:

Đầu vào:

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

Đầu ra:

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

Ồ vâng, một cơ hội tuyệt vời để tôi sử dụng zip()<3
cjfaure

2
Điều này cần một câu trả lời: / Tôi sẽ làm việc với nó.
TheNumberOne

Thật dễ dàng để tạo ra một thiết bị tự động di động mô phỏng điều này, nhưng tôi không thể nghĩ ra cách nào để nó kết thúc.
DanTheMan

vẫn không có ai để cạnh tranh? Thử thách thật dễ thương. Có vẻ như tôi sẽ phải tự đánh mình :)
Jakuje

trông giống như một bản sao của điều này: codegolf.stackexchange.com/questions/2563/fill-in-the-lakes
12Me21

Câu trả lời:


1

perl -p0, 204 + 2 byte

Ý KIẾN

  • Nếu cả hai cạnh của hòn đảo dưới F có chiều cao bằng nhau, hãy thay thế tất cả X *Xes bằng X~*Xes trên đảo đó.
  • Nếu một bên cao hơn, thay thế tất cả X *Xes bằng X~*Xes giữa cống ở phía dưới và điểm gần nhất với F cao hơn đỉnh thấp hơn.

Vùng đất ngay dưới F được tính là một phần của cả hai bên ở đây.

GOLF

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

GHI CHÚ

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
'

Có thể khó nhận ra thuật toán gốc trong triển khai này vì Perl không hỗ trợ các giao diện có độ dài thay đổi.


6

Lua 5.2, 581 byte

Một lần nữa, bắt đầu chậm với ngôn ngữ không hiệu quả để chơi golf và với thuật toán không hiệu quả. Nhưng tôi sẽ cải thiện :)

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

Các trường hợp thử nghiệm (có nguồn nước):

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

từ bash có thể kiểm tra theo cách này, nhưng nó không đẹp lắm:

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

Sử dụng tài liệu ở đây để kiểm tra điều này dễ dàng hơn! Như thế này .
ravron

1

Javascript, 460 byte

Bản demo trực tuyến (trong bảng điều khiển, đã được thử nghiệm trong Chrome và Firefox hiện tại).

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

Thử thách bản thân không phải là quá vui, nhưng vẫn có thể. Thuật toán tương tự như thuật ngữ Lua, hiện có trong javascript.

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.