Tips untuk bermain golf seni ASCII

18

Saya pikir pertanyaan seni ASCII di PPCG itu menyenangkan untuk dilakukan, tetapi secara pribadi saya pikir itu bisa sangat sulit, terutama ketika pertanyaan tersebut ditandai sebagai .

Saya ingin tahu apakah ada orang di sini yang memiliki beberapa tips yang akan berguna untuk memproduksi seni ASCII.

Cukup mengatur karakter itu mudah, tetapi dengan algoritma (pendek), segalanya akan menjadi lebih rumit.

Saya berbicara tentang seni ASCII seperti:

  • Teks ke seni ASCII (karakter)
  • Gambar (logo atau ikon)

Saya hanya mencari tips umum, tetapi bahasa spesifik diperbolehkan karena kebanyakan dari mereka dapat diterjemahkan.

Teun Pronk
sumber

Jawaban:

8

Algoritma kompresi

Anda dapat menerapkan kompresi LZMA ke string.
Banyak bahasa mendukungnya.

Pengodean run-length

Anda dapat menggunakan instruksi pemrosesan seperti [char][number](misalnya b12).
Algoritma kompresi ini digunakan di sini: /codegolf//a/20589/10920

Bacaan lebih lanjut: http://en.wikipedia.org/wiki/Run-length_encoding

Kemasan integer

Anda dapat menggunakan array bilangan bulat untuk menyimpan bentuk kecil seperti:

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

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

Setiap ruang akan diterjemahkan menjadi a 0.
Setiap tajam akan diterjemahkan ke dalam 1.

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

Setiap bit kemudian dibaca menggunakan operator bitwise &.

Algoritme di atas dapat ditingkatkan dengan menggunakan basis integer yang lebih besar:

// ~44 characters
// Integers are in base 36.
// Use `_` as a separator (or a line break).
"47qo_122o_5m9c_lf0c_2hwcf_211ir_1zn03_1c5c"
Florent
sumber
3
Instruksi pemrosesan Anda umumnya dikenal sebagai pengkodean run-length , FYI.
FireFly
@FireFly Terima kasih! Saya tidak tahu ada nama untuk itu.
Florent
Pada par (bahasa saya) ini dapat diperpanjang lebih lanjut karena mendukung bilangan bulat yang disandikan hingga basis 62:[0-9A-Za-z]
Cyoce
5

Cari simetri

Kadang-kadang seni ASCII yang dibutuhkan simetris pada beberapa titik. Misalnya, Argyle ASCII Art membutuhkan output yang mirip dengan ini:

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

Orang hanya dapat mencetak ini secara normal, tetapi tergantung pada bahasa, kode yang diperlukan dapat dipersingkat dengan hanya menghasilkan setengah bagian atas hasilnya, membalikkannya dan menukar /dan \.

Coba transposing

Di ASCII Art Archery Arrows hasil untuk dicetak adalah ini, diskalakan ke yang diberikan n:

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

Jika kita melihat panah, kita dapat melihat ada 8 jenis garis:

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

Mari kita coba hal yang sama untuk transposnya.

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

Di sini, ada 10 macam garis.

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

Tapi ini masalahnya: 5 bawah identik dengan 5 teratas, kecuali untuk bertukar /dan \. Sesuai aturan sebelumnya, Anda pertama-tama dapat menghasilkan 5 pertama, salin, lakukan swap, dan akhirnya transpos untuk mendapatkan panah. Ini dapat menyimpan banyak kode.

PurkkaKoodari
sumber
5

Kontrol karakter, urutan pelarian dan kode konsol

Kecuali pertanyaan melarang mereka, konsensus saat ini di Meta adalah bahwa tantangan seni ASCII tidak memerlukan aliran byte spesifik, tetapi output yang terlihat benar.

Ini berarti bahwa kita dapat menggunakan karakter kontrol ASCII , urutan pelarian ANSI dan kode konsol Linux dalam jawaban kita, dengan asumsi terminal pendukung.

Kecuali ditentukan sebaliknya, sisa jawaban ini akan menjelaskan perilaku terminal Linux, yang mana saya miliki untuk pengujian sekarang.

Karakter kontrol ASCII

Dukungan / interpretasi bervariasi dari terminal ke terminal dan karakter ke karakter. Yang paling portabel adalah linefeed ( \n, \x0a), yang memindahkan karakter ke awal baris berikutnya.

