Мне любопытно, правильно ли я занимаюсь Code Golf. Я поставил перед собой задачу сделать небольшую программу хеширования одним выражением в Python. Я начал с:
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()
Затем я сделал функцию рекурсивной:
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))
Я попытался сократить его с помощью лямбды для повторения кода (это не сработало):
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)
Наконец я закончил с лямбдой:
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))
Я хотел, чтобы программа была одним утверждением, поэтому сначала я придумал:
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")
И, наконец, я закончил с:
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")())
Так ли решаются проблемы Codegolf? Я никогда не делал такого рода вещи, поэтому сейчас я просто хочу знать, правильно ли я это делаю.
Поправка: эта программа делает всю работу за вас; поэтому здесь я буду ссылаться на функцию: в качестве входных данных программа принимает все перестановки данной строки; здесь строка состоит из девяти символов, выбранных случайным образом ascii_lowercase
. Вывод представляет собой читаемую человеком строку, определяющую, является ли результат каждой перестановки данной строки дубликатом другого результата для другой строки. Если нет дубликатов для всех перестановок, программа указывает на успех. Девять символов было выбрано как наибольшая длина символов, легко вычисляемых многократно на моей коробке.
Поправка II Как указал старательный читатель, описанная цель не достигается с помощью прилагаемого кода. Тестовый пример явно неадекватен.
print"x"
вместоprint("x")
list()
?