Beliebige Eiswürfelschalen füllen


27

Angenommen, dieses Gitter von Räumen und X's repräsentiert den Querschnitt einiger seltsam geformter leerer Eiswürfelschalen :

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

Spalten ohne X's stellen Löcher oder Lücken in den Schalen dar, die kein Wasser aufnehmen können und in eine Senke mit unbegrenzter Kapazität abfließen. Wasser, das vom linken oder rechten Rand des Gitters abfällt, fließt ebenfalls in diese endlose Spüle.

Wenn wir einen Wasserhahn über den Schalen positionieren und sie mit Wasser füllen lassen, bis der Wasserstand in allen Fächern stabil bleibt, hängen die genauen Fächer, die gefüllt werden, davon ab, wo genau der Wasserstrom über den Schalen positioniert ist. (Nehmen Sie einen dünnen, gleichmäßigen Wasserstrahl ohne Spritzer an.)


Zum Beispiel, wenn sich unser Wasserhahn Füber der linken Spalte befindet

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

Das Wasser fiel bis zum obersten Punkt Xin dieser Säule und breitete sich links und rechts aus, wobei die linke Hälfte in das darunter liegende Waschbecken und die rechte Hälfte das 2 × 1-Fach füllten. Sobald sich das Fach gefüllt hat, kann die rechte Hälfte des Wasserstroms nur noch in die Spüle fließen, und der Wasserstand ist überall im Wesentlichen stabil.

Wenn Sie den Wasserhahn ausschalten, sieht das Fach jetzt so aus: (mit ~ Wasser)

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

Ebenso, wenn wir den Wasserhahn wie folgt positionieren:

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

Es füllt die beiden Fächer ganz links, aber der Rest des Wassers fließt ab:

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

Wenn wir den Wasserhahn so positionieren:

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

Die linke Hälfte des Stroms fließt in die Spüle, aber die rechte Hälfte füllt schließlich die drei am weitesten rechts liegenden Bereiche aus, da die horizontale Reichweite von Wasser auf einer ebenen Fläche unbegrenzt ist:

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

So positioniert jedoch:

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

Das gesamte Wasser fließt ab und es sind keine Fächer gefüllt:

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

Herausforderung

Schreiben Sie ein Programm oder eine Funktion, die ein rechteckiges Raster aus Leerzeichen Xund einem enthält F. Die oberste Zeile enthält immer die Fund ansonsten nur Leerzeichen. DasX s in jeder Spalte (falls vorhanden) erstrecken sich in einer durchgezogenen Linie von der Basis des Gitters aus, dh es gibt keine Höhlen oder Überhänge.

Drucken Sie das Gitter aus oder senden Sie es zurück, nachdem der Wasserhahn wie oben beschrieben Fmit Wasser gefüllt wurde ~. Lassen Sie die obere FReihe aus der Ausgabe.

  • Das Gitter neben der Wasserhahnreihe beträgt mindestens 1 × 1

    F
    X
    

    ist die kleinste Eingabe, die Sie unterstützen müssen.

  • Die Eingabe erfolgt als vollständiges Textrechteck. Führende und nachfolgende Leerzeichen spielen bei der Eingabe und Ausgabe eine Rolle. zB die Eingabe

        F     
      X  X    
      XXXX    
    

    sollte ergeben

      X~~X    
      XXXX    
    

    (beachte die führenden und nachfolgenden Leerzeichen)

  • Es ist in Ordnung, in der Eingabe oder Ausgabe eine einzige nachgestellte Newline zu haben.

  • Sie können alle vier verschiedene verwenden druckbaren ASCII - Zeichen anstelle von Raum, X, F, ~.

Der kürzeste Code in Bytes gewinnt.


Großes Beispiel:

Eingang:

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

Ausgabe:

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

Oh ja, eine großartige Gelegenheit für mich, meinen geliebten zip()<3
cjfaure

2
Das braucht eine Antwort: / Ich werde daran arbeiten.
TheNumberOne

Es ist relativ einfach, einen zellularen Automaten zu bauen, der dies simuliert, aber ich kann mir keine Möglichkeit vorstellen, wie es enden könnte.
DanTheMan

noch niemand zu konkurrieren? So süße Herausforderung. Es sieht so aus, als
müsste

Antworten:


1

Perl -p0, 204 + 2 Bytes

IDEE

  • Wenn beide Seiten der Insel unter F gleich hoch sind, ersetzen Sie alle X *XdurchX~*X es auf dieser Insel.
  • Wenn eine Seite höher ist, ersetzen Sie alle X *Xes durch X~*Xes zwischen dem Abfluss auf der unteren Seite und dem Punkt, der F am nächsten liegt und höher ist als die Oberseite der unteren Seite.

Das Land direkt unter F zählt hier zu beiden Seiten.

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

ANMERKUNGEN

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
'

Es ist möglicherweise schwierig, den ursprünglichen Algorithmus in dieser Implementierung zu erkennen, da Perl keine Lookbehinds mit variabler Länge unterstützt.


6

Lua 5.2, 581 Bytes

Wieder langsam mit so ineffektiver Sprache zum Golfen und mit ineffektivem Algorithmus beginnen. Aber ich werde mich verbessern :)

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

Testfälle (mit Wasserquelle):

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

Von Bash aus ist es möglich, diesen Weg zu testen, aber es sieht nicht so schön aus:

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

Verwenden Sie Here-Docs , um dies einfacher zu testen! Wie das .
Ravron

1

Javascript, 460 Bytes

Online-Demo (in der Konsole, getestet in aktuellem Chrome und 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(""))}

Mich selbst herauszufordern ist nicht so lustig, aber dennoch möglich. Gleicher Algorithmus wie der von Lua, jetzt in Javascript.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.