Ascii-Art einklappen

12

Herausforderung

Schreiben Sie bei einem rechteckigen Raster aus druckbaren ASCII-Zeichen als Zeichenfolge oder über die Standardeingabe eine Funktion oder ein Programm, mit dem die nicht-Leerzeichen in einem Stapel unten zusammengefasst werden.

Die Regeln:

  • Die Ausgabe hat die gleichen Abmessungen und Zeichen wie die Eingabe.
  • Ein nicht-Leerzeichen an (row a,column b)kann kein Leerzeichen hat ' 'an (a-1, b), (a-1,b-1)oder (a-1,b+1), wo Zeilen werden von dem am weitesten unten nummeriert werden. Dies hat zur Folge, dass alle vertikalen Pfähle seitlich zusammenbrechen sollten.
  • Ein Nicht-Leerzeichen kann sich an den meisten (initial height - final height)Stellen nach links oder rechts bewegen (siehe Abb. 1).
  • Sie können davon ausgehen, dass das Bild genügend Platz zum Ausblenden hat, ohne dass Zeichen aus dem Bildschirm fallen.

Abbildung 1: Mögliche Endpositionen für die @#$als angezeigten Zeichen x,y,z.

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

Die Reihenfolge, in der die Zeichen zusammenfallen, kann frei gewählt werden. Nachgestellte Leerzeichen sind nicht in Ordnung, nachgestellte Zeilenumbrüche jedoch.

Das ist , also gewinnt die kürzeste Antwort in Bytes!

Beispiel

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

Eine mögliche Ausgabe:

 
 
 
                --(_
           /----|/|(o_)
          /|/~\---~\\/o)
..."Have*you~mooed~today?"...
Angs
quelle
Um dies zu verdeutlichen, kann die Art und Weise, wie Zeichen fallen, jedes Mal fest codiert und nicht zufällig generiert werden.
ETHproductions
18
Was hat diese Kuh dir je angetan? :(
FlipTack
@ETHproductions das stimmt. Mein Beispiel funktioniert von unten nach oben, von links nach rechts, aber zufällige Reihenfolge oder etwas anderes ist in Ordnung, solange die Regeln eingehalten werden.
Angs
@ Flp.Tkc Es ist nur ein Modell.
Angs
1
@DestructibleWatermelon Wenn ein Charakter aus dem Bildschirm fällt, ist es seine Schuld, nicht deine.
Angs

Antworten:

4

JavaScript (ES6), 100 90 88 Bytes

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

Erfordert, dass die Zeichenfolge mindestens zwei Zeilen enthält und alle Zeilen auf die gleiche Länge aufgefüllt sind. Ausgabe für das Beispielbild:

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

Beachten Sie, dass beim Versuch, Elemente nach rechts zu verschieben, die *Zeichen nicht zwischen die Zeichen Haveund fallen you.

Bearbeiten: Dank @ETHproductions 10% gespart. Dank @DanielIndie wurden weitere 2 Bytes gespeichert.

Retina 0,8,2 , 50 Bytes

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

Probieren Sie es online! Eine etwas andere Herangehensweise an meine JavaScript-Antwort. Hierbei wird eine Ausgleichsgruppe verwendet, um ein Leerzeichen unter dem Nicht-Leerzeichen-Zeichen abzugleichen. Das (?<-1>)?erlaubt, dass der Abstand eine Spalte nach links ist, während das .?erlaubt, dass der Abstand eine Spalte nach rechts ist.

Retina , 40 Bytes

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

Probieren Sie es online! Port meiner JavaScript-Antwort. Die 0L$atomare Stufe nimmt die Eingabe und setzt die beiden Längen in die zweite Zeile ein, was zu dem Befehl führt, der die Ersetzung tatsächlich durchführt, der dann an der ursprünglichen Eingabe von der ~zusammengesetzten Stufe ausgewertet wird .

Neil
quelle
Dies ist ein großartiger Algorithmus! Sie können \nmit einem wörtlichen Zeilenumbruch ersetzen , um es auf zwei Ziffern zu bringen ;-)
ETHproductions
Auch ich denke du kannst so l=s.search`\n` ein paar Bytes sparen.
ETHproductions
tio.run/##ZY/… 86 Bytes
DanielIndie
@DanielIndie Die f=wird für die Rekursion benötigt, spart mir aber trotzdem 2 Bytes, danke!
Neil
Sie haben Recht, sorry: P
DanielIndie
3

Python 2, 298 Bytes

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

Nimmt die Eingabe als Liste von Zeichenfolgen (eine pro Zeile)

Beispiel: Eingabe:

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

Ausgabe:

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

C 252 Bytes

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-Testcode:

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

Ergebnis der Prüfung:

Bildbeschreibung hier eingeben

VolAnd
quelle
2

Algodoo (nicht konkurrierend)

Eingabe - entartetes Beispiel verwendet.

Installieren

Laufen - Standardschwerkraft und Hüpfen.

Laufen

Die Ausgabegenauigkeit kann über die Einstellungen für Reibung und Dichte an den Objekten angepasst werden.

Ausgabe

Algodoo ist logisch programmierbar .

wyldstallyns
quelle
Warum ist das nicht konkurrierend? Das Nicht-Konkurrieren ist im Allgemeinen Antworten in Sprachen vorbehalten, die neuer sind als die Herausforderung.
Post Rock Garf Hunter
Obwohl Algodoo echte Logik beherrscht, ist diese Simulation gleichbedeutend damit, einen vernichtenden Ausdruck der Eingabe auf den Boden zu werfen und ein Bild davon zu machen. Ich bin mir nicht sicher, wie ich diese Ausgabe überhaupt programmatisch erfassen soll.
Wyldstallyns
Und es schien falsch zu sagen "Zero-Byte-Programm! Ich gewinne!"
Wyldstallyns
Ich vermute, dass dies keine Null-Byte-Antwort ist. Sie sprechen von Einstellungen, die anscheinend dem Schreiben von Code entsprechen. Es könnte eine gute Idee sein, eine Meta-Frage zur Bewertung von Algodoo zu öffnen. Ich glaube auch nicht, dass irgendetwas falsch daran ist, ein Null-Byte-Programm zu haben.
Post Rock Garf Hunter
Ich werde das Meta öffnen.
Wyldstallyns
1

JavaScript, 286 Bytes

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

Beispiele

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

Ausgabe:

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

Ein anderes Beispiel:

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

Ausgabe:

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

Ungolfed Funktion

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")
}
Florent
quelle
Ein kurzer Weg zum Test für nicht leer ist , c>" "wo cdas Zeichen repräsentieren Sie testen.
Neil