Мені колись потрібно було написати функцію, яка обчислює ентропію блоку заданого ряду символів для заданого розміру блоку, і я був здивований тим, наскільки короткий результат. Таким чином, я закликаю вас кодогульфувати таку функцію. Я не кажу тобі, що я зараз робив (і якою мовою), але буду через тиждень чи так, якщо спочатку ніхто не придумає однакових чи кращих ідей.
Визначення ентропії блоку:
Дано послідовність символів A = A_1,…, A_n та розмір блоку m:
- Блок розміром m - це відрізок m послідовних елементів послідовності символів, тобто A_i,…, A_ (i + m − 1) для будь-якого відповідного i.
- Якщо x - послідовність символів розміром m, N (x) позначає кількість блоків A, ідентичних x.
- p (x) - ймовірність того, що блок з A ідентичний послідовності символів x розміру m, тобто p (x) = N (x) / (n − m + 1)
- Нарешті, ентропія блоку для розміру блоку m A становить середнє значення log (p (x)) для всіх блоків x розміром m в A або (що еквівалентно) сумою −p (x) · log (p (x)) для кожного x розміру m, що виникає в А. (Ви можете вибрати будь-який розумний логарифм, який хочете.)
Обмеження та уточнення:
- Ваша функція повинна приймати як аргумент послідовність символів A, а також розмір блоку m.
- Можна припустити, що символи представлені у вигляді нульових цілих чисел або в іншому зручному форматі.
- Ваша програма повинна бути здатна приймати будь-які обґрунтовані аргументи теоретично, а в реальності повинна мати можливість обчислити приклад (див. Нижче) на стандартному комп'ютері.
- Вбудовані функції та бібліотеки дозволені до тих пір, поки вони не виконують великі частини процедури за один виклик, тобто витягують всі блоки розміром m від A, підраховуючи кількість входів даного блоку x або обчислюючи ентропії з послідовності значень p - ви повинні робити ці речі самостійно.
Тест:
[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]
Першими блоковими ентропіями цієї послідовності є (для природного логарифму):
- m = 1: 1,599
- m = 2: 3.065
- m = 3: 4,067
- m = 4: 4.412
- m = 5: 4,535
- m = 6: 4,555
entropy(probabilities(blocks(A,m))).