Intro
Jadi saya sudah membuang-buang waktu lagi meneliti algoritma penyortiran suffix, mengevaluasi ide-ide baru dengan tangan dan dalam kode. Tapi saya selalu berjuang untuk mengingat tipe sufiks saya! Bisakah Anda memberi tahu saya tipe sufiks yang mana?
Paling kiri apa?
Banyak algoritma penyortiran sufiks (SAIS, KA, saya sendiri yang tahu) sufiks menjadi tipe yang berbeda untuk mengurutkannya. Ada dua tipe dasar: sufiks tipe- S dan tipe - L . Sufiks tipe-S adalah sufiks yang secara leksikografis lebih sedikit ( S maller) daripada sufiks berikut dan tipe-L jika sufiksnya lebih besar ( L arger). Sebuah kiri-paling S-type ( LMS-jenis ) hanya itu: A S-jenis akhiran yang diawali dengan L-jenis akhiran.
Hal khusus tentang sufiks tipe-LMS ini adalah bahwa begitu kami mengurutkannya, kami dapat mengurutkan semua sufiks lain dalam waktu linier! Bukankah itu luar biasa?
Tantangan
Diberikan string menganggap itu diakhiri oleh karakter khusus yang kurang dari karakter lain dalam string itu (misalnya lebih kecil daripada byte nol). Keluarkan jenis corrosponding char untuk setiap suffix.
Anda dapat dengan bebas memilih char digunakan untuk jenis tapi aku lebih suka L, S and *
untuk L-, S- and LMS-type
selama mereka semua dicetak ( 0x20 - 0x7E
).
Contoh
Diberikan mmiissiissiippi
keluaran string (saat menggunakan L, S and *
):
LL*SLL*SLL*SLLL
Misalnya yang pertama L
adalah karena fakta yang mmiissiissiippi$
secara leksikografis lebih besar dari miissiissiippi$
(yang $
mewakili karakter minimal yang ditambahkan):
L - mmiissiissiippi$ > miissiissiippi$
L - miissiissiippi$ > iissiissiippi$
* - iissiissiippi$ < issiissiippi and preceeded by L
S - issiissiippi$ < ssiissiippi$
L - ssiissiippi$ > siissiippi$
L - siissiippi$ > iissiippi$
* - iissiippi$ < issiippi$ and preceeded by L
S - issiippi$ < ssiippi$
L - ssiippi$ > siippi$
L - siippi$ > iippi$
* - iippi$ < ippi$ and preceeded by L
S - ippi$ < ppi$
L - ppi$ > pi$
L - pi$ > i$
L - i$ > $
Beberapa contoh lagi:
"hello world" -> "L*SSL*L*LLL"
"Hello World" -> "SSSSL*SSLLL"
"53Ab§%5qS" -> "L*SSL*SLL"
Tujuan
Saya di sini bukan untuk mengganggu Peter Cordes (kadang-kadang saya akan melakukan ini di stackoverflow); Saya sangat malas jadi ini tentu saja kode-golf ! Jawaban terpendek dalam byte menang.
Sunting: Urutan karakter diberikan oleh nilai byte mereka. Itu berarti membandingkan harus seperti C strcmp
.
Sunting2: Seperti yang dinyatakan dalam komentar komentar harus berupa karakter tunggal untuk setiap karakter input. Sementara saya berasumsi bahwa itu akan dipahami sebagai "mengembalikan sebuah string" tampaknya setidaknya 1 jawaban mengembalikan daftar karakter tunggal. Agar tidak membatalkan jawaban yang ada, saya akan memungkinkan Anda mengembalikan daftar karakter tunggal (atau bilangan bulat yang bila dicetak hanya menghasilkan 1 karakter).
Kiat untuk waktu linier:
- Ini dapat dilakukan dalam 2 iterasi maju paralel atau dalam satu iterasi mundur tunggal.
- Keadaan masing-masing sufiks hanya bergantung pada 2 karakter pertama dan tipe yang kedua.
- Memindai input dalam arah terbalik, Anda dapat menentukan L atau S seperti ini:
$t=$c<=>$d?:$t
(PHP 7), di mana$c
karakter saat ini$d
tipe sebelumnya dan$t
sebelumnya. - Lihat jawaban PHP saya . Besok aku akan menghadiahkan hadiah itu.
c++
string gaya. Anggap saja sebagai data biner.*
artinya*
berarti sufiks yang sesuai adalah tipeleft most s-type
.A S-type suffix that is preceeded by a L-type suffix.
.Jawaban:
Haskell ,
64534842 byteCobalah online!
Tidak disatukan, dengan
Char
alih - alihInt
:sumber
z=
dapat dihapus.go
fungsi ini membutuhkan dua argumen. Yang pertama adalah karakter yang mewakili apa yang harus digunakan untuk menggambarkanS
situasi. Yang kedua adalah string. Ini melewati string itu secara rekursif, menghapus karakter pertama di setiap langkah (itulah yangtail
dilakukan). Kuncinya adalah bahwa argumen pertama diatur*
ketika hasil sebelumnya adalahL
, atauS
sebaliknya. Dengan begitu, dalam kasus di mana suatu*
atauS
harus digunakan, argumen pertama itu dapat digunakan secara langsung. Harapan itu masuk akal.Jelly ,
25 23 21 2019 byteProgram lengkap yang mencetak daftar karakter, menggunakan:
(Sebagai tautan, ia mengembalikan daftar di mana semua item adalah karakter kecuali yang terakhir, yang merupakan nol.)
Cobalah online! atau lihat paket tes (dengan konversi ke
LS*
).Bagaimana?
sumber
+
pada string tampaknya vectorise tetapi hasilnya mendasari tidak benar-benar Jelly iterables tapi string (misalnya mencoba (!)+@/L€
Atau+@/L€€
atau ...)+
menghasilkan string yang sebenarnya. Ini adalah fitur tidak berdokumen, atau apa yang Anda sebut bug.Python 3,
9287746965 bytePenggunaan
0
untukL
,1
untukS
, dan2
untuk*
. Bungkus string input dalam karakter kutipan; Saya percaya ini diizinkan oleh konvensi.Cobalah online!
Contoh penggunaan:
disimpan 5 byte berkat Leaky Nun, 4 byte terima kasih untuk Ovs
sumber
JavaScript (ES6),
5145 byteDisimpan 6 byte berkat @Neil.
Solusi rekursif untuk latihan ini.
sumber
f=(c,d)=>c&&(d<(d=c<(c=c.slice(1))))+d+f(c,d)
JavaScript (ES6), 52 byte
Jawaban Port of L3viathan.
sumber
c=1
sebagaic=0
...C (dentang) , 88 byte
Cobalah online!
sumber
Haskell ,
7775 byte, waktu linierCobalah online!
Bagaimana itu bekerja
Ini menggunakan rekursi, menanggalkan satu karakter pada satu waktu dari awal string. (Jenis string Haskell adalah daftar karakter yang terhubung secara tunggal, sehingga setiap langkah ini adalah waktu yang konstan.)
sumber
S, L and *
?[1,1,2,0,1,1,2,0,1,1,2,0,1,1,1]
adalah daftar nomor satu digit, bukan daftar karakter tunggal. Dalam kasus saya, saya pikir mengeluarkan daftar angka tidak akan menyelamatkan saya byte.Python 2 ,
6555 byteVersi rekursif, berdasarkan jawaban L3viathan , menggunakan
012
sebagaiLS*
:Cobalah online!
Python 3 ,
6559 byteSolusi rekursif menggunakan
L
,S
dan*
:Berjalan melalui string dari depan, dan menggantikan semua instance
LS
denganL*
Cobalah online!
sumber
blah if s else''
→s and blah
menyimpan enam byte. Dalam Python 2,str(blah)
→`blah`
menyimpan tiga byte lagi pada solusi kedua.PHP, 82 byte, waktu linier
Berjalan di atas input dari kanan ke kiri dan mengganti setiap karakter dengan tipe.
Menghitung jenis yang diberikan karakter saat ini dan sebelumnya (-1 atau 1). Jika sama jenisnya tidak berubah.
sumber
strtr
PHP , 70 byte
L = 1, S = 0, * = 2
Dukungan Multibyte diperlukan untuk Testcase terakhir dengan
§
+3 Bytesmb_substr
sebagai gantinyasubstr
Cobalah online!
PHP , 71 byte
L = 1, S = 0, * = 2
Cobalah online!
PHP , 74 byte
Cobalah online!
sumber
$s=&$argn
cukup pintar! Saya cukup yakin ada jawaban yang lebih baik;) Semoga seseorang datang dengan itu :)mb_substr
alih-alihsubstr
jika input tidak dalam kisaran ascii sederhana. Apakah perlu untuk mendukung testcase terakhir?§