Ceilán, 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 fue el original, sin golf:
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!");
}
}
Esto toma el argumento de un parámetro de línea de comando ... process.arguments es una secuencia (posiblemente vacía) de cadenas, por lo que antes de usar una de ellas, debemos verificar si realmente existe. En el otro caso, enviamos un mensaje de error (esto no es requerido por la pregunta y será descartado en las próximas versiones).
La sum
función de Ceylon toma un Iterable no vacío de elementos de algún tipo que necesita satisfacer Summable
, es decir, tiene un plus
método, como Integer. (No funciona con secuencias vacías porque cada tipo Summable tendrá su propio cero, y el tiempo de ejecución no tiene oportunidad de saber a qué se refiere).
Los elementos de una cadena, o los bits de un entero, no son un iterable no vacío. Por lo tanto, estamos usando aquí la característica para construir un iterable especificando algunos elementos, luego una "comprensión" (que se evaluará a cero o más elementos). Entonces, en el caso de los caracteres, estamos agregando unos (pero solo cuando se establece el bit correspondiente), en el caso de la cadena estamos agregando el resultado de los caracteres. (La comprensión solo se evaluará cuando la función de recepción realmente repita sobre ella, no cuando se construye el Iterable).
Veamos cómo podemos reducir esto. Primero, cada una de las funciones solo se llama en un lugar, por lo que podemos incorporarlas. Además, como se mencionó anteriormente, elimine el mensaje de error. (764 puntos de huella).
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 }) }));
}
}
}
En realidad no necesitamos el anidado interno sum
, podemos hacer que esta sea una gran comprensión. (Esto nos ahorra 37 puntos de huella sum({0,})
y un poco más para los espacios en blanco, que de todos modos se eliminarán al final). Esto es 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 un principio similar a la "test"
cadena especial en mayúsculas: como en ese caso el resultado es 0 (es decir, no se aporta nada a la suma), podemos hacer esto como parte de la suma (pero tenemos que invertir la condición) . Esto nos ahorra principalmente print(0);
, algunas llaves y un montón de espacios de sangría, reduciéndose a una huella 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 }));
}
}
Hacemos lo mismo para el primero if
, con el efecto secundario de que ahora no dar argumentos también genera resultados en 0
lugar de no hacer nada. (¿Al menos pensé que pasaría aquí, en lugar de eso parece colgar con un lazo eterno? Extraño).
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 }));
}
En realidad, podemos omitir el ()
para la sum
función aquí, usando una sintaxis de llamada a función alternativa , que usa en {...}
lugar de ()
, y completará las comprensiones en argumentos iterables. Esto tiene huella 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 });
}
Reemplazar el nombre de la función footprint
(40) por p
(3) ahorra otros 37 puntos, llevándonos a 501. (Los nombres de las funciones de Ceilán tienen que comenzar con letras minúsculas, por lo que no podemos obtener menos de 3 puntos aquí).
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 });
}
Los nombres de las variables s
(5) y c
(4), i
(4) tampoco son óptimos. Vamos a reemplazarlos por a
(argumento), d
(dígito?) Y b
(índice de bits). Huella 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 });
}
No veo ninguna optimización restante que no sea un espacio en blanco, así que eliminemos el espacio en blanco no necesario (1 punto por cada espacio, dos por cada uno de los dos saltos de línea):
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});}
Al navegar por la API, descubrí que Character.hash en realidad devuelve el mismo valor que su integer
atributo. Pero tiene solo 14 puntos en lugar de 30, ¡así que bajamos 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});}