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 sum
função do Ceilão pega um Iterável não vazio de elementos de algum tipo que precisa satisfazer Summable
, ou seja, possui um plus
mé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 0
vez 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 sum
funçã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 integer
atributo. 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});}