Je suis curieux de savoir si je joue correctement au Code Golf. Je me suis fixé le défi de transformer un petit programme de hachage en une seule instruction en Python. J'ai commencé avec:
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()
J'ai ensuite rendu la fonction récursive:
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))
J'ai essayé de le raccourcir avec un lambda pour répéter le code (cela n'a pas fonctionné):
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)
Enfin je me suis retrouvé avec une 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))
Je voulais que le programme soit une déclaration, alors j'ai d'abord trouvé:
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")
Et enfin je me suis retrouvé avec:
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")())
Est-ce ainsi que les problèmes de codegolf sont résolus? Je n'ai jamais vraiment fait ce genre de choses, donc en ce moment je veux juste savoir si je le fais bien.
Amendement: ce programme fait tout le travail pour vous; je vais donc ici faire référence à la fonction: En entrée, le programme accepte toutes les permutations d'une chaîne donnée; ici, la chaîne est composée de neuf caractères choisis au hasard ascii_lowercase
. La sortie est une chaîne lisible par l'homme définissant si le résultat de chaque permutation de la chaîne donnée est un doublon d'un autre résultat pour une chaîne différente. S'il n'y a pas de doublons pour toutes les permutations, le programme indique le succès. Neuf caractères ont été choisis comme étant la plus grande longueur de caractères facilement calculée à plusieurs reprises sur ma boîte.
Amendement II Comme l'a souligné un lecteur studieux, l'objectif visé décrit n'est pas obtenu par le biais du code d'accompagnement. Le cas de test est évidemment insuffisant.
print"x"
au lieu deprint("x")
list()
?Réponses:
Il n'y a pas de «bonne» façon de jouer au golf. Vous avez bien fait et le processus que vous avez utilisé est assez standard. Faire du programme en une seule déclaration n'est généralement pas une exigence cependant.
Si cela peut vous aider, voici comment j'aborderais le golf avec votre programme ...
Dans la fonction de hachage, l'instruction for peut être remplacée par une somme:
Cela peut alors être défini comme une fonction lambda:
Et maintenant, nous supprimons les espaces et les crochets inutiles:
Comme l'a souligné Sp3000, cela peut être encore raccourci avec énumérer:
Passant à la fonction de test, nous fusionnons ses deux premières lignes:
Étant donné que les deux fonctions ne sont utilisées qu'une seule fois, nous pouvons tout déplacer en ligne:
Ceci est plus court pour une compréhension de liste:
Ensuite, nous lui donnons un nom plus court et supprimons à nouveau les espaces inutiles:
L'instruction if peut être déplacée à l'intérieur de la fonction d'impression:
Cependant, il est généralement plus court à utiliser et / ou:
Puisque
len(x)
ne change pas, nous pouvons calculer et coder en dur sa valeur:Après avoir supprimé les espaces inutiles et changé la comparaison, nous obtenons:
Cela nous permet de tout déplacer dans une seule déclaration:
Et maintenant, nous pouvons utiliser une compréhension d'ensemble à la place:
Le résultat est de 210 octets, hors importations. La prochaine étape serait probablement de baisser les importations ou les longues chaînes.
la source
enumerate
c'est plus court:h=lambda s:sum(ord(x)<<i*len(s)for i,x in enumerate(s))