Saya pernah perlu menulis fungsi yang menghitung entropi blok dari seri simbol yang diberikan untuk ukuran blok yang diberikan dan terkejut betapa pendeknya hasilnya. Jadi saya menantang Anda untuk codegolf fungsi seperti itu. Saya tidak memberi tahu Anda apa yang saya lakukan untuk saat ini (dan dalam bahasa apa), tetapi saya akan melakukannya dalam seminggu atau lebih, jika tidak ada yang datang dengan ide yang sama atau lebih baik terlebih dahulu.
Definisi blok entropi:
Diberikan urutan simbol A = A_1, ..., A_n dan ukuran blok m:
- Blok ukuran m adalah segmen dari m elemen berurutan dari urutan simbol, yaitu, A_i, ..., A_ (i + m − 1) untuk setiap i yang sesuai.
- Jika x adalah urutan simbol dari ukuran m, N (x) menunjukkan jumlah blok A yang identik dengan x.
- p (x) adalah probabilitas bahwa blok dari A identik dengan urutan simbol x ukuran m, yaitu, p (x) = N (x) / (n − m + 1)
- Akhirnya, entropi blok untuk ukuran blok m dari A adalah rata-rata −log (p (x)) di atas semua blok x ukuran m di A atau (yang setara) jumlah −p (x) · log (p (x)) atas setiap x ukuran m yang terjadi di A. (Anda dapat memilih logaritma yang Anda inginkan.)
Pembatasan dan klarifikasi:
- Fungsi Anda harus mengambil urutan simbol A serta ukuran blok m sebagai argumen.
- Anda dapat mengasumsikan bahwa simbol tersebut direpresentasikan sebagai bilangan bulat berbasis nol atau dalam format lain yang sesuai.
- Program Anda harus mampu mengambil argumen yang masuk akal secara teori dan pada kenyataannya harus mampu menghitung contoh kasus (lihat di bawah) pada komputer standar.
- Fungsi dan pustaka built-in diperbolehkan, selama mereka tidak melakukan bagian besar dari prosedur dalam satu panggilan, yaitu, mengekstraksi semua blok ukuran m dari A, menghitung jumlah kemunculan blok tertentu x atau menghitung entropi dari urutan nilai p - Anda harus melakukan hal-hal itu sendiri.
Uji:
[2, 3, 4, 1, 2, 3, 0, 0, 3, 2, 3, 0, 2, 2, 4, 4, 4, 1, 1, 1, 0, 4, 1,
2, 2, 4, 0, 1, 2, 3, 0, 2, 3, 2, 3, 2, 0, 1, 3, 4, 4, 0, 2, 1, 4, 3,
0, 2, 4, 1, 0, 4, 0, 0, 2, 2, 0, 2, 3, 0, 0, 4, 4, 2, 3, 1, 3, 1, 1,
3, 1, 3, 1, 0, 0, 2, 2, 4, 0, 3, 2, 2, 3, 0, 3, 3, 0, 0, 4, 4, 1, 0,
2, 3, 0, 0, 1, 4, 4, 3]
Entropi blok pertama dari urutan ini adalah (untuk logaritma natural):
- m = 1: 1.599
- m = 2: 3.065
- m = 3: 4.067
- m = 4: 4.412
- m = 5: 4.535
- m = 6: 4.554
entropy(probabilities(blocks(A,m)))
.Jawaban:
Mathematica -
8178757267656256 byteSaya belum pernah bermain golf di Mathematica sebelumnya, jadi saya kira ada ruang untuk perbaikan. Yang ini tidak cukup sesuai dengan aturan karena fungsi
Partition
danTally
, tapi itu cukup rapi jadi saya pikir saya tetap akan mempostingnya.Ini berfungsi dengan sekumpulan simbol apa pun, dan dapat digunakan seperti
Berikut ini adalah versi yang agak tidak diubah:
Mungkin akan berjalan lebih cepat jika saya
N
langsung menerapkan ke hasilTally
.By the way, Mathematica sebenarnya memiliki
Entropy
fungsi, yang mengurangi ini menjadi 28 byte , tapi itu jelas melanggar aturan.Di sisi lain, berikut adalah versi 128 byte yang menambahkan
Partition
danTally
:Tidak Disatukan:
sumber
Partition
danTally
bukan merupakan kasus batas, mereka melanggar aturan secara langsung, karena mereka “mengekstraksi semua blok berukuran m dari A” dan “menghitung jumlah kemunculan blok x yang diberikan”, masing-masing, dalam satu panggilan. Namun, setelah semua yang saya tahu tentang Mathematica, saya tidak akan terkejut, jika ada solusi yang layak tanpa mereka.Partition
danTally
.Perl, 140 byte
Script Perl berikut mendefinisikan fungsi
E
yang mengambil urutan simbol, diikuti oleh ukuran segmen sebagai argumen.Versi tidak dikoleksi dengan tes
Hasil:
Simbol:
Simbol tidak terbatas pada bilangan bulat, karena pencocokan pola berdasarkan string digunakan. Representasi string dari simbol tidak boleh mengandung koma, karena itu digunakan sebagai pembatas. Tentu saja, simbol yang berbeda harus memiliki representasi string yang berbeda.
Dalam versi golf, representasi string dari simbol tidak boleh mengandung karakter spesial pola. Empat byte tambahan
\Q
...\E
tidak diperlukan untuk angka.sumber
sub f{($s,$m,$r,%h)=@_;$h{x,@$s[$_..$_+$m-1]}++for 0..@$s-$m;$r-=($_/=@$s-$m+1)*log for values %h;return$r}
; di mana$s
referensi,$r
dan%h
diatur ulang ke undef dengan tugas 1, daftar adalah kunci hash (dengan sedikit bantuan$;
, dan beberapax
- sayangnya), dan agak kurang rumit secara umum, saya pikir.values %h
tidak diperlukan, jadi solusi Anda hanya membutuhkan 106 byte.Python
127 152B138BDisesuaikan untuk tidak melanggar aturan lagi dan memiliki algoritma yang sedikit lebih manis. Disesuaikan menjadi lebih kecil
Versi yang lebih lama:
Skrip Python pertama saya! Lihat dalam aksi: http://pythonfiddle.com/entropy
sumber
count
fungsi ini langsung melanggar aturan, karena ini "menghitung jumlah kemunculan dari blok x yang diberikan".;
jika perlu). Kurung kotak di baris terakhir juga tidak diperlukan.and 1 or 0
) tidak diperlukan. Anda juga dapat menyimpan beberapa karakter dengan menentukan sebelumnyarange(N)
.Python dengan Numpy,
146143 BytesSeperti yang dijanjikan, inilah solusi saya sendiri. Ini membutuhkan input bilangan bulat non-negatif:
Kerugiannya adalah ini meledak memori Anda untuk
m
ataumax(A)
.Berikut adalah versi yang kebanyakan tidak dikomunikasikan dan dikomentari:
sumber
MATLAB
sumber