Urutan skolem
Sebuah Skolem urutan adalah urutan 2n
nomor di mana setiap nomor i
antara 1
dan n
terjadi tepat dua kali, dan jarak antara dua kejadian i
persis i
langkah. Berikut adalah beberapa contoh urutan Skolem:
1 1
1 1 4 2 3 2 4 3
16 13 15 12 14 4 7 3 11 4 3 9 10 7 13 12 16 15 14 11 9 8 10 2 6 2 5 1 1 8 6 5
Urutan berikut bukanlah urutan Skolem:
1 2 1 2 (The distance between the 1's is 2, not 1)
3 1 1 3 (The number 2 is missing)
1 1 2 1 1 2 (There are four 1's)
Objektif
Tulis program, fungsi, atau ekspresi untuk menghitung jumlah semua urutan Skolem dengan panjang tertentu. Secara lebih eksplisit, input Anda adalah bilangan bulat n
, dan output Anda adalah jumlah urutan panjang Skolem 2n
. Urutan ini memiliki entri OEIS . Untuk n = 0
, Anda dapat mengembalikan salah satu 0
atau 1
. Beberapa nilai pertama, mulai dari 0
, adalah
0, 1, 0, 0, 6, 10, 0, 0, 504, 2656, 0, 0, 455936, 3040560, 0, 0, 1400156768
Aturan dan penilaian
Ini golf kode. Format output lemah karena alasan.
0, 1, 0, 0, 6...
di pertanyaan Anda? Apakah itu cuplikan kode, jika demikian bahasa apa itu?0
? Jika Anda akan mengaku0
sebagai input yang valid maka output seharusnya1
.Jawaban:
GolfScript,
4846 karakterVersi yang lebih cepat ( coba online ) - berjalan dengan cepat, mis.
n=8
Membutuhkan waktu sekitar dua detik. Dan pendekatan yang dipilih hanya membutuhkan sedikit karakter.Versi ini juga berfungsi dengan bitmask. Ini membangun array hasil yang mungkin dari 1 ke atas, yaitu untuk
n=3
:Sementara beberapa hasil (seperti 000011) memiliki dua kemungkinan lanjutan, yang lain (yaitu 001100) tidak memiliki dan dihapus dari array hasil.
Penjelasan kode:
sumber
Ekspresi J, 47 karakter
Contoh:
Butuh sekitar 30 detik untuk
y=:5
di mesin saya.Algoritma ini sangat lambat:
~.(i.!+:y)A.,~>:i.y
menghasilkan setiap permutasi1 2 .. y 1 2 .. y
dan menghapus entri duplikat((=&{:+.2-#@])#;.2)\"1
menghitung:(...)\"1
untuk setiap awalan dari setiap baris:#;.2
menghitung elemen sebelum setiap kemunculan elemen terakhir#@]
menghitung jumlah penghitungan (yaitu jumlah kemunculan elemen terakhir)=&{:
menentukan "kesetaraan" "dari" "elemen terakhir" dari daftar hitungan dan daftar asli.+.
adalah OR logis.=&{:+.2-#@]
berbunyi "elemen terakhir [dari daftar hitungan dan daftar asli] sama, atau hanya ada satu elemen [dalam daftar hitungan] daripada dua".*/"1
mengalikan (logis DAN) di atas baris tabel kondisi, menentukan permutasi yang merupakan urutan Skolem.+/
menjumlahkan yang dan nol bersama-sama.sumber
GolfScript (46 karakter)
Ini adalah ekspresi yang mengambil input pada stack. Untuk mengubahnya menjadi program lengkap yang mengambil input pada stdin, prepend
~
Ini cukup tidak efisien - sebagian besar penghematan yang saya lakukan dalam bermain golf turun dari 56 karakter yang tidak diserang adalah dengan memperluas rentang loop dengan cara yang tidak memberikan hasil yang salah tetapi melakukan perhitungan limbah.
Pendekatannya adalah penyembunyian bitwise produk Cartesian. Misalnya (menggunakan biner untuk topeng) untuk
n=4
kode yang tidak diklik akan menghitung xor dari setiap elemen dalam produk Cartesian[00000011 00000110 ... 11000000] x [00000101 00001010 ... 10100000] x ... x [00010001 ... 10001000]
. Hasil apa pun dengan 8 bit hanya dapat dicapai dengan masker yang tidak tumpang tindih.Untuk mengoptimalkan ukuran daripada kecepatan, kode mengakumulasikan produk parsial (
S1 u S1xS2 u S1xS2xS3 ...
) dan membuat setiap produk menjadi2n
elemen bukan hanya2n-1-i
yang sebenarnya dapat berkontribusi pada urutan yang valid.Kecepatan
Versi golf berjalan selama
n=5
10 detik di komputer saya, dan lebih dari 5 menit untukn=6
. Versi ungolfed asli menghitungn=5
dalam waktu kurang dari satu detik, dann=6
dalam waktu sekitar 1 menit. Dengan filter sederhana pada hasil antara, ia dapat menghitungn=8
dalam 30 detik. Saya telah memasukkannya ke 66 karakter (sebagai program - 65 karakter sebagai ekspresi) sambil menjaga agar loop tetap dibatasi dan memfilter tabrakan antara:sumber
GolfScript, 49 karakter
Mengharapkan nomor
n
di STDIN. Ini kode-golf - jangan coba kode dengann
lebih dari 5.sumber
Sage, 70
Ini sedikit lebih pendek dari aslinya.
Bagaimana itu bekerja:
Diberikan matriks 0/1, masalah sampul yang tepat untuk matriks itu adalah menemukan subset dari baris yang dijumlahkan (sebagai bilangan bulat) ke vektor semua-yang. Sebagai contoh,
punya solusinya
Pendekatan favorit saya untuk masalah adalah melemparkannya ke masalah sampul yang tepat. Urutan skolem secara efisien memfasilitasi ini. Saya membuat masalah sampul yang tepat di mana solusi berada di bijection dengan urutan panjang Skolem
2n
. Misalnya, deretan masalahn=6
adalahdi mana 1 dalam posisi
a < n
berarti simbola
yang digunakan. Posisi yang tersisa sesuai dengan lokasi aktual dalam urutan. Sampul yang tepat sesuai dengan setiap simbol yang digunakan tepat sekali, dan setiap lokasi diisi tepat sekali. Dengan konstruksi, simbol apa punk
di lokasi berjarakk
jauh dari mitranya.Dalam Sage,
DLXCPP
adalah implementasi "link menari" - ini memecahkan masalah sampul yang tepat dengan cara yang sangat anggun. Ini adalah salah satu algoritma favorit saya, dan berada tepat di permukaan Sage membuat enumerasi kombinatorial menyenangkan.sumber
len(list(...))
akan menghemat 4 karakter.len(list(...))
n = 16. Dan itu akan benar-benar membunuh runtime.