Цейлон, 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});}