Tipps zum Golfen ASCII art

18

Ich denke, die ASCII-Kunst-Fragen zu PPCG machen Spaß, aber ich persönlich denke, es kann ziemlich schwierig sein, besonders wenn die Frage als markiert ist .

Ich frage mich, ob hier jemand Tipps hat, die für die Erstellung von ASCII-Grafiken hilfreich sind.

Das einfache Anordnen von Zeichen ist einfach, aber mit (kurzen) Algorithmen werden die Dinge komplizierter.

Ich spreche über ASCII-Kunst wie:

  • Text zu ASCII-Kunst (Zeichen)
  • Bilder (Logos oder Icons)

Ich suche nur nach allgemeinen Tipps, aber sprachspezifisch ist erlaubt, da die meisten davon sowieso übersetzt werden können.

Teun Pronk
quelle

Antworten:

8

Kompressionsalgorithmen

Sie können die Zeichenfolge mit LZMA komprimieren.
Viele Sprachen unterstützen es.

Lauflängencodierung

Sie können Verarbeitungsanweisungen wie [char][number]zB verwenden b12.
Dieser Komprimierungsalgorithmus wird hier verwendet: /codegolf//a/20589/10920

Weiterführende Literatur: http://en.wikipedia.org/wiki/Run-length_encoding

Ganzzahlige Packung

Sie können Arrays von ganzen Zahlen verwenden, um kleine Formen zu speichern, wie zum Beispiel:

// This is an invader!
// (SE line height makes it looks awful)
// ~158 characters

    ##          ##    
      ##      ##      
    ##############    
  ####  ######  ####  
######################
##  ##############  ##
##  ##          ##  ##
      ####  ####       

Jedes Leerzeichen wird in ein übersetzt 0.
Jeder Scharfe wird in eine 1. Übersetzt .

// ~58 characters
// Saved ~100 bytes!
[
  196656,  49344,   262128,  999228,
  4194303, 3407859, 3342387, 62400
]

Jedes Bit wird dann mit dem bitweisen Operator gelesen &.

Der obige Algorithmus könnte durch Verwendung einer größeren Ganzzahlbasis verbessert werden:

// ~44 characters
// Integers are in base 36.
// Use `_` as a separator (or a line break).
"47qo_122o_5m9c_lf0c_2hwcf_211ir_1zn03_1c5c"
Florent
quelle
3
Ihre Verarbeitungsanweisungen werden allgemein als Lauflängencodierung (FYI) bezeichnet.
FireFly
@FireFly Danke! Ich wusste nicht, dass es einen Namen dafür gibt.
Florent
In par (meine Sprache) kann dies noch erweitert werden, da es Ganzzahlen unterstützt, die bis zur Basis 62 codiert sind:[0-9A-Za-z]
Cyoce
5

Achten Sie auf Symmetrie

Manchmal ist die erforderliche ASCII-Grafik irgendwann symmetrisch. Für Argyle ASCII Art ist beispielsweise eine Ausgabe ähnlich der folgenden erforderlich:

    /\        /\
   /  \  /\  /  \
/\/    \/  \/    \/\
\/\    /\  /\    /\/
   \  /  \/  \  /
    \/        \/

Man könnte dies normalerweise nur drucken, sondern abhängig von der Sprache, der Code benötigt wird, kann nur verkürzt werden , um die obere Hälfte des Ergebnisses zu erzeugen, Umkehr und Swapping /und \.

Versuchen Sie zu transponieren

In ASCII Art Archery Arrows ist das zu druckende Ergebnis wie folgt skaliert n:

     /\
    /  \
   /    \
  /      \
  \      /
   \____/
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
   /|  |\
  / |  | \
 /  |  |  \
/   |  |   \
/   |  |   \
/   |__|   \
/  /    \  \
/ /      \ \
//        \\
/          \

Wenn wir uns den Pfeil ansehen, sehen wir, dass es 8 Arten von Linien gibt:

/ \
\ /
\_/
| |
/ | | \
/ |_| \
/ / \ \
/ \

Versuchen wir dasselbe für die Transponierung.

                         ///////
                        /     / 
   /\                  /     /  
  /  \                /     /   
 /   _||||||||||||||||||||||    
/    _                     _    
\    _                     _    
 \   _||||||||||||||||||||||    
  \  /                \     \   
   \/                  \     \  
                        \     \ 
                         \\\\\\\

Hier gibt es 10 Arten von Linien.

/
/ /
/ \ / /
/ _|
/ _ _
\ _ _
\ _|
\ / \ \
\ \
\

Aber hier ist der Haken: Die unteren 5 sind identisch mit den oberen 5, außer zum Tauschen /und \. Gemäß der vorherigen Regel können Sie zuerst die ersten 5 generieren, kopieren, tauschen und schließlich transponieren, um den Pfeil zu erhalten. Dies kann viel Code sparen.

PurkkaKoodari
quelle
5

Steuerzeichen, Escape-Sequenzen und Konsolencodes

Sofern die Frage dies nicht verbietet, ist der aktuelle Konsens in Bezug auf Meta, dass ASCII-Kunst-Herausforderungen keinen bestimmten Byte-Stream erfordern, sondern eine Ausgabe, die korrekt aussieht.

Dies bedeutet, dass wir in unseren Antworten ASCII-Steuerzeichen , ANSI-Escape-Sequenzen und Linux-Konsolencodes verwenden können, sofern ein unterstützendes Terminal verwendet wird.

Sofern nicht anders angegeben, wird der Rest dieser Antwort das Verhalten von Linux-Terminals erläutern, das mir derzeit zum Testen zur Verfügung steht.

ASCII-Steuerzeichen

