Format PBM (Portable BitMap) adalah format bitmap ASCII hitam dan putih yang sangat sederhana.
Berikut adalah contoh untuk huruf 'J' (disalin dari tautan wikipedia):
P1 # Ini adalah contoh bitmap dari huruf "J" 6 10 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Sudah saatnya kita membangun alat kecil untuk menghasilkan file dalam format kecil yang bagus ini!
Tujuan Anda adalah untuk menulis program terpendek (dalam bahasa apa pun) yang sesuai dengan aturan berikut:
- Program Anda mengambil satu string dari stdin (misalnya
CODEGOLF.STACKEXCHANGE.COM!
) - Ini menghasilkan file PBM dengan representasi string yang dapat dibaca (dapat dibaca).
- Setiap karakter dibangun sebagai kotak 8x8.
- Anda harus mendukung karakter [AZ] (semua huruf besar), spasi, titik ('.') Dan tanda seru ('!').
- Tidak ada perpustakaan eksternal yang diizinkan (tentu saja tidak ada yang terkait dengan PBM)!
- Set karakter yang digunakan tidak boleh hanya eksternal untuk program Anda. Bagian dari tantangannya adalah menyimpan karakter secara efisien ...
Pengujian validitas format PBM dapat dilakukan dengan GIMP (atau lainnya). Pamerkan input dan output sampel!
Solusi terpendek akan diberikan poin jawaban pada 2012-01-31.
Bersenang-senang bermain golf!
PS: Saya telah menambahkan hadiah (persentase-bijaksana bagian besar dari reputasi codegolf saya) untuk (mudah-mudahan) menarik lebih banyak pesaing.
code-golf
string
graphical-output
ChristopheD
sumber
sumber
letters
kata lain). Tidak berbeda dengan contoh yang ditautkan.Jawaban:
GolfScript, 133 byte
Ini didasarkan pada solusi Perl 164-byte saya dan menggunakan font 4 by 5 pixel yang sama-mengemasi. Sekali lagi, saya akan memberikan versi yang dapat dibaca terlebih dahulu:
Di sini,
FONT DATA HERE
singkatan dari 71 byte data font yang dikemas biner. Pengkodean sedikit berbeda dari pada versi Perl: alih-alih membelah string yang dikemas pada spasi putih, saya memperluasnya terlebih dahulu dan kemudian membaginya pada nibble3
(dipilih karena kebetulan tidak terjadi di mana pun di font).Karena data font dalam skrip aktual berisi karakter yang tidak patut dicetak, saya berikan sebagai hex dump di bawah ini. Gunakan
xxd -r
untuk mengubah hex dump kembali menjadi kode GolfScript yang dapat dieksekusi:Tidak seperti script Perl, kode ini mencetak karakter apapun di luar set
A
-Z
,!
,.
,space
sebagai coretan kecil yang lucu-cari. Mengganti coretan dengan kosong akan membutuhkan 2 karakter tambahan; menghapusnya seluruhnya akan memakan biaya 4.Ini adalah program GolfScript pertama saya, jadi saya tidak akan terkejut jika masih ada ruang untuk optimasi. Begini cara kerjanya:
{91,65>"!. "+?}%:s
memetakan karakter input yang valid (A
-Z
,!
,.
,space
) ke angka 0 - 28 dan ditunjuk hasilnya kes
. Setiap karakter di luar set yang valid dipetakan ke -1, yang menghasilkan coretan ketika dicetak."P4"\,8*8
mendorong nilai "P4", 8 kali panjang input, dan 8 ke tumpukan. Saat dicetak di bagian akhir, ini akan membentuk header PBM.{16base}%[3]/
mengambil string sebelumnya dari data font, membagi setiap byte dari itu menjadi dua camilan, dan membagi hasilnya menjadi blok-blok yang dibatasi oleh nilai3
.{:p;{[p=0]0=}s%}%
kemudian lompati blok-blok ini, pertama-tama menugaskan setiap blok ke variabelp
dan kemudian mengulangi string input yang dipetakan kembalis
, mengganti setiap karakter dengan nilai pada offset yang sesuai dip
. Konstruk yang tampak lucu[p=0]0=
melakukan hal yang samap=
, kecuali bahwa ia mengembalikan 0 untuk setiap offset melewati akhirp
; Saya tidak begitu menyukainya, tetapi saya belum bisa menemukan cara yang lebih pendek untuk mengatasinya.Akhirnya,
]n*
ambil semua yang ada di tumpukan (tiga nilai header dan array data gambar) dan gabungkan dengan baris baru untuk dicetak.sumber
Perl, 164 byte, tidak ada kompresi zlib / gzip
Setelah tidur pada masalah, saya berhasil menemukan solusi yang jauh lebih pendek daripada yang pertama. Caranya adalah dengan memanfaatkan celah kecil dalam aturan: karakter harus masing-masing pas dengan 8 x 8 piksel, tetapi tidak ada yang mengatakan mereka harus mengisi semua ruang itu. Jadi saya menggambar font 4 x 5 pixel saya sendiri, memungkinkan saya untuk mengemas dua karakter menjadi 5 byte.
Outputnya terlihat seperti ini:
(diskalakan x 4)
(ukuran asli)
Sebelum memberikan kode aktual dengan data font yang disematkan, izinkan saya menunjukkan versi de-golf:
Dalam kode aktual,
PACKED FONT DATA
digantikan oleh string biner yang terdiri dari delapan baris ruang-dibatasi (empat baris 14-byte dan satu 13-byte, ditambah tiga byte nol tunggal untuk baris kosong). Saya sengaja mendesain font saya sehingga data yang dikemas tidak mengandung spasi, tanda kutip tunggal atau garis miring terbalik, sehingga bisa dikodekan dalamqw'...'
.Karena string font yang dikemas berisi karakter yang tidak patut, saya telah menyediakan skrip aktual sebagai hex dump. Gunakan
xxd -r
untuk mengubahnya kembali menjadi kode Perl yang dapat dieksekusi:Begini cara kerjanya:
Baris pertama (dalam versi de-golf) membaca satu baris input, membaginya menjadi sebuah array karakter (dengan mudah menghilangkan setiap baris baru) dan memetakan huruf
A
keZ
dan karakter!
dan.
ke kode karakter 0 hingga 28, yang biasanya sesuai dengan karakter kontrol yang tidak diinginkan dalam ASCII / Unicode. (Efek samping minor dari ini adalah bahwa setiap tab pada input dapat dicetak sebagaiJ
s.) Karakter spasi dibiarkan tidak dipetakan, karena loop output mengubah kode di atas 28 menjadi kosong.Baris kedua hanya mencetak header PBM. Ini menggunakan fitur Perl 5.10
say
, jadi Anda perlu menjalankan skrip iniperl -M5.010
agar bisa berfungsi.Output loop mengambil daftar baris gambar yang dipisahkan spasi-putih dan menugaskan masing-masing dari mereka
$p
secara bergantian. (Saya mendesain font agar data yang dikemas tidak mengandung spasi atau'
karakter apa pun .) Kemudian loop di atas karakter input masuk@a
, menggunakanvec
perintah Perl untuk mengekstrak nibble 4-bit yang sesuai dengan kode karakter yang dipetakan dari baris gambar, membalutnya ke byte 8-bit dan mencetaknya.Jawaban lama, 268 byte:
Ini adalah upaya pertama yang cepat dan kotor. Saya mencuri font PleaseStand dan mengompresnya bersama dengan kode sumber saya. Karena skrip yang dihasilkan sebagian besar tidak dapat dicetak, inilah hexdump; gunakan
xxd -r
untuk mengubahnya menjadi kode Perl yang dapat dieksekusi:Kode Perl yang terdekompresi terdiri dari pembukaan berikut:
diikuti oleh delapan pengulangan kode berikut:
dengan
BITMAP DATA HERE
diganti dengan 29 byte encoding satu baris font.sumber
8086 Kode Mesin
190 Bytes (122 Bytes menggunakan BIOS)
Inilah file BaseX yang dikodekan oleh WinXP / MSDos .COM:
(Gunakan sesuatu seperti ini ) untuk memecahkan kode teks dan simpan sebagai "pbm.com". Kemudian, pada prompt perintah, ketik:
Saya sudah menguji ini pada mesin WinXP saya menggunakan prompt perintah standar dan DosBox V0.74.
MEMPERBARUI
Versi ini adalah 190 byte dan menggunakan font kecil Ilmari Karonen (tidak ada akses bios di sini!): -
sumber
puts
di Ruby adalah perpustakaan eksternal. Ya, itu memang menggunakan font bios, diakses melalui pointer derefence (tidak adaload
operasi untuk mendapatkan font ke dalam RAM). Membengkokkan aturan terlalu jauh mungkin. Saya akan lolos begitu saja kalau bukan karena anak-anak sial ;-)Skrip shell (kode + data = 295 karakter)
Saya harap tail, gzip, dan dd tidak dihitung sebagai "perpustakaan eksternal." Jalankan sebagai
echo -n 'YOUR TEXT HERE' | ./text.sh > out.pbm
. Font yang saya gunakan adalah Small Fonts ukuran 7.5, walaupun saya memang harus memotong descender dari Q.Contoh output
Kode (137 karakter)
Script lengkap
(gunakan
xxd -r
untuk membuat ulang file asli)Penjelasan
od
adalah program utilitas standar "octal dump". The-tu1
pilihan mengatakan itu untuk menghasilkan dump desimal byte individu, bukan (solusi yang cukup karena kurangnya bash dari bawah ke atas (), Ord (), .charCodeAt (), dll)P4
adalah angka ajaib untuk file PBM format biner, yang mengemas delapan piksel ke dalam setiap byte (dibandingkanP1
dengan file PBM format ASCII). Anda akan melihat bagaimana ini terbukti bermanfaat.dd
. (tail -2 $0
mengekstrak dua baris terakhir skrip; data yang dikompresi mencakup satu byte linefeed 0x0a.) Kebetulan delapan piksel adalah lebar karakter tunggal. Bytes nol yang mengisi celah antara karakter yang didukung mudah dikompres karena semuanya sama.wc -c
mencetak nama file input "8" setelah jumlah byte-nya.sumber
Python 2,
248247 byteMenggunakan font 3x5, dikemas dalam string yang dapat dicetak, 3 byte per karakter. Font jelas terbaca, meskipun n adalah huruf kecil dan v mungkin keliru untuk au jika tidak terlihat dalam konteks.
Ukuran sebenarnya:
Zoom x3:
Outputnya adalah tipe P1 PBM, sesuai contoh dalam tantangan. Itu adalah tantangan yang menyenangkan.
sumber
Ruby 1.9, 346 byte (122 kode + 224 byte data)
Inilah hasilnya:
(Ini menyenangkan, bukan?)
Font dihasilkan oleh
figlet -f banner -w 1000 $LETTERS
dan skrip ini .Jalankan dengan
echo -n 'CODEGOLF.STACKEXCHANGE.COM!' | ruby script.rb > image.pbm
.Script menghasilkan semua baris dan cukup mencetaknya.
Berikut adalah hexdump (gunakan
xxd -r
):Dibutuhkan 93 byte kode saat menggunakan goruby:
Menggunakan ZLib memangkas ukuran data menjadi 142 byte, bukan 224, tetapi menambahkan 43 byte dalam kode, jadi 307 byte:
Yang memberi total 268 saat menggunakan goruby:
sumber
Java
862826:Ini pendekatan yang berbeda. Saya pikir 'awt' tidak dihitung sebagai lib eksternal.
Dan ungolfed:
Robot adalah cara Jawa yang agak aneh untuk memanggil getPixel. Saya membuat Label dengan alfabet, dan mengukur di mana piksel untuk setiap huruf.
Dalam metode cat,
int py = (y < 3) ? y : y +1;
dan(8*a+x+17+x/4, py+81)
merupakan cara yang rumit, untuk menyesuaikan posisi di font. Huuuh! lain itu akan membutuhkan 9 baris, dan setiap huruf ke-4, ada pixel tambahan secara horizontal. Trial and error membawa saya ke solusi ini.Kemudian header PBM ditulis, dan setiap baris pesan. Pesan diteruskan sebagai judul bingkai.
Itu dia. Bukan kode terpendek, tetapi tidak perlu lukisan font manual.
Mungkin bisa lebih pendek di BeanShell atau Scala.
Dan sekarang - bagaimana tampilannya?
Beberapa zoom diterapkan:
Unzoomed:
Bukan berarti jumlah karakter adalah jumlah karakter dari solusi Perl yang dikocok.
(bermain golf sedikit lebih. Membuat Robot statis, yang menghindari satu deklarasi Pengecualian.)
sumber
eog
(Eye of Gnome) dan tangkapan layar. Saya akan mengunggah versi yang tidak berskalajpg
; mungkin browser Anda menggunakan interpolasi tetangga terdekat :).C ++ TERLALU BESAR UNTUK MENANG
Saya menulis program menggambar PPM berfitur lengkap di C ++, dengan font bitmap saya sendiri. Bahkan menghapus semua fungsi yang tidak perlu itu masih besar dibandingkan dengan jawaban di sini karena definisi untuk font.
Bagaimanapun, ini adalah output untuk HELLO WORLD:
Dan kodenya:
ppmdraw.h
ppmdraw.cpp
main.cpp
Makefile
Jika Anda tertarik, pustaka PPMDraw lengkap ada di sini :
sumber
SmileBASIC, 231 byte
Setiap karakter hanya berisi 2 pola baris yang berbeda, dipilih dari "palet" dari 8 kombinasi. Data untuk setiap simbol disimpan dalam 1 byte, dengan palet disimpan secara terpisah.
sumber