填充任意冰块托盘


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列的最顶部,并左右扩散,左半部分溢出到下方的水槽中,右半部分填充2×1隔室。一旦隔间装满,右边的一半水就无处可流,只能流入水槽,并且各处的水位基本稳定。

关闭水龙头,托盘现在看起来像这样:(与~水一起使用)

   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

水的左半部分将流入水槽,但右半部分最终将填满最右边的三个隔间,因为水在平面上水平行进的距离没有限制:

   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代替空格字符,XF~

以字节为单位的最短代码获胜。


大例子:

输入:

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

2
这需要一个答案:/我会努力的。
TheNumberOne

制作一个可以模拟这种情况的元胞自动机相对容易,但是我想不出一种结束它的方法。
DanTheMan 2015年

还是没人能竞争?如此可爱的挑战。看来我必须击败自己:)
Jakuje 2015年

Answers:


1

perl -p0,204 + 2个字节

理念

  • 如果岛下方F的两边高度相等,则将所有X *Xes 替换为X~*X该孤岛上的。
  • 如果一侧较高,则将所有X *Xes 替换为X~*X下侧的排水口和最接近F的点(高于下侧的顶部)之间的es。

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不支持可变长度的后视,因此在此实现中可能难以识别原始算法。


6

Lua 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可以更轻松地进行测试!这样
拉夫隆

1

Javascript,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相同的算法,现在使用javascript。

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.