Collapse ascii-art


12

Sfida

Data una griglia rettangolare di caratteri ASCII stampabili come stringa o tramite input standard, scrivere una funzione o un programma che comprime i caratteri non spaziali in una pila sul fondo.

Le regole:

  • L'output ha le stesse dimensioni e caratteri dell'input.
  • Un personaggio non spaziale in (row a,column b)non può avere un carattere spaziale ' 'in (a-1, b), (a-1,b-1)o (a-1,b+1), dove le righe sono numerate dal più in basso. Ciò ha la conseguenza che tutte le pile verticali dovrebbero crollare lateralmente.
  • Un personaggio non spaziale può viaggiare nella maggior parte dei (initial height - final height)posti a sinistra o a destra (vedi Fig. 1).
  • Puoi presumere che l'immagine abbia abbastanza spazio per crollare senza che i personaggi cadano dallo schermo.

Figura 1: possibili posizioni finali per i personaggi @#$mostrati come x,y,z, rispettivamente.

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

L'ordine in cui i personaggi collassano può essere scelto liberamente. Gli spazi finali non vanno bene, ma lo sono le nuove righe finali.

Questo è , quindi vince la risposta più breve in byte!

Esempio

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

Un possibile output:

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

Giusto per chiarire, il modo in cui i personaggi cadono può essere codificato ogni volta piuttosto che generato casualmente?
ETHproductions

18
Cosa ti ha mai fatto quella mucca ?? :(
FlipTack,

@ETHproductions che è corretto. Il mio esempio lo fa dal basso verso l'alto, da sinistra a destra ma l'ordine casuale o qualcos'altro va bene, purché le regole vengano rispettate.
Angs,

@ Flp.Tkc È solo un modello.
Angs,

1
@DestructibleWatermelon se un personaggio capita di cadere fuori dallo schermo, è colpa sua, non tua.
Angs

Risposte:


4

JavaScript (ES6), 100 90 88 byte

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

Richiede che la stringa abbia almeno due righe e tutte le righe riempite alla stessa lunghezza. Output per l'immagine di esempio:

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

Si noti che nel tentativo di spostare gli elementi a destra, se possibile, il *non è compreso tra il Havee il you.

Modifica: risparmiato il 10% grazie a @ETHproductions. Salvati altri 2 byte grazie a @DanielIndie.

Retina 0.8.2 , 50 byte

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

Provalo online! Un approccio leggermente diverso alla mia risposta JavaScript, utilizza un gruppo di bilanciamento per abbinare uno spazio al di sotto del carattere non spaziale; il (?<-1>)?consente allo spazio di essere una colonna a sinistra mentre il .?consente allo spazio di essere una colonna a destra.

Retina , 40 byte

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

Provalo online! Porta della mia risposta JavaScript. Lo 0L$stadio atomico accetta l'input e sostituisce le due lunghezze nella seconda riga risultando nel comando che esegue effettivamente la sostituzione, che viene quindi valutata sull'input originale dallo ~stage composto.


Questo è un ottimo algoritmo! Puoi sostituirlo \ncon una nuova riga letterale per
ridurlo

Inoltre, penso che puoi farlo l=s.search`\n` per risparmiare qualche byte.
ETHproductions


@DanielIndie f=È necessario per la ricorsione, ma mi fa ancora risparmiare 2 byte, grazie!
Neil,

hai ragione, scusa: P
DanielIndie

3

Python 2, 298 byte

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

Accetta input come un elenco di stringhe (una per riga)

Esempio: input:

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

Produzione:

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

3

C, 252 byte

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

Codice di prova non golfato:

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

Risultato del test:

inserisci qui la descrizione dell'immagine


2

Algodoo (non concorrenziale)

Input - esempio degenerato utilizzato.

Impostare

Runnning: gravità e rimbalzo predefiniti.

In esecuzione

Output: la precisione può essere regolata tramite le impostazioni di attrito e densità sugli oggetti.

Produzione

Algodoo è programmabile in logica .


Perché questo non è in competizione? La non competizione è generalmente riservata alle risposte in lingue più recenti della sfida.
Ad Hoc Garf Hunter il

Sebbene Algodoo possa fare la vera logica, questa simulazione equivale a far cadere una stampa frantumata dell'input sul pavimento e scattare una foto di esso. Non sono sicuro di come anche catturare quell'output in modo programmatico.
wyldstallyns,

E sembrava sbagliato dire "programma zero byte! Ho vinto!"
wyldstallyns,

Sospetto che questa non sia in realtà una risposta a zero byte. Parli di modificare le impostazioni che sembrano equivalere alla scrittura del codice. Potrebbe essere una buona idea aprire una meta domanda sul punteggio di Algodoo. Inoltre, non penso che ci sia qualcosa di sbagliato nell'avere un programma a zero byte.
Ad Hoc Garf Hunter,

Aprirò quella meta.
wyldstallyns,

1

JavaScript, 286 byte

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

Esempi

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

Produzione:

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

Un altro esempio:

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

Produzione:

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

Funzione non golfata

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

Un modo breve per verificare se non è vuoto è c>" "dove crappresenta il personaggio che si sta testando.
Neil,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.