Свернуть ascii-art


12

Вызов

Учитывая прямоугольную сетку печатаемых символов ascii в виде строки или через стандартный ввод, напишите функцию или программу, которая сворачивает непробельные символы в стопку внизу.

Правила:

  • Вывод имеет те же размеры и символы, что и ввод.
  • Не-символ пробела при (row a,column b)не может иметь пробел ' 'на (a-1, b), (a-1,b-1)или (a-1,b+1), где строки пронумерованы по сравнению с самой нижней. Это приводит к тому, что все вертикальные сваи должны разрушаться вбок.
  • Символ без пробела может перемещаться в большинстве (initial height - final height)мест слева или справа (см. Рис. 1).
  • Вы можете предположить, что на изображении достаточно места, чтобы свернуть его без выпадения символов с экрана.

Рисунок 1: возможные конечные местоположения для символов @#$показаны x,y,zсоответственно.

..............
...@..........
..xxx.........
.xxxxx...#....
xxxxxxx.yyy.$.

Порядок, в котором персонажи разрушаются, можно выбирать свободно. Конечные пробелы не в порядке, но конечные переводы строки.

Это , поэтому выигрывает самый короткий ответ в байтах!

пример

                 (__)
                 (oo)
           /------\/
          / |    ||
         *  /\---/\
            ~~   ~~
..."Have you mooed today?"...

Один из возможных выходов:

 
 
 
                --(_
           /----|/|(o_)
          /|/~\---~\\/o)
..."Have*you~mooed~today?"...

Просто чтобы уточнить, способ падения символов может быть жестко закодирован, а не генерироваться случайным образом каждый раз?
ETHproductions