Karakter berguna lainnya termasuk:

  • Tab vertikal ( \v, \x0b) menggerakkan kursor satu posisi ke kanan, lalu satu posisi ke bawah.

    $ echo -e 'a\vb'
    a
     b
    
  • Carriage return ( \r, \x0d) memindahkan kursor ke awal baris saat ini . Setiap karakter yang dapat dicetak berikutnya akan menimpa karakter pertama dari baris saat ini.

    $ echo -e 'ab\rc'
    cb
    
  • Backspace ( \b, \x08) menggerakkan kursor satu posisi ke kiri. Setiap karakter yang dapat dicetak berikutnya akan menimpa karakter sebelum ruang belakang.

    $ echo -e 'ab\bc'
    ac
    
  • Escape ( \e, \x1b) tidak melakukan apa-apa pada dirinya sendiri, tetapi merupakan bagian dari urutan escape ANSI (opsional) dan kode konsol Linux.

Banyak bahasa mengizinkan karakter kontrol aktual dalam kode sumber.

Urutan melarikan diri ANSI

(belum datang)

Kode konsol Linux

Meskipun ada lebih banyak lagi, kode konsol yang paling berguna untuk seni ASCII mungkin adalah ini:

  • Urutan \ecakan mengatur ulang terminal. Ini membersihkan layar, memindahkan kursor ke sudut kiri atas dan menetapkan warna latar depan dan belakang, kursor yang berkedip, dll. Ke nilai standarnya.

  • Urutan \eMmenyebabkan umpan baris terbalik , yaitu, kursor akan bergerak satu posisi ke atas.

    $ echo -e '\na\eMb\n'
     b
    a
    
  • Urutan \eHmengatur berhenti tab di kolom saat ini.

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

Cari polanya

Yang ini mungkin agak jelas, tapi ... cari pola, persamaan dan pengulangan dalam output. Misalnya, ketika saya melihat Transform number menjadi tugas pola tampilan 7-segmen, saya mulai berpikir tentang bagaimana seseorang bisa bermain golf, dan mulai mencari kesamaan. Karena cara segmen horisontal bergerak di antara yang vertikal dalam matriks karakter, mungkin akan lebih mudah untuk berurusan dengan tiga segmen sekaligus, dikelompokkan bersama (menambahkan dua segmen "selalu kosong" untuk yang pertama, yang paling atas) :

segmen meraba-raba

Dengan demikian, Anda bisa melakukan sesuatu seperti lc + " "*N + rc + "\n"N-1 kali dan kemudian lc + bc*N + rcsekali, untuk setiap tiga segmen ( lc, bc, rcmenjadi karakter kiri, bottom, dan kanan-segmen, yaitu salah satu |, _atau  ).

FireFly
sumber
2

Gunakan konversi basis

Jawaban ini adalah untuk pertanyaan yang ingin seni ASCII yang terdiri dari karakter + |-dan baris baru. Karena hanya ada 5 karakter yang mungkin, ini dapat diperlakukan sebagai nomor basis 5 dan dikonversi ke byte, mengemas 3,45 karakter per byte.

Memanfaatkan keteraturan

Seringkali, data akan memiliki beberapa keteraturan, bahkan jika keteraturan tersebut tidak cukup kuat untuk menggunakan alat khusus seperti mirroring. Misalnya, dalam pertanyaan di atas, output yang diinginkan memiliki baris baru yang secara kasar berjarak merata di sepanjang tes, karena teksnya kira-kira persegi panjang. Saya mengeksploitasi ini untuk mempersingkat kode saya, dengan menggunakan Pyth's split menjadi fungsi n pieces, kemudian bergabung di baris baru.

Ketahui alat Anda, dan pilih yang tepat untuk pekerjaan itu.

Alat pemrosesan teks yang paling kuat dan efisien yang saya tahu adalah:

Mesin Regex:, ///Retina, Perl, dalam urutan power / conciseness tradeoff.

Gunakan jika hal yang ingin Anda lakukan dapat dengan hati-hati dijelaskan dalam penggantian regex, seperti jawaban ini

Alat pemrosesan teks yang tidak jelas: gema, dll. (Saya yakin ada yang lain, tapi terlalu kabur)

Gunakan jika mereka memiliki fitur yang persis Anda butuhkan, yang tidak dimiliki oleh yang lain. Seperti dalam pertanyaan ini , dengan pencocokan rekursif gema.

Bahasa golf kode umum: CJam, Pyth, dll.

Gunakan jika Anda mengeksploitasi beberapa kompleksitas yang cukup halus sehingga tidak ada alat lain yang dapat melakukan pekerjaan itu atau hanya melakukan pekerjaan yang lebih pendek.

Coba banyak pendekatan

Ini berlaku dalam setiap pertanyaan kode-golf, terutama di sini. Anda tidak akan tahu apakah keteraturan dapat dieksploitasi hingga Anda mencobanya. Mungkin dalam berbagai bahasa.

isaacg
sumber