Saya ingin tahu apakah saya Code Golfing dengan benar. Saya mengatur tantangan bagi diri saya untuk membuat program hashing kecil menjadi satu pernyataan dengan Python. Saya mulai dengan:
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()
Saya kemudian membuat fungsi rekursif:
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))
Saya mencoba memperpendeknya dengan lambda untuk mengulang kode (tidak berhasil):
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)
Akhirnya saya berakhir dengan 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))
Saya ingin program menjadi satu pernyataan, jadi pertama-tama saya membuat:
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")
Dan terakhir saya berakhir dengan:
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")())
Apakah ini bagaimana masalah codegolf diselesaikan? Saya tidak pernah benar-benar melakukan hal semacam ini, jadi sekarang saya hanya ingin tahu apakah saya melakukannya dengan benar.
Amandemen: Program ini melakukan semua pekerjaan untuk Anda; jadi di sini saya akan merujuk ke fungsi: Sebagai input, program mengambil semua permutasi dari string yang diberikan; di sini string diambil sembilan karakter secara acak ascii_lowercase
. Outputnya adalah string yang dapat dibaca manusia yang mendefinisikan apakah hasil dari setiap permutasi dari string yang diberikan adalah duplikat dari hasil lain untuk string yang berbeda. Jika tidak ada duplikat untuk semua permutasi, program menunjukkan keberhasilan. Sembilan karakter dipilih sebagai panjang karakter terbesar yang siap dihitung berulang kali di kotak saya.
Amandemen II Seperti yang ditunjukkan oleh pembaca yang rajin belajar, tujuan yang dimaksudkan tidak diperoleh melalui kode yang menyertainya. Kasus uji jelas tidak memadai.
print"x"
bukannyaprint("x")
list()
?Jawaban:
Tidak ada cara yang 'benar' untuk bermain golf. Anda telah melakukannya dengan baik, dan proses yang Anda gunakan cukup standar. Membuat program menjadi satu pernyataan biasanya bukan keharusan.
Jika ini membantu, inilah cara saya mendekati golf di program Anda ...
Dalam fungsi hashing, pernyataan for dapat diganti dengan jumlah:
Ini kemudian dapat didefinisikan sebagai fungsi lambda:
Dan sekarang kami menghapus spasi dan tanda kurung yang tidak perlu:
Seperti yang Sp3000 tunjukkan, ini dapat dipersingkat lebih lanjut dengan menyebutkan:
Beralih ke fungsi tes, kami menggabungkan dua baris pertamanya:
Karena kedua fungsi hanya digunakan satu kali, kami dapat memindahkan semua yang sebaris:
Ini lebih pendek sebagai pemahaman daftar:
Selanjutnya, kami memberikan nama yang lebih pendek dan menghapus spasi yang tidak perlu lagi:
Pernyataan if dapat dipindahkan di dalam fungsi cetak:
Namun, biasanya lebih pendek untuk digunakan dan / atau:
Karena
len(x)
tidak berubah, kami dapat menghitung dan meng-hardcode nilainya:Setelah menghapus spasi yang tidak perlu dan beralih di antara perbandingan, kami mendapatkan:
Ini memungkinkan kita memindahkan semuanya menjadi satu pernyataan:
Dan sekarang kita bisa menggunakan pemahaman set sebagai gantinya:
Hasilnya adalah 210 byte, tidak termasuk impor. Langkah selanjutnya mungkin akan menurunkan impor atau string panjang.
sumber
enumerate
lebih pendek:h=lambda s:sum(ord(x)<<i*len(s)for i,x in enumerate(s))