18
Что эта корова когда-либо делала с тобой ?? :(
FlipTack

@ETHproductions это правильно. Мой пример делает это снизу вверх, слева направо, но случайный порядок или что-то еще в порядке, если соблюдать правила.
Angs

@ Flp.Tkc Это всего лишь модель.
Angs

1
@DestructibleWatermelon, если персонаж выпадает из экрана, это его вина, а не ваша.
Ангс

Ответы:


4

JavaScript (ES6), 100 90 88 байт

f=s=>s==(l=s.search`
`,s=s.replace(eval(`/(\\S)([^]{${l-1},${l+1}}) /`),` $2$1`))?s:f(s)
s=`                 (__)        
                 (oo)        
           /------\\/         
          / |    ||          
         *  /\\---/\\          
            ~~   ~~          
..."Have you mooed today?"...`
console.log(s)
console.log(f(s))

Требует, чтобы строка имела как минимум две строки и все строки дополнялись до одинаковой длины. Выход для примера изображения:

              ( --           
            /|---/|-(o__     
          */~~\---~\|\/o))   
..."Have you/mooed~today?"...

Обратите внимание, что когда он пытается переместить элементы вправо, если это возможно, *он не попадает между Haveи you.

Изменить: 10% сэкономлено благодаря @ETHproductions. Сохранено еще 2 байта благодаря @DanielIndie.

Сетчатка 0.8.2 , 50 байт

+`(?<=(.)*)(\S)(.*¶(?<-1>)?(?>(?<-1>.)*).?) 
 $3$2

Попробуйте онлайн! Немного другой подход к моему ответу JavaScript, в котором используется балансирующая группа для соответствия пробелу под непробельным символом; (?<-1>)?позволяет пространство , чтобы быть один столбец влево в то время как .?позволяет пространство , чтобы быть один столбец вправо.

Сетчатка , 40 байт

~0L$`.(.*)¶
+s`(\S)(.{$.1,$.&}) ¶ $$2$$1

Попробуйте онлайн! Порт моего JavaScript ответа. 0L$Атомный этап принимает входной сигнал и заменяет две длину на вторую линию , в результате чего команды , которая фактически выполняет замены, который затем оценивали на исходном вход со стороны ~стадии соединения.


Это отличный алгоритм! Вы можете заменить \nего буквальным символом новой строки, чтобы сократить до двух цифр ;-)
ETHproductions

Кроме того, я думаю, что вы можете l=s.search`\n` сэкономить несколько байтов.
ETHproductions


@DanielIndie The f=требуется для рекурсии, но это все еще экономит мне 2 байта, спасибо!
Нил

Вы правы, извините: P
DanielIndie

3

Python 2, 298 байт

a=input()
L=len(a);s=' '
a=[list(s*L+l.ljust(L+max(map(len,a))))for l in a]
t=1
while t:
 t=0
 for y in range(L-1):
  for x in range(len(a[y])):
   c=a[y][x];C=a[y+1][x-1:x+2]
   if s!=c and s in C:t=1;a[y][x]=s;a[y+1][[[x+1,x][C[1]==s],x-1][C[0]==s]]=c
for l in map(''.join,a):print l[L:].rstrip()

Принимает ввод как список строк (по одной на строку)

Пример: ввод:

['                 (__)',
'                 (oo)',
'           /------\/',
'          / |    ||',
'         *  /\---/\ ',
'            ~~   ~~',
'..."Have you mooed today?"...']

Выход:

              (
            -----/|-(o__
         //|~~\---~\|\/o))
..."Have*you/mooed~today?"...

3

C, 252 байта

e=1,l,c,i,j,p,r,w,a[999];f(){while((i=getchar())>0)a[w++]=i,i<16?l++:0,l?0:c++;while(e)for(i=e=0;i<c;i++)for(j=l;j>=0;j--)e=(r=a[p=j*(c+1)+i]-32?a[r=p+c+1]-32?a[r=p+c]-32?a[r=p+c+2]-32?0:r:r:r:0)?l=a[p],a[p]=a[r],a[r]=l:e;for(i=0;i<w;)putchar(a[i++]);}

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

#include <stdio.h>

e=1,l,c,i,j,p,r,w,a[999];
f()
{
    // counting lines and columns
    while ((i = getchar())>0)a[w++] = i, i<16 ? l++ : 0, l ? 0 : c++;
    // main shaking loop
    while (e) // repeat while collapsing
        for (i = e = 0; i < c; i++) // columns loop
            for (j = l; j >= 0; j--) // lines loop
                e = ( // remember that collapsing was
                     r = // find place to collapse
                         a[p = j*(c + 1) + i] - 32 ? // if not space
                             a[r = p + c + 1] - 32 ? // if char under the current is not a space
                                 a[r = p + c] - 32 ? // see one position left
                                    a[r = p + c + 2] - 32 ? 0 // then one position right
                                                          : r
                                    : r
                                 : r
                             : 0
                         ) ? // and if place was found
                           l=a[p],a[p]=a[r],a[r]=l // replace values in positions p and r
                           : e;
    //print resulting picture
    for(i=0;i<w;)putchar(a[i++]);
}

int main(void)
{
    int cnt;
    FILE * testf = fopen("caw.txt","w");
    char testd[][31] = {
        "                 (__)        \n",
        "                 (oo)        \n", 
        "           /------\\/         \n", 
        "          / |    ||          \n", 
        "         *  /\\---/\\          \n", 
        "            ~~   ~~          \n", 
        "...\"Have you mooed today ? \"...",
        "" };
    // prepare data for test
    printf("Initial data:\n");
    for(cnt = 0; cnt < 7; cnt++)
    {
        printf("%s", testd[cnt]);
        fprintf(testf, testd[cnt]);
    }
    fclose(testf);
    // redirect standard input
    freopen("caw.txt", "r", stdin);
    printf("\n\nResult:\n");
    // start test
    f();
}

Результат теста:

введите описание изображения здесь


2

Альгодоо (неконкурентный)

Input - вырожденный пример.

Настроить

Runnning - по умолчанию гравитация и подпрыгивание.

Бег

Вывод - точность можно регулировать с помощью настроек трения и плотности на объектах.

Выход

Algodoo является логически программируемым .


Почему это не конкурирует? Неконкурентные обычно зарезервированы для ответов на языках, более новых, чем вызов.
Ad Hoc Garf Hunter

Хотя Algodoo может выполнять настоящую логику, это моделирование эквивалентно удалению распечатки входных данных на полу и съемке этого изображения. Я не уверен, как запечатлеть этот вывод программным способом.
wyldstallyns

И было неправильно говорить «программа с нулевым байтом! Я выиграл!»
wyldstallyns

Я подозреваю, что на самом деле это не нулевой ответ. Вы говорите о настройке параметров, которая кажется эквивалентной написанию кода. Это может быть хорошей идеей, чтобы открыть мета вопрос о выигрыше Algodoo. Я также не думаю, что с нулевой байтовой программой что-то не так.
Ad Hoc Garf Hunter

Я открою эту мету.
wyldstallyns

1

JavaScript, 286 байт

b=>eval('f=b=>b==null||" "==b;b=b.split`\n`.map(b=>[...b]);a:for(;;){for(c=0;c<b.length-1;c++)for(g=b[c],d=0;d<g.length;d++){h=g[d];if(!f(h)){e=0;f(b[c+1][d])?e=2:f(b[c+1][d-1])?e=1:f(b[c+1][d+1])&&(e=3);if(e){b[c+1][d+e-2]=h;b[c][d]=" ";continue a}}}break}b.map(b=>b.join``).join`\n`')

Примеры

// Here I assume that you've assigned the above function to `fall`
console.log(fall(`
                 (__)
                 (oo)
           /------\/
          / |    ||
         *  /\---/\\
            ~~   ~~
..."Have you mooed today?"...`))

Выход:

                -       
            /--(-\--(__  
          /|~~---/~||/oo))
..."Have*you/mooed~today?"...

Другой пример:

console.log(fall(`
 (\__/)  .~    ~. ))
 /O O  ./      .'
{O__,   \    {
  / .  . )    \\
  |-| '-' \    }
 .(   _(   )_.'
'---.~_ _ _&`))

Выход:

    _ , /            
  OO/__'_.. .         
 {.(|-|.(O'))/.~{      
/('---.~___-_&)_.'}\~.'))

Неуправляемая функция

function fall(input) {
  let move = true
  let lines = input.split("\n").map(line => line.split(""))
  let isSpace = c => c == null || c == " "
  loop: for (;;) {
    for (let y = 0; y < lines.length - 1; y++) {
      let line = lines[y]
      for (let x = 0; x < line.length; x++) {
        let ch = line[x]
        if (!isSpace(ch)) {
          let dx = 0
          if (isSpace(lines[y+1][x])) { dx = 2 }
          else if (isSpace(lines[y+1][x-1])) { dx = 1 }
          else if (isSpace(lines[y+1][x+1])) { dx = 3 }
          if (dx) {
            lines[y + 1][x + dx - 2] = ch
            lines[y][x] = " "
            continue loop
          }
        }
      }
    }
    break
  }
  return lines.map(line => line.join("")).join("\n")
}

Короткий путь к испытанию для не заготовок , c>" "где cпредставляет собой символ , который вы проверяете.
Нил
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.