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});}
Bu orjinal, asılsızdı:
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!");
}
}
Bu, argümanı bir komut satırı parametresinden alır ... process.arguments, (muhtemelen boş) bir dizeler dizisidir, bu nedenle bunlardan birini kullanmadan önce gerçekten olup olmadığını kontrol etmemiz gerekir. Diğer durumda bir hata mesajı veriyoruz (bu, soru için gerekli değildir ve sonraki sürümlerde atılacaktır).
Ceylon'un sum
işlevi boş bırakmayan, tatmin etmesi gereken Summable
, yani plus
Integer gibi bir metoda sahip olan bir tür öğeden tekrarlanabilir . (Boş dizilerle çalışmaz, çünkü her bir Summable türünün kendi sıfıra sahip olması ve çalışma süresinin hangisinin ne demek olduğunu bilme şansı yoktur.)
Bir dizgenin elemanları veya bir tamsayının bitleri, boş olmayan bir yinelenemez değildir. Bu nedenle burada bazı unsurları belirleyerek tekrarlanabilir bir yapı oluşturmak için özelliğini, ardından bir “anlama” (sıfıra veya daha fazla eleman olarak değerlendirilecek) kullanıyoruz. Bu yüzden karakter harfine bir tane ekliyoruz (ancak karşılık gelen bit ayarlandığında), dizge harfine karakterlerin sonucunu ekliyoruz. (Kavrama, ancak alma işlevi gerçekte yinelendiğinde değerlendirilir, yinelemeyi oluştururken değil.)
Bakalım bunu nasıl daraltabileceğimizi görelim. İlk olarak, işlevlerin her biri yalnızca bir yerde çağrılır, bu nedenle onları satır içi yapabiliriz. Ayrıca, yukarıda belirtildiği gibi hata mesajından kurtulun. (764 ayak izi noktaları.)
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 }) }));
}
}
}
Aslında iç içe yuvaya ihtiyacımız yok sum
, bunu büyük bir kavrayış haline getirebiliriz. (Bu, bize sum({0,})
sonunda en sonunda elimine edilecek olan beyaz alan için 37 ayakiz puanını ve biraz daha fazlasını kurtarıyor .) Bu, 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 }));
}
}
}
Özel kasalı "test"
dizgeye benzer bir prensip uygulayabiliriz : bu durumda sonuç 0'dır (yani, hiçbiri toplama katkısı yoktur), bunu sadece toplamın bir parçası olarak yapabiliriz (ancak koşulu tersine çevirmeliyiz) . Bu, esas olarak bizi print(0);
, bazı parantezleri ve bir sürü girinti alanını, 571'in kapladığı alandan kurtarıyor :
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 }));
}
}
Birincisi için de aynısını yapıyoruz, if
şimdi hiçbir argüman vermeyen yan etki ile 0
hiçbir şey yapmamak yerine çıktılar . (En azından burada olacağını düşünmüştüm, bunun yerine ebedi bir döngü ile asılı gibi görünüyor? Garip.)
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 }));
}
Aslında buradaki ()
for sum
işlevini ihmal edebiliriz ; bunun yerine , kullanan ve alternatif ifadeleri yinelenebilir argümanlara dolduracak alternatif bir işlev çağrısı sözdizimi kullanabilirsiniz. Bu ayak izi 538 var:{...}
()
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 });
}
İşlev ismini footprint
(40) p
(3) ile değiştirmek, 37 puan daha kaydeder ve bizi 501'e getirir. (Ceylon işlev isimleri küçük harf karakterlerle başlamalıdır, bu nedenle 3 noktadan az alamayız.)
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 });
}
Değişken isimleri s
(5) ve c
(4), i
(4), aynı zamanda optimal değildir. Onları a
(argüman), d
(hane?) Ve b
(bit indeksi) ile değiştirelim. Ayak izi 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 });
}
Kalan boşluk olmayan optimizasyon göremiyorum, bu yüzden gerekli olmayan boşlukları kaldıralım (her alan için 1 nokta, iki satır sonunun her biri için iki tane):
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});}
API'ye göz atarken, Character.hash öğesinin integer
özniteliği ile aynı değeri döndürdüğünü gördüm . Fakat 30 yerine sadece 14 puan kaldı, bu yüzden 451'e düştük!
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});}