Ceylon 386 333 252 230 222 216 171 153 131 111
String t(String s,Integer l)=>s.size<l then s else s[0:(s[0:l-2].lastIndexWhere(" -".contains)else l-3)]+"...";
Asli Tidak Disatukan:
String truncate(String text, Integer length) {
if(text.size < length) {
return text;
}
Boolean spacePredicate(Character char) {
return char == ' ' || char == '-';
}
Integer? spaceIndex = text[0:length-2].lastIndexWhere(spacePredicate);
if(exists spaceIndex) {
return text[0:spaceIndex] + "...";
}
return text[0:length-3]+"...";
}
Ini adalah 386 byte / karakter. Beberapa fitur menarik di sini:
The x[y:z]sintaks sintaksis gula untuk x.measure(y, z), dan mengembalikan subrange dari xmulai ydengan panjang z- untuk string, ini adalah substring. (Ada juga x[y..z]sintaksis, yang merupakan rentang dari indeks y ke z, keduanya inklusif, serta bentang setengah terbuka x[...z]dan x[y...].)
List.lastIndexWheremengambil predikat (yaitu fungsi mengambil elemen daftar dan mengembalikan boolean, yaitu di sini a Callable<Boolean, [Character]>), dan memberikan indeks elemen daftar terakhir tempat predikat terpenuhi (atau nol, jika tidak pernah terpenuhi). Karena string adalah daftar, ini juga berfungsi untuk string.
Hasil dari ini, spaceIndexadalah tipe Integer|Null, atau Integer?untuk pendek - yaitu dapat berupa Integer atau null(satu-satunya nilai tipe Null). (Nama itu spaceIndexberasal dari ketika saya tidak menyadari bahwa -itu juga istimewa - saya kira breakIndexakan lebih baik.)
Dengan exists spaceIndexkita dapat memeriksa apakah spaceIndexitu nol, dan kemudian melakukan sesuatu yang berbeda. (Di dalam ini jika-blok kompiler tahu bahwa itu bukan nol ... tanpa itu akan mengeluh jika saya digunakan spaceIndexuntuk mengakses string.)
Alih-alih fungsi lokal spacePredicatekami juga dapat menggunakan fungsi anonim
(Character char) => char == ' ' || char == '-'
Ini membawa kita ke 333 karakter:
String truncate(String text, Integer length) {
if(text.size < length) {
return text;
}
Integer? spaceIndex = text[0:length-2].lastIndexWhere(
(Character char) => char == ' ' || char == '-');
if(exists spaceIndex) {
return text[0:spaceIndex] + "...";
}
return text[0:length-3]+"...";
}
Optimalisasi selanjutnya adalah menggunakan nama variabel dan fungsi yang lebih pendek, yang menurunkan kita sebesar 81 byte menjadi 252:
String t(String s, Integer l) {
if(s.size < l) {
return s;
}
Integer? i = s[0:l-2].lastIndexWhere(
(Character e) => e == ' ' || e == '-');
if(exists i) {
return s[0:i] + "...";
}
return s[0:l-3]+"...";
}
Fungsi predikat sebenarnya tidak perlu tipe argumennya dideklarasikan, yang dapat disimpulkan oleh kompiler. Sama untuk jenis i(di mana kita masih harus menulis valueuntuk menandainya sebagai deklarasi). Sekarang deklarasi itu cukup pendek untuk muat pada satu baris, membawa kita ke 230:
String t(String s, Integer l) {
if(s.size < l) {
return s;
}
value i = s[0:l-2].lastIndexWhere((e) => e == ' ' || e == '-');
if(exists i) {
return s[0:i] + "...";
}
return s[0:l-3]+"...";
}
Alih-alih e == ' ' || e == '-'kita juga dapat menulis e in [' ', '-'](atau e in {' ', '-'}, ini adalah konstruktor yang dapat diubah bukan yang tuple). The inOperator peta dengan metode Category.contains, yang membawa kita ke gagasan bahwa kita dapat melewati bahwa tuple ini containsmetode langsung (itu adalah callable mengambil objek apapun, sehingga juga menerima karakter), tanpa (e) => ...boilerplate (222 bytes):
String t(String s, Integer l) {
if(s.size < l) {
return s;
}
value i = s[0:l-2].lastIndexWhere([' ', '-'].contains);
if(exists i) {
return s[0:i] + "...";
}
return s[0:l-3]+"...";
}
Sebenarnya, kategori lain yang mengandung dua karakter yang sama adalah string dua karakter " -". (Selain itu juga mengandung substringnya, tapi tidak ada salahnya di sini). 216 byte.
String t(String s, Integer l) {
if(s.size < l) {
return s;
}
value i = s[0:l-2].lastIndexWhere(" -".contains);
if(exists i) {
return s[0:i] + "...";
}
return s[0:l-3]+"...";
}
Saya kira kita mendapatkan yang terbaik dari baris ini, mari kita beralih ke yang lain ... dua pernyataan pengembalian terakhir memiliki beberapa kesamaan yang dapat kita eksploitasi - mereka hanya berbeda dalam ivs l-3, dan menggunakan itepat ketika itu bukan nol, jika tidak l-3. Untungnya inilah yang elsedibuat untuk operator!
String t(String s, Integer l) {
if(s.size < l) {
return s;
}
value i = s[0:l-2].lastIndexWhere(" -".contains);
return s[0:(i else l-3)] + "...";
}
(Kurung tampaknya diperlukan di sini, karena elsememiliki prioritas lebih rendah daripada [:].) Ini adalah 171 karakter. Sekarang idigunakan hanya sekali, jadi kita bisa inline itu, membawa kita ke 153 karakter:
String t(String s, Integer l) {
if(s.size < l) {
return s;
}
return s[0:(s[0:l-2].lastIndexWhere(" -".contains) else l-3)] + "...";
}
Kami juga dapat mengganti if-return-returnkombinasi ini dengan kombinasi operator thendan elsedalam satu return. ( thenpengembalian adalah operan kedua ketika yang pertama benar, jika tidak nol, yang kemudian memungkinkan elseuntuk mengembalikan operan kedua.`) 131 byte (meskipun beberapa penghematan adalah ruang putih yang akan kita singkirkan):
String t(String s, Integer l) {
return s.size < l then s else s[0:(s[0:l-2].lastIndexWhere(" -".contains) else l-3)] + "...";
}
Fungsi yang berisi hanya satu pengembalian dengan ekspresi alternatifnya dapat ditulis dengan notasi "panah gemuk", memberikan 123:
String t(String s, Integer l) =>
s.size < l then s else s[0:(s[0:l-2].lastIndexWhere(" -".contains) else l-3)] + "...";
Menghapus spasi kosong yang tidak dibutuhkan memberi kita 111 byte terakhir:
String t(String s,Integer l)=>s.size<l then s else s[0:(s[0:l-2].lastIndexWhere(" -".contains)else l-3)]+"...";
Sebagai tambahan, berikut adalah fungsi yang mencetak contoh-contoh dari pertanyaan (menggunakan nama tyang digunakan setelah langkah kedua):
shared void testTruncate() {
value testInputs = {
["This is some very long text.", 25],
["This-is-some-long-hyphen-separated-text.", 33],
["Programming Puzzles & Code Golf is a question and answer site for programming puzzle enthusiasts and code golfers.", 55],
["abcdefghijklmnopqrstuvwxyz", 20],
["a b c", 4],
["Very long.", 100]
};
for(input in testInputs) {
print(t(*input));
}
}