Gebäudeabbruch

11

Herausforderung

Schreiben Sie ein vollständiges Programm / eine vollständige Funktion, um ein bestimmtes Gebäude mit einer Geschwindigkeit von 1 Stockwerk pro Sekunde abzureißen .

EINGANG

Eingabe ist ein Gebäude durch STDIN (oder wie auch immer in Ihrer Sprache genannt) oder durch ein ARGUMENT einer Funktion. t = 0 s

   |
  |#|
  {#}
 |# #|
|# # #|
|# # #|
|# # #|
TTTTTTT  

Eingabe besteht aus:

  • | markiert Anfang und Ende eines Stockwerks.
  • {, }Markiert den Boden mit Sprengstoff.
  • # ist ein Fenster, das zur Dekoration dient.
  • ist Raum, der überall in den Böden ist, wo #nicht da ist.
  • T markiert den Boden (kann nicht abgerissen werden).
  • * markiert den detonierten Boden.

Eingaberegeln:

  • Das Gebäude beginnt von oben mit eins |und endet auf dem Boden (mit no ( T) = no ( char used in ground floor)).
  • Ein Fenster #befindet sich an jeder ungeraden Stelle in jeder Etage.
  • T markiert das Ende Ihrer Eingabe.
  • Nur eine Etage besteht aus Sprengstoff.
  • Jede Etage besteht aus ungeraden Nr. von Zeichen.
  • Wenn Sie die Etagen hinuntersteigen, können die Etagen entweder die gleiche Größe wie die vorherige Etage haben oder 2 Zeichen größer sein.
  • Die Eingabe kann als Array von charsoder erfolgen strings.

Ausgabe :

t = 0,5 s

   |
  |#|
  ***
 |# #|
|# # #|
|# # #|
|# # #|
TTTTTTT  

t = 1 s

   |
  |#|
 |# #|
|# # #|
|# # #|
|# # #|
TTTTTTT  

t = 1,5 s

   |
  ***
 |# #|
|# # #|
|# # #|
|# # #|
TTTTTTT  

t = 2 s

   |
 |# #|
|# # #|
|# # #|
|# # #|
TTTTTTT  

t = 2,5 s

   *
 |# #|
|# # #|
|# # #|
|# # #|
TTTTTTT  

t = 3 s

 |# #|
|# # #|
|# # #|
|# # #|
TTTTTTT  

t = 3,5 s

 *****
|# # #|
|# # #|
|# # #|
TTTTTTT  

t = 4 s

|# # #|
|# # #|
|# # #|
TTTTTTT  

t = 4,5 s

*******
|# # #|
|# # #|
TTTTTTT  

t = 6,5 s

*******
TTTTTTT  

t = 7 s

TTTTTTT  

Ausgaberegeln:

  • Jede Etage endet mit einem newlineZeichen.
  • Boden kann / kann keine nachlaufende Newline haben.
  • Geben Sie das Gebäude (oder was davon übrig ist) alle 0,5 s aus.
  • Die Ausgabe ist wie eine Animation, die alle 0,5 s geändert und angezeigt wird.
    (Sie können auch gerne GIFs mit Ihrer Antwort posten.)

Dies ist ein Code-Golf, also gewinnt der Code in kürzesten Bytes!
Das letzte Einreichungsdatum ist genau 5 Tage ab jetzt

(Aber weißt du was? Gewinnen ist nicht alles. Probieren Sie diese Herausforderung auch in Ihrer Lieblingssprache aus, auch nachdem ein Gewinner bekannt gegeben wurde:]).

EDIT: Ich habe die Art und Weise geändert, wie Sie Eingaben machen (meine schlechte eigentlich).

