<
,,}:?
.
;(" {(={}{".
,",;=};} }) "{@
Input N
diikuti oleh string, dipisahkan oleh karakter non-numerik.
Cobalah online!
Ini ditulis bekerja sama dengan Sp3000 (yang berarti saya tidak bisa diganggu untuk mencari tahu algoritma, jadi dia mulai bekerja pada itu, datang dengan solusi 118 byte tetapi tidak dapat diganggu golf itu, jadi saya melakukan golf. .. yay untuk kerja tim).
Penjelasan
Primer biasa Sp (seperti biasa sedikit dimodifikasi):
- Labyrinth adalah bahasa 2D berbasis stack dengan dua tumpukan, utama dan tambahan. Hampir semua yang terjadi pada tumpukan utama, tetapi Anda dapat menggeser nilainya ke yang lain, misalnya untuk membalikkan atau menyimpannya untuk nanti.
- Tumpukan tidak berdasar dan diisi dengan nol, sehingga muncul dari tumpukan kosong bukanlah kesalahan.
- Eksekusi dimulai dari karakter valid pertama (di sini kiri atas). Di setiap persimpangan, di mana ada dua atau lebih jalur yang mungkin untuk mengambil penunjuk instruksi (IP), bagian atas tumpukan diperiksa untuk menentukan ke mana harus pergi berikutnya. Negatif belok kiri, nol maju dan positif belok kanan. Meskipun ini dimaksudkan untuk membuat kode terlihat seperti lilitan, bagian yang berkelok-kelok, tidak ada yang menghentikan Anda dari membuat "kamar" di mana kondisi ini diperiksa di setiap sel. Itu bisa menghasilkan perilaku yang tidak terduga, tetapi bagus untuk bermain golf.
- Kode sumber (dan karenanya tata letak labirin) dapat dimodifikasi pada saat runtime menggunakan
<>^v
yang secara siklis menggeser baris atau kolom atau kisi.
"
adalah no-ops.
Kita mulai.
Kode dimulai pada <
, yang merupakan trik golf yang saya gunakan beberapa kali ketika mulai dengan sepotong kode linier yang panjang. Ini menggeser baris pertama secara siklis ke kiri, dengan IP di atasnya , sehingga sumbernya akan terlihat seperti ini:
<
,,}:?
.
;(" {(={}{".
,",;=};} }) "{@
Tapi sekarang IP tidak bisa bergerak kemana-mana, jadi dieksekusi <
lagi. Ini berlanjut sampai kita mencapai keadaan ini:
<
,,}:?
.
;(" {(={}{".
,",;=};} }) "{@
Pada titik ini, IP dapat meninggalkan sel dan mulai menjalankan baris kedua mulai dari ?
. Jadi, inilah kode liniernya:
? # Read the first integer on STDIN, i.e. N.
:} # Duplicate it and move one copy over to the auxiliary stack.
, # Read the separator character.
,. # Read the first character of the input string and directly print it.
IP sekarang memasuki ruangan 3x2 ini, yang sebenarnya adalah dua loop 2x searah jarum jam terkompresi (tumpang tindih). Loop pertama membaca dan membuang N-1
karakter dari STDIN.
; # Discard the top of the stack. On the first iteration, this is the
# separator we've already read. On subsequent iterations this will be
# one of the N-1 characters from the input string.
( # Decrement N. If this hits zero, we leave the loop, otherwise we continue.
, # Read the next character from STDIN to be discarded.
Sekarang kita memasuki loop kedua yang membaca sisa dari string input. Kami dapat mendeteksi EOF karena ,
akan kembali -1
dalam kasus itu, membuat IP berbelok ke kiri.
, # Read a character. Exit the loop if EOF.
( # Decrement it.
Penurunan itu sebenarnya tidak berguna, tetapi kita dapat membatalkannya nanti secara gratis dan di sini memungkinkan kita untuk tumpang tindih dua loop.
Jika kita mengambil 5 ABCDEFGHIJKLMNOP
input sebagai contoh, tumpukan terlihat seperti ini:
Main [ ... 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' -1 | 5 ... ] Auxiliary
Perhatikan bahwa ini benar-benar sesuai dengan karakter input FGHIJKLMNOP
(karena kami menurunkannya), dan bahwa kami sebenarnya tidak ingin mencetak yang pertama (kami hanya membuang N-1
karakter, tetapi ingin melompati N
).
Sekarang ada bit linear pendek yang menyiapkan stack untuk loop berikutnya:
; # Discard the -1.
= # Swap the tops of the stacks, i.e. N with the last character.
# By putting the last character on the auxiliary stack, we ensure that
# it doesn't get discarded in the next loop.
} # Move N over to the auxiliary stack as well.
Tumpukan sekarang terlihat seperti:
Main [ ... 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' | 5 'O' ... ] Auxiliary
Kami memasukkan loop 2x2 searah jarum jam. Ini membuang N
karakter teratas dari tumpukan utama:
; # Discard the top of the main stack.
{ # Pull N over from the auxiliary stack.
( # Decrement it. It it's 0 we leave the loop.
} # Push N back to the auxiliary stack.
Ketika kita keluar dari loop, =
swap itu 0
dan karakter terakhir dari string input lagi. Sekarang tumpukannya terlihat seperti ini:
Main [ ... 'E' 'F' 'G' 'H' 'I' 'O' | ... ] Auxiliary
Kami ingin mencetak isi tumpukan utama (kecuali elemen bawah dan semuanya bertambah 1), dari kiri . Itu berarti kita harus membawanya ke tumpukan tambahan. Itulah yang dilakukan loop 2x2 (searah jarum jam) berikutnya:
{ # Pull an element over from the auxiliary stack. This is necessary so we
# have a 0 on top of the stack when entering the loop, to prevent the IP
# from turning right immediately.
} # Move the top of the main stack back to the auxiliary stack. If this was the
# bottom of the stack, exit the loop.
) # Increment the current character.
} # Move it over to the auxiliary stack.
Tumpukan sekarang:
Main [ ... | 'F' 'G' 'H' 'I' 'J' 'P] ... ] Auxiliary
Kami memindahkan yang pertama (yang tidak ingin kita cetak) kembali ke tumpukan utama {
. Dan sekarang kita memasuki loop 2x2 akhir ( berlawanan arah jarum jam ), yang mencetak sisanya:
{ # Pull another character over from the auxiliary stack. Exit the loop
# if that's the zero at the bottom of the stack.
. # Print the character.
Akhirnya kami mengakhiri program dengan @
.
'
sebagai karakter penghitungan? Sebagai contoh:''123321
?