Ceilão, 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});}
Este era o original, não destruído:
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!");
}
}
Isso leva o argumento a partir de um parâmetro da linha de comando ... process.arguments é uma sequência de sequências (possivelmente vazias); portanto, antes de usar uma delas, precisamos verificar se ela realmente existe. No outro caso, emitimos uma mensagem de erro (isso não é requerido pela pergunta e será descartado nas próximas versões).
A sumfunção do Ceilão pega um Iterável não vazio de elementos de algum tipo que precisa satisfazer Summable, ou seja, possui um plusmétodo, como Inteiro. (Ele não funciona com sequências vazias porque cada tipo de Summable terá seu próprio zero e o tempo de execução não tem chance de saber qual é o significado.)
Os elementos de uma string ou os bits de um número inteiro não são iteráveis não vazios. Portanto, estamos usando aqui o recurso para criar uma iterável especificando alguns elementos, depois uma "compreensão" (que será avaliada como zero ou mais elementos). Portanto, no caso de caracteres, estamos adicionando uns (mas somente quando o bit correspondente é definido), no caso de string, estamos adicionando o resultado dos caracteres. (A compreensão será avaliada apenas quando a função de recebimento realmente iterar sobre ela, não ao criar o Iterable.)
Vamos ver como podemos diminuir isso. Primeiro, cada uma das funções é chamada apenas em um local, para que possamos incorporá-las. Além disso, como mencionado acima, livre-se da mensagem de erro. (764 pontos de pegada).
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 }) }));
}
}
}
Na verdade, não precisamos do interior aninhado sum, podemos fazer uma grande compreensão. (Isso economiza 37 pontos de pegada para sum({0,}), e mais alguns, para espaços em branco, que serão eliminados no final de qualquer maneira.) Isso é 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 }));
}
}
}
Podemos aplicar um princípio semelhante à "test"sequência especial : como nesse caso o resultado é 0 (ou seja, nada é contribuído para a soma), podemos fazer isso como parte da soma (mas temos que inverter a condição) . Isso nos poupa principalmente print(0);, algumas chaves e um monte de espaços de recuo, chegando a uma pegada de 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 }));
}
}
Fazemos o mesmo para o primeiro if, com o efeito colateral que agora não gera argumentos também gera, em 0vez de não fazer nada. (Pelo menos eu pensei que isso iria acontecer aqui, em vez disso, parece travar com um laço eterno? Estranho.)
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 }));
}
Na verdade, podemos omitir o ()para a sumfunção aqui, usando uma sintaxe de chamada de função alternativa , que usa {...}em vez de (), e irá preencher compreensões em argumentos iteráveis. Isso tem pegada 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 });
}
Substituir o nome da função footprint(40) por p(3) economiza outros 37 pontos, levando-nos para 501. (Os nomes das funções do Ceilão precisam começar com caracteres minúsculos, portanto, não podemos obter menos de 3 pontos aqui.)
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 });
}
Os nomes das variáveis s(5) e c(4), i(4) também não são ótimos. Vamos substituí-los por a(argumento), d(dígito?) E b(índice de bits). Pegada 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 });
}
Não vejo nenhuma otimização restante de espaço em branco, portanto, vamos remover o espaço em branco não necessário (1 ponto para cada espaço, dois para cada uma das duas quebras de linha):
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});}
Ao navegar na API, descobri que Character.hash realmente retorna o mesmo valor que seu integeratributo. Mas tem apenas 14 pontos em vez de 30, então chegamos a 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});}