Input akan terdiri dari karakter berikut:
^
: Naik satuv
: Turun satu▲
atauk
: Naik dua▼
atauj
: Turun dua
Misalnya, input berikut:
^^▲^v▼▲^^v
akan menghasilkan output berikut:
^
^ ^ v
▲ v ▲
^ ▼
^
Urutan melarikan diri yang menggerakkan kursor seperti \e[B
tidak diizinkan. Anda harus menghasilkan output menggunakan spasi dan baris baru.
Berikut adalah beberapa kasus uji lagi.
▲v^v^v^v^v^v^v^v▲
▲
▲ ^ ^ ^ ^ ^ ^ ^
v v v v v v v v
^^^^^^^▲▲▲▼▼▼vvvvvv
▲
▲ ▼
▲ ▼
^ ▼
^ v
^ v
^ v
^ v
^ v
^ v
v^^vv^^vvv^v^v^^^vvvv^^v^^vv
^ ^ ^
^ v ^ v ^ v ^
v v v ^ ^ ^ v ^ ^ v
v v v v ^ v v
v
j
untuk turun dua kali dank
untuk naik dua kali juga.Jawaban:
Pyth, 27 byte
Cobalah online: Demonstrasi atau Test Suite
Saya menggunakan
k
danj
bukannya▲
dan▼
. Ada banyak baris kosong terkemuka dan tertinggal. Anda harus mencari sedikit untuk menemukan gambar. Berikut ini adalah versi 34 byte , yang menghapus semua baris kosong awal dan akhir.Cobalah online: Demonstrasi atau Test Suite
Penjelasan:
sumber
Tidak dapat dibaca ,
219921452134210420872084 byteMendukung baik
k
/j
maupun▲
/▼
sintaksis.Dalam tradisi Unreadable yang baik, berikut adalah program yang diformat dalam font proporsional, untuk mengaburkan perbedaan antara tanda kutip dan tanda kutip ganda:
Ini adalah tantangan yang luar biasa. Terima kasih telah mengirim!
Penjelasan
Untuk memahami apa yang bisa dan tidak bisa dilakukan Unreadable, bayangkan Brainfuck dengan pita tak terbatas di kedua arah, tetapi alih-alih penunjuk memori yang memindahkan satu sel pada satu waktu, Anda dapat mengakses sel memori apa pun dengan mendereferensikan penunjuk. Ini sangat berguna dalam solusi ini, meskipun operasi aritmatika lainnya - termasuk modulo - harus dilakukan dengan tangan.
Berikut adalah program sebagai kodesemu dengan komentar sutradara:
Begitu banyak untuk logika program. Sekarang kita perlu menerjemahkan ini ke Tidak Dapat Dibaca dan menggunakan beberapa trik golf yang lebih menarik.
Variabel selalu direferensikan secara numerik dalam Unreadable (misalnya
a = 1
menjadi sesuatu seperti*(1) = 1
). Beberapa literal numerik lebih panjang dari yang lain; yang terpendek adalah 1, diikuti oleh 2, dll. Untuk menunjukkan seberapa jauh angka negatif itu, inilah angka dari -1 hingga 7:Jelas, kami ingin mengalokasikan variabel # 1 ke variabel yang paling sering muncul dalam kode. Di loop sementara pertama, ini pasti
mod5
, yang muncul 10 kali. Tapi kita tidak perlumod5
lagi setelah loop sementara pertama, sehingga kita dapat mengalokasikan kembali lokasi memori yang sama ke variabel lain yang kita gunakan nanti. Iniptr2
danptr3
. Sekarang variabel direferensikan 21 kali secara total. (Jika Anda mencoba menghitung sendiri jumlah kemunculannya, ingatlah untuk menghitung sekitara++
dua kali, satu kali untuk mendapatkan nilai dan satu kali untuk menetapkannya.)Hanya ada satu variabel lain yang bisa kita gunakan kembali; setelah kami menghitung nilai modulo,
ch
tidak lagi diperlukan.up
dandn
muncul jumlah yang sama kali, jadi tidak masalah. Merge Mari kitach
denganup
.Ini menyisakan total 8 variabel unik. Kita dapat mengalokasikan variabel 0 hingga 7 dan kemudian memulai blok memori (berisi karakter dan nomor baris) pada 8. Tapi! Karena 7 panjang kode yang sama dengan −1, kita juga bisa menggunakan variabel −1 hingga 6 dan memulai blok memori pada 7. Dengan cara ini, setiap referensi ke posisi awal blok memori sedikit lebih pendek dalam kode! Ini memberi kita tugas-tugas berikut:
Sekarang ini menjelaskan inisialisasi di bagian paling atas: itu 5 karena itu 7 (awal dari blok memori) minus 2 (kenaikan wajib dalam kondisi sementara pertama). Hal yang sama berlaku untuk dua kejadian lainnya dari 5 di loop terakhir.
Perhatikan bahwa, karena 0 dan 4 memiliki panjang kode yang sama,
ptr
danminLine
dapat dialokasikan dengan cara apa pun. ... Atau bisakah mereka?Bagaimana dengan 2 misterius di loop kedua-terakhir sementara? Bukankah ini seharusnya 6? Kami hanya ingin mengurangi angka dalam blok data, bukan? Begitu kita mencapai 6, kita berada di luar blok data dan kita harus berhenti! Ini akan menjadi kerentanan kesalahan kegagalan buffer overflow kesalahan keamanan!
Nah, pikirkan apa yang terjadi jika kita tidak berhenti. Kami menurunkan variabel 6 dan 4. Variabel 6 adalah
mod4
. Itu hanya digunakan di loop sementara pertama dan tidak lagi diperlukan di sini, jadi tidak ada salahnya dilakukan. Bagaimana dengan variabel 4? Bagaimana menurut Anda, seharusnya variabel 4ptr
atau seharusnyaminLine
? Itu benar,minLine
tidak lagi digunakan pada saat ini juga! Dengan demikian, variabel # 4 adalahminLine
dan kita dapat dengan aman mengurangi dan tidak merusak!PEMBARUAN 1! Golfed 2199-2145 byte dengan menyadari bahwa
dn
bisa juga digabung denganmod5
, meskipunmod5
masih digunakan dalam perhitungan nilai untukdn
! Tugas variabel baru sekarang:PEMBARUAN 2! Ditarik dari 2145 hingga 2134 byte dengan menyadari bahwa, karena
mod5
sekarang berada dalam variabel yang sama dengandn
, yang dihitung hingga 0 dalam loop sementara,mod5
tidak perlu lagi diinisialisasi secara eksplisit ke 0.UPDATE 3! Bermain golf dari 2134 hingga 2104 byte dengan menyadari dua hal. Pertama, meskipun ide "modulo negatif" tidak sia-sia
mod5
, alasan yang sama tidak berlakumod4
karena kami tidak pernah menguji terhadapmod4+2
dll. Oleh karena itu, mengubahmod4 ? mod4+1 : -3
untukmod4 ? mod4-1 : 3
membawa kami ke 2110 byte. Kedua, karenamod4
selalu 0 atau 2, kita dapat menginisialisasimod4
ke 2 bukannya 0 dan membalikkan dua terner (mod4 ? 3 : 1
bukanmod4 ? 1 : 3
).PEMBARUAN 4! Ditarik dari 2104 hingga 2087 byte dengan menyadari bahwa loop sementara yang menghitung nilai modulo selalu berjalan setidaknya sekali, dan dalam kasus seperti itu, Unreadable memungkinkan Anda untuk menggunakan kembali nilai pernyataan terakhir dalam ekspresi lain. Jadi, alih-alih
while --ch: [...]; up = (mod5 ? mod5+1 ? [...]
sekarang kita milikiup = ((while --ch: [...]) ? mod5+1 ? [...]
(dan di dalam loop sementara itu, kita menghitungmod4
dulu, jadi itulahmod5
pernyataan terakhir).UPDATE 5! Ditarik dari 2087 hingga 2084 byte dengan menyadari bahwa alih-alih menuliskan konstanta
32
dan10
(spasi dan baris baru), saya dapat menyimpan angka 10 dalam variabel (sekarang tidak digunakan) variabel # 2 (sebut sajaten
). Alih-alihptr3 = 5
kita menulisten = (ptr3 = 5) + 5
, maka32
menjaditen+22
danprint 10
menjadiprint ten
.sumber
CJam, 37 byte
Ini mencetak baris kosong sebelum dan sesudah output yang diinginkan, yang telah diizinkan oleh OP .
Cobalah online di juru bahasa CJam .
Bagaimana itu bekerja
sumber
Python 2, 102
Mencetak baris demi baris.
Loop melalui karakter dalam input dan melacak ketinggian saat ini. Ketinggian diperbarui oleh salah satu
+2, +1, -1, -2
seperti yang dihitung oleh'kv_^j'.find(c)-2
. Mungkin ada rantai mod yang lebih pendekKetika ketinggian saat ini sama dengan nomor baris (yang bisa negatif), kami menambahkan karakter saat ini ke garis, dan jika tidak menambahkan spasi. Kemudian, kami mencetak garis. Sebenarnya, ini lebih pendek untuk memulai ketinggian pada nomor baris saat ini dan mengurangi perubahan tinggi, menambahkan karakter ketika nilainya menyentuh
0
.Nomor garis mencakup rentang yang cukup besar sehingga urutan naik-dua atau turun-dua akan tetap di dalamnya. Sebenarnya, ada jumlah berlebih yang baik. Jika kita memiliki batas atas pada panjang input, akan lebih pendek untuk menulis, katakanlah
j=999
.Anehnya,
i and' 'or c
lebih pendek dari biasanya[' ',c][i==0]
. Catatan yangi
bisa negatif, yang memotong beberapa trik biasa.sumber
MATLAB, 116
Ini awal. The
j
dank
membuat rasa sakit di leher karena saya tidak dapat menemukan cara untuk matematis peta darij^vk
ke[-2 -1 1 2]
dan dengan MATLAB tidak mengakui Unicode (rupanya kedua atas dan bawah memiliki nilai 26 pada gambar MATLAB. Go!), Ada banyak byte yang terbuang untuk melakukan pemetaan.Dengan menggambar inspirasi dari solusi @xnors, kode dapat dikurangi dengan 14 karakter lain dengan memetakan karakter kontrol di dalam for loop.
Ada juga banyak byte yang terbuang untuk mencoba menghitung jika string input mengirim pola kembali ke bawah indeks di mana ia mulai (mungkin jika ada batas pada panjang string saya bisa menyederhanakan bit itu).
Dan dalam bentuk yang mudah dibaca:
sumber
b=[-2 -1 1 2](a==[106 107 94 118])
bekerja Ia bekerja di oktaf. Atau bahkanb=[-2 -1 1 2](a-94==[12 13 0 24])
jika Anda ingin memotong satu byte lagi!==
berhenti yang berfungsi, dan juga di MATLAB Anda tidak dapat menempatkan()
setelah[]
.+=
, fwiw.)JavaScript (ES6), 140
Tes menjalankan cuplikan di bawah ini di peramban yang mendukung EcmaScript 6 (diuji pada Firefox).
sumber
GS2, 34 byte
Yang ini dengan benar menghitung batas output sehingga tidak ada spasi kosong yang dihasilkan. Inilah solusi saya dalam hex
Ada sedikit penjelasan. Pada stack kita memiliki input pengguna sebagai array kode ascii. Program dimulai dalam string literal karena
05
. Kita mulai.GS2, 24 byte
Saya juga memiliki solusi 24 byte yang tidak terlalu peduli menghitung ukuran output, dan berakhir dengan spasi tambahan. Saya lebih suka yang dengan spasi putih tetap minimum.
sumber
Crayon , 13 byte (tidak bersaing)
Cobalah online! Gunakan panah asli karena mengapa tidak.
Non-bersaing karena Crayon jauh lebih baru daripada tantangan ini.
Bagaimana itu bekerja
Crayon adalah bahasa berbasis tumpukan yang dirancang untuk menjadi pembunuh di tantangan ASCII-art. Itu dibangun di sekitar dasar "kanvas" keluaran 2-dimensi, dan "krayon", kursor yang bergerak di sekitar kanvas ini. Apa pun yang dikirim ke output digambar di atas kanvas di posisi krayon, dan ke arah krayon menghadap. Secara default, krayon menunjuk ke Timur (ke kanan).
sumber
pb - 136 byte
Penggunaan
k
danj
bukan▲
dan▼
.Beberapa catatan:
Escape sequences that move the cursor such as \e[B are not allowed. You must produce the output using spaces and newlines.
Saya mengikuti aturan ini! pb menggunakan konsep "kuas" untuk menghasilkan karakter. Kuas bergerak di sekitar "kanvas" dan dapat mencetak karakter tepat di bawahnya. Namun, implementasi aktual mencetak karakter menggunakan spasi dan baris baru.You are allowed trailing spaces and/or empty lines
. Ini karena beberapa alasan:n
mulai dariY=3n+1
. Ini-1
karena turun3n
dariY=-1
, dan mulaiY=2n-1
gagal untuk input semuak
.Anda dapat menonton program ini beraksi di YouTube! Versi ini sedikit dimodifikasi sehingga hanya turun ke
n-1
. Ini berfungsi untuk input ini, tetapi akan gagal untuk orang lain. Namun, hasilnya jauh lebih bagus.Dengan komentar:
sumber
Ceylon, 447 byte
Atau dengan jeda baris untuk "keterbacaan":
import ceylon.language{o=null,v=variable,s=shared}s void y(){v L c;v L f;v L l;v Integer i=0;class L(v L?p,v L?n){s v String t="";s L u=>p else(f=p=L(o,this));s L d=>n else(l=n=L(this,o));s void a(Character c)=>t=t+" ".repeat(i-t.size)+c.string;}f=l=c=L(o,o);for(x in process.readLine()else""){switch(x)case('^'){c=c.u;}case('v'){c=c.d;}case('▲'|'k'){c=c.u.u;}case('▼'|'j'){c=c.d.d;}else{}c.a(x);i++;}print(f.t);while(f!=l){f=f.d;print(f.t);}}
Ini berfungsi baik dengan input ▲ / ▼ dan j / k (Jika kita harus mendukung salah satunya saja, program akan lebih pendek 8 byte). Baris keluaran terakhir kosong ketika posisi awal berada di atasnya (yaitu input pertama adalah a
▲
dan^
dan kami tidak pernah mendapatkan di bawah itu lagi nanti). Input yang bukan merupakan salah satu karakter yang ditentukan hanya akan dicetak apa adanya, tanpa beralih baris:→
Ini adalah versi yang diformat (753 bytes):
Ini adalah program "berorientasi objek" yang hampir langsung ... kelas (lokal)
L
(penyangga baris) menyimpan satu baris teks (dalamt
), dan juga (nullable) pointer ke penunjuk berikutnya (n
) dan sebelumnya (p
) baris. Atribut (tidak nullable)u
(untuk atas) dand
(untuk turun) menginisialisasi mereka jika diperlukan (dengan pointer terbalik ke dirinya sendiri), dan dalam hal ini juga melacak keseluruhan baris pertama dan terakhir (dalamf
danl
variabel).Metode
a
(tambahkan) menambahkan karakter ke baris ini, termasuk beberapa ruang yang pada akhirnya diperlukan.c
adalah baris saat ini. Kami mengurai string input (menggunakanreadLine
sebagai input harus pada satu baris) menggunakan pernyataan switch yang memperbarui baris saat ini, dan kemudian memanggil metode append.Setelah penguraian selesai, kita beralih pada garis dari yang pertama hingga yang terakhir, mencetak masing-masing. (Ini menghancurkan
f
pointer, jika diperlukan setelah itu, kita harus menggunakan variabel terpisah untuk ini.)Beberapa trik yang digunakan untuk bermain golf:
Beberapa hal yang dalam bahasa lain akan menjadi kata kunci sebenarnya hanya pengidentifikasi dalam
ceylon.language
paket, dan dapat diubah namanya dengan impor alias - kami menggunakan ini untuk anotasishared
(digunakan 5 ×) danvariable
(digunakan 6 ×), serta untuk objeknull
(digunakan 4 ×):(Trivia: Formatter dalam Ceylon IDE memformat beberapa anotasi bahasa bawaan, di antara mereka
variable
danshared
, dengan menempatkannya pada baris yang sama dengan deklarasi beranotasi, berbeda dengan anotasi khusus, yang diletakkan pada baris terpisah di atas deklarasi. Ini membuat versi program golf yang diformat tidak dapat dibaca, oleh karena itu saya mengubah alias-impor kembali untuk versi ini.)this
,void
,case
,else
Adalah kata kunci yang sebenarnya dan tidak dapat diganti dengan cara ini, danInteger
,String
danCharacter
muncul hanya sekali masing-masing, sehingga tidak ada yang bisa diperoleh dengan mengimpor.Awalnya saya juga memiliki kelas ScreenBuffer yang terpisah (yang melacak daftar buffer baris yang terhubung, indeks saat ini, dan sebagainya), tetapi karena hanya ada satu objek saja, itu dioptimalkan jauh.
Itu kelas Screenbuffer juga memiliki
up
dandown
metode, yang dipanggil dari parser (dan hanya melakukancurrentLine = currentLine.up
masing - masingcurrentLine = currentLine.down
). Ini menunjukkan bahwa melakukan hal ini secara langsung di sakelar pengurai lebih pendek. Itu juga diizinkan untuk menuliscurrentLine = currentLine.up.up
(yang kemudian menjadic = c.u.u
) alih-alihcurrentLine = currentLine.up;currentLine = currentLine.up
.Awalnya kami memang melewatkan indeks saat ini sebagai argumen ke dalam metode append (dan bahkan ke parser dari loop) - memiliki variabel dalam fungsi yang berisi lebih pendek.
Awalnya metode printAll saya menggunakan pointer saat ini dan memindahkannya terlebih dahulu sampai baris saat ini kosong, dan kemudian turun saat mencetak setiap baris. Ini pecah ketika menggunakan ▲ dan ▼ untuk melompati garis, jadi kami harus secara eksplisit menambahkan sesuatu di garis melompat itu. Melacak baris pertama / terakhir terbukti lebih mudah (meskipun perlu menggunakan dua pernyataan cetak, karena tidak ada loop do-while-do di Ceylon).
Awalnya saya punya sesuatu seperti ini:
process.readLine
kembalinull
jika tidak ada baris yang dapat dibaca (karena input telah ditutup), dan kompiler Ceylon mengharuskan saya untuk memeriksa sebelum saya mengaksesinput
. Seperti dalam kasus ini saya tidak ingin melakukan apa-apa, saya bisa menggunakanelse
operator yang mengembalikan argumen pertama jika bukan nol, dan sebaliknya argumen kedua, menyimpan variabel dan pernyataan-if. (Ini juga akan memungkinkan kami untuk mengkodekan input default untuk menguji:for (x in process.readLine() else "^^▲^v▼▲^^v") {
)sumber
JavaScript (ES6), 228 byte
Nah, berikut ini adalah solusi rekursif (agak panjang) yang melewati semua test case yang diberikan. Itu tantangan yang bagus. Ini menggunakan
k
danj
menggantikan▼
dan▲
.Cuplikan Tes
Meskipun pengiriman itu sendiri hanya dapat menangani
k,j
, cuplikan berikut dapat menangani keduanyak,j
dan▼,▲
.sumber