Estou curioso para saber se eu sou o Code Golfing corretamente. Eu propus o desafio de transformar um pequeno programa de hash em uma única declaração no Python. Comecei com:
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()
Eu então fiz a função 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))
Tentei encurtá-lo com um lambda para repetir o código (não funcionou):
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 acabei com uma 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))
Eu queria que o programa fosse uma declaração, então, primeiro, criei:
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")
E, finalmente, acabei com:
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")())
É assim que os problemas do codegolf são resolvidos? Eu nunca realmente fiz esse tipo de coisa, então agora eu só quero saber se estou fazendo certo.
Alteração: Este programa faz todo o trabalho para você; portanto, vou me referir à função: Como entrada, o programa recebe todas as permutações de uma determinada string; aqui a string tem nove caracteres escolhidos aleatoriamente ascii_lowercase
. A saída é uma sequência legível por humanos que define se o resultado de cada permutação da sequência fornecida é uma duplicata de outro resultado para uma sequência diferente. Se não houver duplicatas para todas as permutações, o programa indica sucesso. Nove caracteres foram escolhidos como sendo o maior tamanho de caracteres prontamente computados repetidamente na minha caixa.
Alteração II Conforme indicado por um leitor estudioso, o objetivo pretendido descrito não é obtido através do código que o acompanha. O caso de teste é obviamente inadequado.
print"x"
em vez deprint("x")
list()
?Respostas:
Não existe uma maneira "certa" de jogar golfe. Você se saiu bem e o processo usado é bastante padrão. Transformar o programa em uma declaração geralmente não é um requisito.
Se ajudar, eis como eu abordaria o golfe no seu programa ...
Na função de hash, a instrução for pode ser substituída por uma soma:
Isso pode ser definido como uma função lambda:
E agora removemos espaços e colchetes desnecessários:
Como o Sp3000 apontou, isso pode ser reduzido ainda mais com enumerar:
Passando para a função de teste, mesclamos suas duas primeiras linhas:
Como ambas as funções são usadas apenas uma vez, podemos mover tudo em linha:
Isso é mais curto como compreensão da lista:
Em seguida, atribuímos um nome mais curto e removemos os espaços desnecessários novamente:
A instrução if pode ser movida dentro da função de impressão:
No entanto, geralmente é mais curto para usar e / ou:
Como
len(x)
não muda, podemos calcular e codificar seu valor:Após remover espaços desnecessários e alternar a comparação, obtemos:
Isso nos permite mover tudo para uma declaração:
E agora podemos usar uma compreensão de conjunto:
O resultado é 210 bytes, excluindo importações. O próximo passo provavelmente seria reduzir as importações ou as longas cordas.
fonte
enumerate
é mais curto:h=lambda s:sum(ord(x)<<i*len(s)for i,x in enumerate(s))