Tengo curiosidad si estoy Code Golfing correctamente. Me propuse el desafío de hacer un pequeño programa de hash en una sola declaración en Python. Primero comencé con:
from itertools import permutations
from string import ascii_lowercase
from random import sample
def test():
chars = sample(ascii_lowercase, 9)
sums = list(map(h, permutations(chars)))
if len(set(sums)) == len(sums):
print("unique results for permutations of given string")
else:
print("duplicate entries present in test results")
def h(s):
r = 0
for i in range(len(s)):
r += ord(s[i]) << (i * len(s))
return r
test()
Luego hice la función recursiva:
def h(s, i=0):
if i < len(s) - 1: return h(s, i+1) + ord(s[i]) << (i * len(s))
else: return ord(s[i]) << (i * len(s))
Intenté acortarlo con un lambda para repetir el código (no funcionó):
def h(s, i=0, f=lambda s,i: ord(s[i]) << (i * len(s))):
if i < len(s) - 1: return h(s, i+1) + f(s,i)
else: return f(s,i)
Finalmente terminé con una lambda:
h=lambda s,i=0:h(s,i+1)+ord(s[i])<<(i*len(s))if i<len(s)-1 else ord(s[i])<<(i*len(s))
Quería que el programa fuera una declaración, así que primero se me ocurrió:
def test():
chars = sample(ascii_lowercase, 9)
sums = list(map((lambda s,i=0,f=lambda s,i,f:f(s,i+1,f)+ord(s[i])<<(i*len(s))if i<len(s)-1 else ord(s[i])<<(i*len(s)):f(s,i,f)), permutations(chars)))
if len(set(sums)) == len(sums):
print("unique results for permutations of given string")
else:
print("duplicate entries present in test results")
Y finalmente terminé con:
print((lambda x=list(map((lambda s,i=0,f=lambda s,i,f:f(s,i+1,f)+ord(s[i])<<(i*len(s))if i<len(s)-1 else ord(s[i])<<(i*len(s)):f(s,i,f)), permutations(sample(ascii_lowercase, 9)))): "unique results for permutations of given string" if len(set(x)) == len(x) else "duplicate entries present in test results")())
¿Es así como se resuelven los problemas de codegolf? Realmente nunca he hecho este tipo de cosas, así que ahora solo quiero saber si lo estoy haciendo bien.
Enmienda: este programa hace todo el trabajo por usted; así que aquí me referiré a la función: como entrada, el programa toma todas las permutaciones de una cadena dada; aquí la cadena tiene nueve caracteres elegidos al azar ascii_lowercase
. La salida es una cadena legible por humanos que define si el resultado de cada permutación de la cadena dada es un duplicado de otro resultado para una cadena diferente. Si no hay duplicados para todas las permutaciones, el programa indica éxito. Se seleccionaron nueve caracteres como la mayor longitud de caracteres que se calcularon fácilmente repetidamente en mi caja.
Enmienda II Como lo señaló un lector estudioso, el propósito previsto descrito no se obtiene a través del código adjunto. El caso de prueba es obviamente inadecuado.
print"x"
en lugar deprint("x")
list()
?Respuestas:
No hay una forma "correcta" de jugar al golf. Lo has hecho bien y el proceso que has utilizado es bastante estándar. Sin embargo, convertir el programa en una declaración no suele ser un requisito.
Si ayuda, así es como abordaría el golf en su programa ...
En la función hash, la instrucción for se puede reemplazar con una suma:
Esto se puede definir como una función lambda:
Y ahora eliminamos espacios y corchetes innecesarios:
Como señaló Sp3000, esto se puede acortar aún más con enumerate:
Pasando a la función de prueba, fusionamos sus dos primeras líneas:
Como ambas funciones solo se usan una vez, podemos mover todo en línea:
Esto es más corto como una lista de comprensión:
A continuación, le damos un nombre más corto y eliminamos espacios innecesarios nuevamente:
La instrucción if se puede mover dentro de la función de impresión:
Sin embargo, generalmente es más corto de usar y / o:
Como
len(x)
no cambia, podemos calcular y codificar su valor:Después de eliminar espacios innecesarios y cambiar la comparación, obtenemos:
Esto nos permite mover todo a una declaración:
Y ahora podemos usar un conjunto de comprensión en su lugar:
El resultado es 210 bytes, excluidas las importaciones. El siguiente paso probablemente sería reducir las importaciones o las largas cadenas.
fuente
enumerate
es más corto:h=lambda s:sum(ord(x)<<i*len(s)for i,x in enumerate(s))