Démolition de bâtiments

11

Défi

Écrivez un programme / une fonction complète pour démolir un bâtiment donné au rythme de 1 étage par seconde .

CONTRIBUTION

L'entrée est un bâtiment via STDIN (ou tout autre nom dans votre langue) ou via un ARGUMENT d'une fonction. t = 0 s

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

l'entrée consiste en:

  • | marque le début et la fin d'un étage.
  • {, }marque le sol avec des explosifs.
  • # est une fenêtre qui sert à la décoration.
  • est l'espace, qui est partout à l'intérieur des étages où il #n'y en a pas.
  • T marque le sol (ne peut être démoli).
  • * marque le sol détoné.

Règles d'entrée:

  • le bâtiment commence par le haut avec un |et se termine au sol (sans no ( T) = no ( char used in ground floor)).
  • une fenêtre #est à chaque endroit étrange à l'intérieur de chaque étage.
  • T marque la fin de votre saisie.
  • un seul étage est composé d'explosifs.
  • chaque étage est fait de non impair . de caractères.
  • lorsque vous montez les étages, les étages peuvent être de taille égale à celle de l'étage précédent ou 2 caractères plus gros.
  • L'entrée peut être considérée comme un tableau de charsou strings.

Production :

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  

Règles de sortie:

  • chaque étage se termine par un newlinecaractère.
  • Ground peut / peut ne pas avoir de retour à la ligne.
  • sortir le bâtiment (ou ce qu'il en reste) toutes les 0,5 s.
  • La sortie est comme une animation qui est modifiée toutes les 0,5 s et s'affiche.
    (N'hésitez pas non plus à publier des GIF avec votre réponse)

C'est un Code-Golf donc le code en octets les plus courts gagne!
la dernière date de soumission est dans exactement 5 jours

(Mais vous savez quoi? Gagner n'est pas tout, n'hésitez pas à essayer ce défi dans votre langue préférée, même après qu'un gagnant ait été déclaré:]).

EDIT: J'ai changé la façon dont vous prenez l'entrée (ma mauvaise en fait).

Mukul Kumar
la source
Quelles sont les réponses censées être publiées dans 1 heure à partir de maintenant ?
Dennis
1 heure à compter de mon message. afin que je dispose d'au moins 1 heure pour rectifier tout doute lié à la question.
Mukul Kumar
8
Je ne sais pas si la communauté serait disposée à appliquer ce genre de limitation. Si vous n'êtes pas sûr que vos spécifications soient solides, vous pouvez publier le brouillon du défi dans notre bac à sable pour obtenir des commentaires avant de le publier sur main.
Dennis
@dennis Hmm ... supprimé
Mukul Kumar
Deux questions: (1) Pouvons-nous supposer qu'il n'y a aucun espace de fuite sur aucun étage? (2) Peut-on supposer qu'il n'y a plus de lignes d'entrée après le sol?
H Walters

Réponses:

4

Vim, 41 38 octets

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

Ici, ^est utilisé pour un curseur littéral; ␍ est utilisé pour CTRL-M.

Explication

qw:sl 500m␍qdort une demi-seconde, tout en enregistrant la demi-seconde de sommeil en tant que macro w. /{␍se déplace au sol avec des explosifs. qqcommence l'enregistrement de la macro q, qui s'appellera récursivement.

jkdescend et monte; cela génère une erreur si vous êtes sur la dernière ligne (sol); l'erreur met fin à la macro récursive. ^v$r*remplace tout, du premier caractère non blanc à la fin de la ligne par des *. @wattend une demi-seconde, puis ddsupprime l'étage actuel. :-␍monte d'un étage sans terminer la macro si vous êtes sur la ligne supérieure. @wattend ensuite une demi-seconde @qsupplémentaire et appelle la macro q (initialement vide).

q@q arrête d'enregistrer la macro q, puis l'appelle, déclenchant la récursivité.

Animation

démolition vim

H Walters
la source
J'étais affamé de voir un gif !!
Mukul Kumar
J'ai remarqué que personne d'autre n'a mis de gif, mais vous avez dit "n'hésitez pas à", donc pour mon post c'était un must! Quoi qu'il en soit, ma réponse pourrait être "jouée" davantage si elle était réécrite en V.
H Walters
my answer could be "golfed" further... ça ne suffit pas? : P
Mukul Kumar
4

JavaScript (ES6), 208 198 octets

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
la source
2

Java 7, 589 477 476 octets

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, c'est un gâchis / long, mais ce défi a tellement de choses ennuyeuses pour Java. Impression multi-ligne; Thread.sleep(500)qui nécessite un throws Exception; remplacer une sous-chaîne entre deux délimiteurs par une quantité égale de *; etc.
Tout cela fait que le programme est assez gros. Il peut certainement être joué au golf encore plus, peut-être même divisé par deux avec une approche différente, mais au moins il y a une réponse maintenant. ;)

Non golfé:

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);
}

Code de test:

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){}
  }
}

Essayez-le ici. (Sur ideone, il sort immédiatement et ignore lesleep..)

Kevin Cruijssen
la source
La capture de l'exception peut vous faire économiser quelques octets. Ou peut try{...}finally{return;}- être ?
Neil
@Neil Merci, mais j'ai réussi à fusionner les deux méthodes, alors maintenant j'ai un singlethrows Exception
Kevin Cruijssen
2

Haskell, 245 221 octets

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

Exemple d'utilisation:

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

Comment ça fonctionne:

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

Remarque: il y a aussi threadDelayfrom GHC.Concau lieu de usleepfrom System.Posix.Unistdqui est un peu plus court, mais cela ne fonctionne qu'avec le GHCcompilateur, donc ce ne serait pas une Haskellréponse générique .

nimi
la source
2

C, 314 287 281 271 octets

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 après le changement !=de -quand il est possible et d' éviter les ombles littéraux, ainsi que isspace(Merci à H Walters). Mais le code non golfé reste inchangé.

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 octets après application du coma et suppression {}après deux 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 octets après peu d'optimisation, suppression des parenthèses inutiles, ainsi que changement des variables locales en global (avec initialisation automatique 0) et b[0]by *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);}

Code de test avec non golfé 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
la source
1
Vous pouvez définir l' s,e,textérieur à l'échelle mondiale comme cecis,e,t;
Mukul Kumar
@MukulKumar tu es sûr?
Mark Yisri
Oui, allez-y et essayez-le ..., incluez-le également iavec les autres.
Mukul Kumar
J'essaierai une autre optimisation et utiliserai également vos suggestions
VolAnd
@MukulKumar Merci pour vos conseils ... -23 octets
VolAnd
1

Perl, 153 octets

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}

Cela utilise la commande GNU sleep pour attendre 500 millisecondes.

Version non golfée

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
la source
1

PHP, 286 282 274 234 229 octets

<?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);}

prend l'entrée comme liste de chaînes à partir des arguments de ligne de commande (pas de caractère de nouvelle ligne!)

enregistrer dans un fichier, exécuter avec php <filename> ' |' ' |#|' ' {#}' ' |# #|' '|# # #|' '|# # #|' '|# # #|' 'TTTTTTT'

panne

<?
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
la source