Die Unterstützung / Interpretation variiert von Terminal zu Terminal und von Zeichen zu Zeichen. Das portabelste sollte der Zeilenvorschub ( \n, \x0a) sein, mit dem das Zeichen an den Anfang der nächsten Zeile verschoben wird.

Andere nützliche Zeichen sind:

  • Der vertikale Tabulator ( \v, \x0b) bewegt den Cursor eine Position nach rechts und dann eine Position nach unten.

    $ echo -e 'a\vb'
    a
     b
    
  • Der Wagenrücklauf ( \r, \x0d) bewegt den Cursor an den Anfang der aktuellen Zeile. Jedes nachfolgende druckbare Zeichen überschreibt das erste Zeichen der aktuellen Zeile.

    $ echo -e 'ab\rc'
    cb
    
  • Die Rücktaste ( \b, \x08) bewegt den Cursor um eine Position nach links. Jedes nachfolgende druckbare Zeichen überschreibt das Zeichen vor der Rücktaste.

    $ echo -e 'ab\bc'
    ac
    
  • Das Escape ( \e, \x1b) tut nichts für sich, sondern ist Teil von ANSI-Escape-Sequenzen (optional) und Linux-Konsolencodes.

Viele Sprachen erlauben tatsächliche Steuerzeichen im Quellcode.

ANSI-Escape-Sequenzen

(noch kommen)

Linux-Konsolencodes

Obwohl es noch viele weitere gibt, sind die nützlichsten Konsolencodes für ASCII-Grafiken wahrscheinlich folgende:

  • Die Sequenz \ecwird zurückgesetzt Terminal. Dies löscht den Bildschirm, bewegt den Cursor in die obere linke Ecke und setzt die Vorder- und Hintergrundfarbe, die Cursor-Blinkrate usw. auf ihre Standardwerte.

  • Die Sequenz \eMbewirkt einen Zeilenumbruch , dh der Cursor bewegt sich eine Position nach oben.

    $ echo -e '\na\eMb\n'
     b
    a
    
  • Die Sequenz \eHsetzt den Tabulator an der aktuellen Spalte.

    $ echo -e '   \eHa\n\tb'
       a
       b
    
Dennis
quelle
2

Suchen Sie nach Mustern

Dies mag ein bisschen offensichtlich sein, aber ... achten Sie auf Muster, Ähnlichkeiten und Wiederholungen in der Ausgabe. Als ich zum Beispiel die Aufgabe " Nummer in 7-Segment-Anzeigemuster transformieren" sah, dachte ich darüber nach, wie man Golf spielen kann, und suchte nach Ähnlichkeiten. Aufgrund der Art und Weise, wie die horizontalen Segmente zwischen den vertikalen Segmenten in der Zeichenmatrix liegen, ist es wahrscheinlich am einfachsten, drei Segmente gleichzeitig zu behandeln, die als solche gruppiert sind (indem zwei "immer leere" Segmente für das erste, oberste hinzugefügt werden). :

Segmente tastend

So Sie so etwas wie tun können , lc + " "*N + rc + "\n"N-1 mal und dann lc + bc*N + rceinmal, für alle drei Segmente ( lc, bc, rcwobei die linken, Boden- und rechtes Segment Zeichen, das heißt einer der |, _oder  ).

FireFly
quelle
2

Verwenden Sie die Basiskonvertierung

Diese Antwort bezog sich auf eine Frage, die ASCII-Kunst wollte, die aus Zeichen + |-und Zeilenumbrüchen bestand. Da es nur 5 mögliche Zeichen gibt, können diese als Basis-5-Zahl behandelt und in Bytes umgewandelt werden, wobei 3,45 Zeichen pro Byte gepackt werden.

Regelmäßigkeiten ausnutzen

Häufig weisen die Daten einige Regelmäßigkeiten auf, auch wenn diese Regelmäßigkeiten nicht stark genug sind, um bestimmte Tools wie das Spiegeln zu verwenden. Zum Beispiel hatte in der obigen Frage die gewünschte Ausgabe Zeilenumbrüche, die während des Tests ungefähr gleichmäßig verteilt waren, da der Text ungefähr rechteckig war. Ich habe dies ausgenutzt, um meinen Code zu verkürzen, indem ich Pyths in n Teile aufgeteilte Funktion verwendete und mich dann in Zeilenumbrüchen einfügte.

Kennen Sie Ihre Werkzeuge und wählen Sie das richtige für den Job.

Die leistungsfähigsten und effizientesten Textverarbeitungswerkzeuge, die ich kenne, sind:

Regex-Motoren:, ///Retina, Perl, in der Reihenfolge des Kompromisses zwischen Leistung und Prägnanz.

Verwenden Sie diese Option, wenn das, was Sie tun möchten, in regulären Substitutionen genau beschrieben werden kann, z. B. in dieser Antwort

Obskure Textverarbeitungswerkzeuge: Gema usw. (Ich bin sicher, es gibt andere, aber sie sind zu dunkel)

Verwenden Sie, wenn sie eine Funktion haben, die genau das ist, was Sie brauchen, die sonst nichts hat. Wie in dieser Frage , mit Gemas rekursivem Matching.

Allgemeine Code-Golfsprachen: CJam, Pyth usw.

Verwenden Sie diese Option, wenn Sie ein so komplexes Programm ausnutzen, dass es von keinem anderen Tool ausgeführt wird, oder wenn es nur kürzer ist.

Probieren Sie viele Ansätze

Dies gilt in jeder Code-Golf-Frage, insbesondere aber hier. Sie werden nicht wissen, ob eine Regelmäßigkeit ausnutzbar ist, bis Sie es ausprobieren. Möglicherweise in mehreren Sprachen.

isaacg
quelle