Снос зданий

11

Вызов

Напишите полную программу / функцию, чтобы Разрушить данное здание со скоростью 1 этаж в секунду .

ВХОД

Ввод - это построение через STDIN (или как там называется на вашем языке) или через аргумент функции. t = 0 с

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

вход состоит из:

  • | отмечает начало и конец пола.
  • {, }отмечает пол взрывчаткой.
  • # это окно для украшения.
  • это пространство, которое везде внутри этажей, где #его нет.
  • T отмечает землю (не может быть снесен).
  • * отмечает взорванный пол.

Правила ввода:

  • строительство начинается сверху одним |и заканчивается на земле (без ( T) = нет ( char used in ground floor)).
  • окно #в каждом странном месте на каждом этаже.
  • T отмечает конец вашего ввода.
  • только один этаж состоит из взрывчатых веществ.
  • каждый этаж сделан из нечетного нет. символов
  • когда вы поднимаетесь вниз по этажам, этажи могут быть одинакового размера с этажами предыдущего этажа или могут быть на 2 знака больше.
  • Ввод может быть принят как массив charsили strings.

Выход :

t = 0,5 с

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

t = 1 с

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

t = 1,5 с

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

t = 2 с

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

t = 2,5 с

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

t = 3 с

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

t = 3,5 с

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

t = 4 с

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

t = 4,5 с

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

t = 6,5 с

*******
TTTTTTT  

t = 7 с

TTTTTTT  

Правила вывода:

  • каждый этаж заканчивается одним newlineперсонажем.
  • земля может / не может иметь завершающий символ новой строки.
  • выводить здание (или то, что от него осталось) каждые 0,5 с.
  • Вывод похож на анимацию, которая изменяется каждые 0,5 с и отображается.
    (Также не стесняйтесь размещать GIF с вашим ответом)

Это Code-Golf, поэтому выигрывает код в кратчайших байтах!
последняя дата подачи ровно через 5 дней

(Но вы знаете, что? Победа - это еще не все, не стесняйтесь пробовать это испытание на своем любимом языке, даже после того, как был объявлен победитель:]).

РЕДАКТИРОВАТЬ: Я изменил способ, которым вы принимаете вход (мой плохой на самом деле).

Мукул Кумар
источник
Какие ответы должны быть опубликованы через 1 час ?
Деннис
1 час с момента моего поста. так что у меня есть хотя бы 1 час, чтобы исправить любые сомнения, связанные с вопросом.
Мукул Кумар
8
Я не уверен, что сообщество хотело бы применять такие ограничения. Если вы не уверены в правильности своей спецификации, вы можете опубликовать черновой вариант в нашей песочнице, чтобы получить отзыв, прежде чем публиковать его на главной.
Деннис
@dennis Хмм ... удалено
Мукул Кумар
Два вопроса: (1) Можем ли мы предположить, что нет ни одного пробела на любом этаже? (2) Можем ли мы предположить, что больше нет линий ввода после земли?
H Уолтерс

Ответы:

4

Vim, 41 38 байт

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

Здесь ^используется для буквальной каретки; For используется для CTRL-M.

объяснение

qw:sl 500m␍qспит полсекунды, а полсекунды записывает как макрос w. /{␍движется к полу со взрывчаткой. qqначинает запись макроса q, который будет рекурсивно вызывать себя.

jkдвижется вниз и вверх; это приводит к ошибке, если вы находитесь на последней линии (земля); ошибка завершает рекурсивный макрос. ^v$r*заменяет все от первого непробельного символа до конца строки с *. @wждет полсекунды, затем ddудаляет текущий этаж. :-␍поднимается на пол, не заканчивая макрос, если вы находитесь на верхней строке. @wзатем ждет еще полсекунды и @qвызывает макрос q (изначально пустой).

q@q останавливает запись макроса q, затем вызывает его, вызывая рекурсию.

Анимация

Vim снос

H Уолтерс
источник
Я голодал, чтобы увидеть GIF!
Мукул Кумар
Я заметил, что никто не вставил гифку, но вы сказали «не стесняйтесь», поэтому для моего поста это было необходимо! Во всяком случае, мой ответ мог бы быть «заигран» дальше, если бы он был переписан в V.
H Walters
my answer could be "golfed" further... не , что достаточно? : P
Мукул Кумар
4

JavaScript (ES6), 208 198 байт

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

Нил
источник
2

Java 7, 589 477 476 байт

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

Хорошо, это беспорядок / длинный, но этот вызов имеет так много раздражающих вещей для Java .. Печать многострочных; Thread.sleep(500)который требует throws Exception; замена подстроки между двумя разделителями равным количеством *; и т. д.
Все это приводит к тому, что программа становится довольно большой. Определенно ее можно сыграть в гольф еще, возможно, даже вдвое с другим подходом, но, по крайней мере, сейчас есть ответ. ;)

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

Тестовый код:

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

Попробуй это здесь. (На ideone выводит сразу и игнорируетsleep..)

Кевин Круйссен
источник
Перехват исключения может сэкономить вам несколько байтов. Или может быть try{...}finally{return;}?
Нил
@Neil Спасибо, но мне удалось объединить оба метода, так что теперь у меня есть синглthrows Exception
Кевин Круйссен
2

Haskell, 245 221 байт

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

Пример использования:

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

Как это работает:

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

Примечание: есть также threadDelayfrom, GHC.Concа не usleepfrom, System.Posix.Unistdкоторый немного короче, но он работает только с GHCкомпилятором, поэтому он не будет общим Haskellответом.

Ними
источник
2

C, 314 287 281 271 байт

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 после изменения , !=чтобы -и избежать полукокса литералов , когда это возможно, а также isspace(многие благодаря H Walters). Но негольфированный код остается неизменным.

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 байт после применения комы и удаления {}после двух 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 байт после небольшой оптимизации, удаления ненужных скобок, а также изменения локальных переменных на глобальные (с автоматической инициализацией 0) и 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);}

Тестовый код с 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
источник
1
Вы можете определить s,e,tснаружи глобально, как этоs,e,t;
Mukul Kumar
@MukulKumar ты уверен?
Марк Йисри
Да, конечно, попробуйте и попробуйте ..., также включите iс другими.
Мукул Кумар
Я попробую другую оптимизацию и буду использовать ваши предложения
VolAnd
@MukulKumar Спасибо за совет ... -23 байта
VolA и
1

Perl, 153 байта

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}

Это использует команду сна GNU для ожидания 500 миллисекунд.

Неуправляемая версия

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
 }
Адам
источник
1

PHP, 286 282 274 234 229 байт

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

принимает входные данные в виде списка строк из аргументов командной строки (без символа новой строки!)

сохранить в файл, запустить с php <filename> ' |' ' |#|' ' {#}' ' |# #|' '|# # #|' '|# # #|' '|# # #|' 'TTTTTTT'

сломать

<?
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
источник