Цейлон, 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});}
Це було оригінальне, невольфське:
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!");
}
}
Це бере аргумент з параметра командного рядка ... process.arguments - це (можливо, порожня) послідовність рядків, тому перш ніж використовувати один з них, нам потрібно перевірити, чи він насправді існує. В іншому випадку ми виводимо повідомлення про помилку (це питання не вимагає, і його буде викинуто в наступних версіях).
Цейлону sum
функція приймає непорожнє Iterable елементів деякого типу , який повинен задовольняти Summable
, тобто є plus
спосіб, як Integer. (Це не працює з порожніми послідовностями, оскільки у кожного типу Summable буде свій нуль, і час виконання не має шансів дізнатися, що саме означає.)
Елементи рядка, або один біт цілого числа, не є порожнім ітерабельним. Тому ми використовуємо тут функцію для побудови ітерабельного, вказуючи деякі елементи, а потім "розуміння" (яке буде оцінено до нуля або більше елементів). Отже, у випадку символів ми додаємо їх (але лише тоді, коли встановлено відповідний біт), у випадку рядка ми додаємо результат символів. (Розуміння буде оцінено лише тоді, коли функція прийому насправді повторюється над нею, а не при побудові Iterable.)
Подивимось, як ми можемо зменшити це. По-перше, кожна з функцій викликається лише в одному місці, тому ми можемо їх вбудувати. Також, як було сказано вище, позбудьтеся повідомлення про помилку. (764 бальних оцінок.)
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 }) }));
}
}
}
Насправді нам не потрібна внутрішня вкладеність sum
, ми можемо зробити це одне велике розуміння. (Це заощаджує нам 37 очкових позицій для sum({0,})
та ще трохи для пробілу, який у будь-якому разі буде усунено в кінці кінців.) Це 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 }));
}
}
}
Ми можемо застосувати аналогічний принцип до спеціального "test"
рядка, що знаходиться в обкладинці : так як у такому випадку результат дорівнює 0 (тобто нічого не внесено до суми), ми можемо просто зробити це як частину підсумовування (але умову потрібно перевернути) . Це, головним чином, заощаджує нас print(0);
, деякі підтяжки та купу пробілів, знижуючись до рівня 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 }));
}
}
Ми робимо те ж саме для першого if
, з побічним ефектом, який зараз не дає жодних аргументів, і не дає 0
нічого робити. (Принаймні, я думав, що це відбудеться тут, натомість, здається, висить вічна петля? Дивно.)
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 }));
}
Ми можемо на самому ділі опустити ()
для sum
функції тут, використовуючи альтернативний синтаксис виклику функції , яка використовує {...}
замість ()
, і заповнимо осягнення в Iterable аргументів. Це має слід 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 });
}
Заміна назви функції footprint
(40) на p
(3) заощаджує ще 37 балів, що приводить нас до 501. (Назви цілонових функцій повинні починатися з малих символів, тому ми не можемо отримати менше 3 балів.)
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 });
}
Імена змінних s
(5) і c
(4), i
(4) також не є оптимальними. Замінимо їх на a
(аргумент), d
(розряд?) Та b
(біт-індекс). Слід 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 });
}
Я не бачу жодної оптимізації, що не залишається пробілом, тому давайте видалимо не потрібний пробіл (1 бал за кожен пробіл, два для кожного з двох розривів рядків):
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 я виявив, що Character.hash насправді повертає те саме значення, що і його integer
атрибут. Але він має всього 14 балів замість 30, тому ми доходимо до 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});}