Mukul Kumar
quelle
Welche Antworten sollen in etwa 1 Stunde veröffentlicht werden ?
Dennis
1 Stunde ab dem Zeitpunkt meines Beitrags. so dass ich mindestens 1 Stunde Zeit habe, um alle Fragen im Zusammenhang mit Fragen zu beseitigen.
Mukul Kumar
8
Ich bin mir nicht sicher, ob die Community bereit wäre, diese Art von Einschränkung durchzusetzen. Wenn Sie nicht sicher sind, ob Ihre Spezifikation solide ist, können Sie den Herausforderungsentwurf in unserer Sandbox veröffentlichen , um Feedback zu erhalten, bevor Sie ihn auf main veröffentlichen.
Dennis
@dennis Hmm ... entfernt
Mukul Kumar
Zwei Fragen: (1) Dürfen wir annehmen, dass es auf keiner Etage nachgestellte Leerzeichen gibt? (2) Dürfen wir annehmen, dass nach dem Boden keine Eingangsleitungen mehr vorhanden sind?
H Walters

Antworten:

4

Vim, 41 38 Bytes

qw:sl 500m␍q/{␍qqjk^v$r*@wdd:-␍@w@qq@q

Hier ^wird für ein wörtliches Caret verwendet; ␍ wird für STRG-M verwendet.

Erläuterung

qw:sl 500m␍qschläft eine halbe Sekunde, während die halbe Sekunde Schlaf als Makro w aufgezeichnet wird. /{␍bewegt sich mit Sprengstoff zu Boden. qqbeginnt mit der Aufzeichnung des Makros q, das sich rekursiv selbst aufruft.

jkbewegt sich runter und rauf; Dies erzeugt einen Fehler, wenn Sie sich in der letzten Zeile (Boden) befinden. Der Fehler beendet das rekursive Makro. ^v$r*Ersetzt alles vom ersten Nicht-Leerzeichen bis zum Zeilenende durch *. @wwartet eine halbe Sekunde und ddlöscht dann die aktuelle Etage. :-␍bewegt sich eine Etage nach oben, ohne das Makro zu beenden, wenn Sie sich in der obersten Zeile befinden. @wwartet dann eine weitere halbe Sekunde und @qruft das q-Makro auf (zunächst leer).

q@q stoppt die Aufzeichnung des Makros q, ruft es dann auf und löst die Rekursion aus.

Animation

Vim Abriss

H Walters
quelle
Ich war hungrig, um ein GIF zu sehen !!
Mukul Kumar
Ich habe bemerkt, dass niemand anderes ein GIF eingegeben hat, aber Sie sagten "Fühlen Sie sich frei zu", also war es für meinen Beitrag ein Muss! Wie auch immer, meine Antwort könnte weiter "golfen", wenn sie in V.
H Walters
my answer could be "golfed" further... ist nicht , dass genug? : P
Mukul Kumar
4

JavaScript (ES6), 208 198 Bytes

f=
(t,s=f=>setTimeout(f,500),v=t.value.split(/(\S.*\n)/),i=v.findIndex(s=>/}/.test(s)),c=_=>t.value=v.join``,d=_=>c(v.splice(--i,2),v[3]&&s(e,i?--i:++i)),e=_=>c(v[i]=v[i].replace(/./g,'*'),s(d)))=>s(e)
<textarea id=t rows=9>
   |
  |#|
  {#}
 |# #|
|# # #|
|# # #|
|# # #|
TTTTTTT
</textarea><input type=button value=Go! onclick=f(t)>

Neil
quelle
2

Java 7, 589 477 476 Bytes

import java.util.*;void x(List<String>b,int x)throws Exception{Thread.sleep(500);int i=0,l=b.size(),z=x;String w;for(;i<l;i++){System.out.println(w=b.get(i));if(w.contains("{"))x=i;}System.out.println();w=b.get(x);i=w.contains("*")?1:0;if(i>0)b.remove(x);else b.set(x,z<0?r(w,'{','}'):r(w,'|','|'));if(l>1)x(b,i>0&x>0?x-1:x);}String r(String s,char y,char z){int a,b;return s.substring(0,a=s.indexOf(y))+s.substring(a,b=s.lastIndexOf(z)+1).replaceAll(".","*")+s.substring(b);}

Ok, es ist ein Chaos / lang, aber diese Herausforderung hat so viele nervige Dinge für Java. Mehrzeiliges Drucken; Thread.sleep(500)was erfordert ein throws Exception; Ersetzen eines Teilstrings zwischen zwei Begrenzern durch eine gleiche Menge von *; usw.
All dies führt dazu, dass das Programm ziemlich groß ist. Es kann definitiv noch mehr Golf gespielt werden, vielleicht sogar mit einem anderen Ansatz halbiert werden, aber zumindest gibt es jetzt eine Antwort. ;)

Ungolfed:

void x(List<String>b, int x) throws Exception{
  Thread.sleep(500);
  int i = 0,
      l = b.size(),
      z = x;
  String w;
  for(;i<l; i++){
    System.out.println(w=b.get(i));
    if(w.contains("{")){
      x = i;
    }
  }
  System.out.println();
  w = b.get(x);
  i = s.contains("*")
       ? 1
       : 0;
  if(i>0){
    b.remove(x);
  }
  else{
    b.set(x, z < 0
              ? r(s, '{', '}')
              : r(s, '|', '|'));
  }
  if(l>1){
    x(b, i > 0 & x > 0
          ? x-1
          : x);
  }
}

String r(String s, chary, char z){
    int a, b;
    return s.substring(0, a=s.indexOf(y)) + s.substring(a, b=s.lastIndexOf(z) + 1).replaceAll(".", "*") + s.substring(b);
}

Testcode:

import java.util.*;

class M{
  void x(List<String>b,int x)throws Exception{Thread.sleep(500);int i=0,l=b.size(),z=x;String w;for(;i<l;i++){System.out.println(w=b.get(i));if(w.contains("{"))x=i;}System.out.println();w=b.get(x);i=w.contains("*")?1:0;if(i>0)b.remove(x);else b.set(x,z<0?r(w,'{','}'):r(w,'|','|'));if(l>1)x(b,i>0&x>0?x-1:x);}String r(String s,char y,char z){int a,b;return s.substring(0,a=s.indexOf(y))+s.substring(a,b=s.lastIndexOf(z)+1).replaceAll(".","*")+s.substring(b);}

  public static void main(String[] a){
    try{
        List<String> l = new ArrayList(){{
            add("   |   ");
            add("  |#|  ");
            add("  |#|  ");
            add(" {# #} ");
            add("|# # #|");
            add("|# # #|");
            add("|# # #|");
            add("TTTTTTT");
        }};
        new M().c(l, -1);
    }
    catch(Exception e){}
  }
}

Probieren Sie es hier aus. (Auf ideone wird es sofort ausgegeben und ignoriert dassleep..)

Kevin Cruijssen
quelle
Wenn Sie die Ausnahme abfangen, sparen Sie möglicherweise einige Bytes. Oder vielleicht try{...}finally{return;}?
Neil
@ Neil Danke, aber ich habe es geschafft, beide Methoden zusammenzuführen, also habe ich jetzt eine Singlethrows Exception
Kevin Cruijssen
2

Haskell, 245 221 Bytes

import System.Posix.Unistd
r=reverse
c#l|(i,j)<-span(<'!')l=i++(c<$j)
f[b]=[[b]]
f s|(h@(a:b),d:c)<-break(elem '{')s=(h++'*'#d:c):(h++c):f(init h++'{'#last h:c)|1<2=r<$>(f$r s)
mapM((usleep 500000>>).mapM putStrLn).init.f

Anwendungsbeispiel:

mapM((usleep 500000>>).mapM putStrLn).init.f $ ["  |"," {#}"," |#|","|# #|","|# #|","TTTTT"]

Wie es funktioniert:

c#l|(i,j)<-span(<'!')l=i++(c<$j)    -- helper function that takes a char c and
                                    -- a string l and keeps the leading spaces
                                    -- of l and replaces the rest with c

                                    -- f takes a building (list of strings) and
                                    -- makes the sequence of collapsing buildings
                                    -- as a list of list of strings
f[b]=[[b]]                          -- base case. Stop when there's only a single
                                    -- floor left
f s                                 -- if the building has at least two floors
   |(h@(a:b),d:c)<-break(elem '{')s --   if there is at least one floor above the
                                    --   explosion
        =(h++'*'#d:c) :             --     return the current building with the
                                    --     floor to explode replaced by *
        (h++c) :                    --     followed by the current building with
                                    --     the exploded floor removed 
        f(init h++'{'#last h:c)     --     followed by a recursive call
                                    --     with the next to explode floor marked
                                    --     with '{'
   |1<2=r<$>(f$r s)                 --   if all top floors have exploded, reverse
                                    --   the left over floors, let them explode
                                    --   and reverse the floors of each building
                                    --   again.

                      f             -- let the building collapse
                 init               -- f comes with an additional building with
                                    -- a single floor of * only -> drop it
mapM(     )                         -- for every building
     (usleep 500000>>)              --   delay 0.5 sec
             mapM putStrLn          --   and print the floors

Hinweis: Es gibt auch threadDelayvon GHC.Concstatt usleepvon System.Posix.Unistdwas etwas kürzer ist, aber es funktioniert nur mit dem GHCCompiler, so dass es keine generische HaskellAntwort wäre.

Nimi
quelle
2

C, 314 287 281 271 Bytes

s,e,t,i;f(char**b){char*p;do{system("CLS");i=0;do{while(!(p=b[i]))i++;if(!*b&&e==1)e=i;while(*p<33)putchar(*p++);if(!t)e=*p=='{'?i:e,s+=2;do{putchar(e==i&&t%2&&*p>16?'*':*p);}while(*p&&*p++>16);}while(*b[i++]-84);if(t++%2)b[e]=0,*b&&e>0?e--:e++;Sleep(500);}while(t<s-1);}

-10 nach dem Wechsel !=zu -und Vermeiden von Zeichenliteralen, wenn es möglich ist, sowie isspace(vielen Dank an H Walters). Der ungolfed Code bleibt jedoch unverändert.

s,e,t,i;f(char**b){char*p;do{system("CLS");i=0;do{while(!(p=b[i]))i++;if(!*b&&e==1)e=i;while(isspace(*p))putchar(*p++);if(!t)e=*p=='{'?i:e,s+=2;do{putchar(e==i&&t%2&&*p>0xF?'*':*p);}while(*p&&*p++>0xF);}while(*b[i++]!='T');if(t++%2)b[e]=0,*b&&e>0?e--:e++;Sleep(500);}while(t<s-1);}

-6 Bytes nach dem Anwenden des Komas und dem Löschen {}nach zwei if.

s,e,t,i;f(char**b){char*p;do{system("CLS");i=0;do{while(!(p=b[i]))i++;if(!*b&&e==1)e=i;while(isspace(*p))putchar(*p++);if(!t){s+=2;e=*p=='{'?i:e;}do{putchar(e==i&&t%2&&*p>0xF?'*':*p);}while(*p&&*p++>0xF);}while(*b[i++]!='T');if(t++%2){b[e]=0;e=*b&&e>0?e-1:e+1;}Sleep(500);}while(t<s-1);}

-26 Bytes nach geringer Optimierung, Entfernen unnötiger Klammern sowie Ändern lokaler Variablen in globale (mit automatischer 0-Initialisierung) und b[0]durch *b.

f(char**b){int s=0,e=0,t=0;char*p;do{system("CLS");int i=0;do{if(!t){s+=2;if(strchr(b[i],'}'))e=i;printf(b[i]);}else{while(!(p=b[i]))i++;if(!b[0]&&e==1)e=i;do{putchar((e==i&&t%2&&!isspace(*p))?'*':*p);}while(*p&&*p++!='\n');}}while(b[i++][0]!='T');if(t%2){b[e]=0;e=(b[0]&&e)?e-1:e+1;}t++;Sleep(500);}while(--s>1);}

Testcode mit ungolfed f:

#include <stdio.h>
#include <windows.h> // to use Sleep and system

s, e, t, i;
f(char**b)
{
    char*p;
    do{
        system("CLS");
        i = 0;
        do
        {
            while (!(p=b[i]))i++; // skip demolished floors
            if (!*b && e==1) e = i;
            while (isspace(*p)) putchar(*p++); // print spaces 
            if (!t){ s += 2; e = *p == '{' ? i : e; } // find a bomb and count steps at the first iteration
            do{
                putchar(e == i && t%2 &&*p>0xF ? '*' : *p); // print floor or * for next floor at odd step
            } while (*p && *p++ >0xF); // >0xF is instead of !='\n'
        } while (*b[i++] != 'T'); // until the ground
        if (t++ % 2)
        {
            b[e] = 0; // delete the demolished floor
            e = *b&&e>0 ? e-1 : e+1; // and determine next floor to be demolished
        }
        Sleep(500);
    } while (t<s-1);
}

int main(void)
{
    char * arr[] = { "   |\n",
                     "  |#|\n",
                     "  {#}\n",
                     " |# #|\n",
                     "|# # #|\n",
                     "|# # #|\n",
                     "|# # #|\n",
                     "TTTTTTT" };
    f(arr);
}
VolAnd
quelle
1
Sie können s,e,taußerhalb global wie s,e,t;
folgt
@ MukulKumar bist du sicher?
Mark Yisri
Ja sicher, probieren Sie es aus ... auch imit anderen.
Mukul Kumar
Ich werde eine andere Optimierung versuchen und auch Ihre Vorschläge verwenden
VolAnd
@ MukulKumar Danke für den Rat ... -23 Bytes
VolAnd
1

Perl, 153 Bytes

for(@a=<>;$a[$i]!~/{/;$i++){}for(;$a[0]!~/^T/;`sleep .5`){if($P=!$P){$a[$i]=~s/(\S.*\S|\S)/"*" x length($1)/e}else{splice(@a,$i,1);if($i){$i--}}print@a}

Dies verwendet den GNU-Schlafbefehl, um 500 Millisekunden zu warten.

Ungolfed Version

for(@a=<>;$a[$i]!~/{/;$i++){}
for(;$a[0]!~/^T/;`sleep .5`){
    if($P=!$P){
       $a[$i]=~s/(\S.*\S|\S)/"*" x length($1)/e
    } else { 
       splice(@a,$i,1);
       if($i){$i--}
    }
    print @a
 }
Adam
quelle
1

PHP, 286 282 274 234 229 Bytes

<?for($a=$argv,array_shift($a);!strstr($a[+$i++],"{"););while($a[0][0]!=T){$x=&$a[$i-=$i>0];$x=str_pad(substr($x,0,strspn($x," ")),strlen($x),"*");eval($p='echo join("\n",$a),"\n\n";usleep(5e5);');array_splice($a,$i,1);eval($p);}

Nimmt die Eingabe als Liste von Zeichenfolgen aus Befehlszeilenargumenten (kein Zeilenumbruchzeichen!)

In Datei speichern, ausführen mit php <filename> ' |' ' |#|' ' {#}' ' |# #|' '|# # #|' '|# # #|' '|# # #|' 'TTTTTTT'

Nervenzusammenbruch

<?
for($a=$argv,array_shift($a);   // import input
    !strstr($a[+$i++],"{"););   // find explosives
while($a[0][0]!=T)              // loop while ground not reached:
{
    $x=&$a[$i-=$i>0];               // move up if possible, reference floor
    $x=str_pad(
        substr($x,0,strspn($x," ")  // keep leading spaces
    ),strlen($x),"*");              // replace rest with asterisks
                                    // print and wait
    eval($p='echo join("\n",$a),"\n\n";usleep(5e5);');
    array_splice($a,$i,1);          // remove current floor
    eval($p);                       // print and wait
}
Titus
quelle