Ceylon, 1431 , 764 , 697 , 571 , 547 , 538 , 501 , 493 , 467 , 451
shared void p(){print(sum{0,if(exists a=process.arguments[0])if(a!="test")for(c in a)for(b in 0..7)if(c.hash.get(b))1});}
Ini yang asli, tidak diserang:
Integer footprintCharacter(Integer b) {
return sum({0, for(i in 0..7) if(b.get(i)) 1 });
}
Integer footPrintString(String s) {
if(s == "test") {return 0;}
return sum({0, for(c in s) footprintCharacter(c.integer)});
}
shared void footprint() {
if(exists s = process.arguments[0]) {
print(footPrintString(s));
} else {
print("This program needs at least one parameter!");
}
}
Ini mengambil argumen dari parameter baris perintah ... process.arguments adalah urutan string (mungkin kosong), jadi sebelum menggunakan salah satunya, kita perlu memeriksa apakah itu benar-benar ada. Dalam kasus lain kami menampilkan pesan kesalahan (ini tidak diperlukan oleh pertanyaan dan akan dibuang di versi berikutnya).
sum
Fungsi Ceylon mengambil elemen Iterable yang tidak kosong dari beberapa jenis yang perlu dipenuhi Summable
, yaitu memiliki plus
metode, seperti Integer. (Itu tidak bekerja dengan urutan kosong karena setiap tipe Summable akan memiliki nol sendiri, dan runtime tidak memiliki kesempatan untuk mengetahui yang mana yang dimaksudkan.)
Elemen-elemen string, atau satu bit integer, bukan iterable yang tidak kosong. Oleh karena itu kami menggunakan fitur ini untuk membangun iterable dengan menentukan beberapa elemen, lalu "pemahaman" (yang akan dievaluasi menjadi nol atau lebih elemen). Jadi dalam case karakter kita menambahkan yang (tetapi hanya ketika bit yang sesuai diatur), dalam case string kita menambahkan hasil dari karakter. (Pemahaman hanya akan dievaluasi ketika fungsi penerima benar-benar beralih di atasnya, bukan ketika membangun Iterable.)
Mari kita lihat bagaimana kita bisa mengecilkan ini. Pertama, masing-masing fungsi hanya dipanggil di satu tempat, jadi kita bisa sebarisinya. Juga, seperti disebutkan di atas, singkirkan pesan kesalahan. (764 titik jejak.)
shared void footprint() {
if (exists s = process.arguments[0]) {
if (s == "test") {
print(0);
} else {
print(sum({ 0, for (c in s) sum({ 0, for (i in 0..7) if (c.integer.get(i)) 1 }) }));
}
}
}
Kita tidak benar-benar membutuhkan sarang dalam sum
, kita bisa membuat pemahaman yang besar ini. (Ini menghemat kami untuk 37 titik jejak kaki sum({0,})
, dan beberapa lagi untuk spasi putih, yang akan dihilangkan pada akhirnya.) Ini adalah 697:
shared void footprint() {
if (exists s = process.arguments[0]) {
if (s == "test") {
print(0);
} else {
print(sum({ 0, for (c in s) for (i in 0..7) if (c.integer.get(i)) 1 }));
}
}
}
Kita dapat menerapkan prinsip yang mirip dengan "test"
string cased khusus : seperti dalam kasus ini hasilnya adalah 0 (yaitu tidak ada yang berkontribusi pada penjumlahan), kita dapat melakukan ini sebagai bagian dari penjumlahan (tetapi kita harus membalikkan kondisinya) . Ini terutama menyelamatkan kita print(0);
, beberapa kawat gigi dan sekelompok ruang lekukan, turun ke jejak 571:
shared void footprint() {
if (exists s = process.arguments[0]) {
print(sum({ 0, if (s != "test") for (c in s) for (i in 0..7) if (c.integer.get(i)) 1 }));
}
}
Kami melakukan hal yang sama untuk yang pertama if
, dengan efek samping yang sekarang tidak memberikan argumen juga menghasilkan 0
bukannya melakukan apa-apa. (Setidaknya saya pikir itu akan terjadi di sini, alih-alih sepertinya menggantung dengan loop abadi? Aneh.)
shared void footprint() {
print(sum({ 0, if (exists s = process.arguments[0]) if (s != "test") for (c in s) for (i in 0..7) if (c.integer.get(i)) 1 }));
}
Kita sebenarnya bisa menghilangkan fungsi ()
untuk di sum
sini, menggunakan sintaks pemanggilan fungsi alternatif , yang menggunakan {...}
alih-alih ()
, dan akan mengisi pemahaman menjadi argumen yang dapat diubah. Ini memiliki tapak 538:
shared void footprint() {
print(sum{ 0, if (exists s = process.arguments[0]) if (s != "test") for (c in s) for (i in 0..7) if (c.integer.get(i)) 1 });
}
Mengganti nama fungsi footprint
(40) dengan p
(3) menyimpan 37 poin lagi, membawa kami ke 501. (Nama fungsi Ceylon harus dimulai dengan karakter huruf kecil, jadi kami tidak bisa mendapatkan kurang dari 3 poin di sini.)
shared void p() {
print(sum{ 0, if (exists s = process.arguments[0]) if (s != "test") for (c in s) for (i in 0..7) if (c.integer.get(i)) 1 });
}
Nama variabel s
(5) dan c
(4), i
(4) juga tidak optimal. Mari kita ganti dengan a
(argumen), d
(digit?) Dan b
(bit-index). Jejak 493:
shared void p() {
print(sum{ 0, if (exists a = process.arguments[0]) if (a != "test") for (c in a) for (b in 0..7) if (c.integer.get(b)) 1 });
}
Saya tidak melihat sisa optimasi non-spasi putih, jadi mari kita hapus spasi putih yang tidak diperlukan (1 poin untuk setiap ruang, dua untuk masing-masing dari dua jeda baris):
shared void p(){print(sum{0,if(exists a=process.arguments[0])if(a!="test")for(c in a)for(b in 0..7)if(c.integer.get(b))1});}
Saat menjelajah API, saya menemukan bahwa Character.hash sebenarnya mengembalikan nilai yang sama dengan integer
atributnya. Tapi itu hanya memiliki 14 poin, bukan 30, jadi kami turun ke 451!
shared void p(){print(sum{0,if(exists a=process.arguments[0])if(a!="test")for(c in a)for(b in 0..7)if(c.hash.get(b))1});}