Jestem ciekawy, czy prawidłowo gram w golfa. Podjąłem wyzwanie, aby przekształcić mały program mieszający w jedną instrukcję w Pythonie. Zacząłem od:
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()
Następnie ustawiłem funkcję rekurencyjną:
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))
Próbowałem skrócić go za pomocą lambda do powtarzania kodu (nie działało):
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)
W końcu skończyło się na 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))
Chciałem, aby program był jedną instrukcją, więc najpierw wymyśliłem:
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")
I w końcu skończyło się na:
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")())
Czy w ten sposób rozwiązywane są problemy codegolf? Tak naprawdę nigdy tego nie robiłem, więc teraz chcę tylko wiedzieć, czy robię to dobrze.
Poprawka: Ten program wykonuje całą pracę za Ciebie; odniosę się tutaj do funkcji: Jako dane wejściowe program przyjmuje wszystkie permutacje danego ciągu; tutaj ciąg składa się z dziewięciu znaków losowo wybranych ascii_lowercase
. Dane wyjściowe to czytelny dla człowieka ciąg znaków, który określa, czy wynik każdej permutacji danego ciągu jest duplikatem innego wyniku dla innego ciągu. Jeśli nie ma duplikatów dla wszystkich permutacji, program wskazuje sukces. Dziewięć znaków zostało wybranych jako największa długość znaków, które można wielokrotnie obliczać na moim pudełku.
Poprawka II Jak wskazał uważny czytelnik, opisany zamierzony cel nie został osiągnięty za pomocą załączonego kodu. Przypadek testowy jest oczywiście nieodpowiedni.
print"x"
zamiastprint("x")
list()
?