Kiedyś musiałem napisać funkcję, która oblicza entropię bloku danej serii symboli dla danego rozmiaru bloku i byłem zaskoczony, jak krótki był wynik. Dlatego wzywam was do kodegolfa takiej funkcji. Nie mówię wam, co na razie zrobiłem (i w jakim języku), ale zrobię to za tydzień, jeśli nikt wcześniej nie wpadnie na takie same lub lepsze pomysły.
Definicja entropii bloku:
Biorąc pod uwagę sekwencję symboli A = A_1,…, A_n i rozmiar bloku m:
- Blok o rozmiarze m jest segmentem m kolejnych elementów sekwencji symboli, tj. A_i,…, A_ (i + m-1) dla dowolnego odpowiedniego i.
- Jeśli x jest sekwencją symboli o rozmiarze m, N (x) oznacza liczbę bloków A, które są identyczne z x.
- p (x) jest prawdopodobieństwem, że blok z A jest identyczny z sekwencją symboli x o rozmiarze m, tj. p (x) = N (x) / (n − m + 1)
- Wreszcie, entropia bloku dla rozmiaru bloku m A jest średnią −log (p (x)) dla wszystkich bloków x wielkości m w A lub (co jest równoważne) sumą −p (x) · log (p (x)) na każdy x rozmiaru m występujący w A. (Możesz wybrać dowolny rozsądny logarytm).
Ograniczenia i wyjaśnienia:
- Twoja funkcja powinna przyjąć jako argument sekwencję symboli A oraz rozmiar bloku m.
- Możesz założyć, że symbole są reprezentowane jako liczby całkowite od zera lub w innym wygodnym formacie.
- Twój program powinien być w stanie przyjąć uzasadniony argument teoretycznie, a w rzeczywistości powinien być w stanie obliczyć przykładowy przypadek (patrz poniżej) na standardowym komputerze.
- Wbudowane funkcje i biblioteki są dozwolone, o ile nie wykonują dużych części procedury w jednym wywołaniu, tj. Wyodrębniają wszystkie bloki o rozmiarze m z A, licząc liczbę wystąpień danego bloku x lub obliczając entropie z sekwencji wartości p - musisz to zrobić sam.
Test:
[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]
Pierwszymi entropiami blokowymi tej sekwencji są (dla logarytmu naturalnego):
- 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)))
.Odpowiedzi:
Mathematica -
8178757267656256 bajtówNigdy wcześniej nie grałem w golfa w Mathematica, więc przypuszczam, że jest miejsce na poprawę. Ten nie jest do końca zgodny z regułami z powodu funkcji
Partition
iTally
, ale jest całkiem fajny, więc pomyślałem, że i tak go opublikuję.Działa to z dowolnym zestawem symboli i może być używane podobnie
Oto nieco nie golfowa wersja:
Prawdopodobnie będzie działać szybciej, jeśli zastosuję się
N
bezpośrednio do wynikuTally
.Nawiasem mówiąc, Mathematica faktycznie ma
Entropy
funkcję, która redukuje to do 28 bajtów , ale to zdecydowanie niezgodne z regułami.Z drugiej strony, tutaj jest wersja 128-bajtowa, która reimplementuje
Partition
iTally
:Nie golfowany:
źródło
Partition
iTally
nie są przypadkami granicznymi, wprost łamią zasady, ponieważ „wydobywają wszystkie bloki wielkości mz A” i „zliczają odpowiednio liczbę wystąpień danego bloku x” w jednym wywołaniu. Mimo wszystko, mimo wszystko, co wiem o Mathematica, nie zdziwiłbym się, gdyby bez nich istniało przyzwoite rozwiązanie.Partition
iTally
.Perl, 140 bajtów
Poniższy skrypt Perla definiuje funkcję,
E
która przyjmuje sekwencję symboli, a następnie wielkość segmentu jako argumenty.Wersja bez golfa z testem
Wynik:
Symbolika:
Symbole nie są ograniczone do liczb całkowitych, ponieważ stosowane jest dopasowanie wzorca oparte na ciągach znaków. Ciąg znaków reprezentujący symbol nie może zawierać przecinka, ponieważ jest używany jako separator. Oczywiście różne symbole muszą mieć różne reprezentacje ciągów.
W wersji golfowej reprezentacja ciągu symboli nie powinna zawierać znaków specjalnych wzorów. Dodatkowe cztery bajty
\Q
...\E
nie są potrzebne dla liczb.źródło
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}
; gdzie$s
jest odwołanie$r
i%h
są resetowane do undef przy pierwszym przypisaniu, listy są kluczami skrótu (z niewielką pomocą$;
, a niektórex
- niestety) i, ogólnie rzecz biorąc, nieco mniej skomplikowanymi.values %h
nie jest potrzebne, dlatego twoje rozwiązanie potrzebuje tylko 106 bajtów.Python
127 152B138BDostosowano tak, aby nie łamał już reguł i ma nieco bardziej skomplikowany algorytm. Dostosowano tak, aby był mniejszy
Starsza wersja:
Mój pierwszy skrypt w języku Python! Zobacz to w akcji: http://pythonfiddle.com/entropy
źródło
count
funkcji jest wręcz sprzeczne z regułami, ponieważ „zlicza liczbę wystąpień danego bloku x”.;
jeśli to konieczne). Również nawiasy kwadratowe w ostatnim wierszu nie są potrzebne.and 1 or 0
) Jest niepotrzebna. Możesz także zapisać niektóre postacie, wstępnie definiującrange(N)
.Python z Numpy,
146143 bajtówTak jak obiecałem, oto moje własne rozwiązanie. Wymaga wprowadzenia nieujemnych liczb całkowitych:
Wadą jest to, że powoduje to pęknięcie pamięci na dużą
m
lubmax(A)
.Oto najczęściej nieoznaczona i skomentowana wersja:
źródło
MATLAB
źródło