Ich musste einmal eine Funktion schreiben, die die Blockentropie einer bestimmten Symbolserie für eine bestimmte Blockgröße berechnet, und war überrascht, wie kurz das Ergebnis war. Daher fordere ich Sie heraus, eine solche Funktion zu codegolfen. Ich erzähle Ihnen nicht, was ich im Moment getan habe (und in welcher Sprache), aber ich werde es in einer Woche oder so tun, wenn niemand zuerst die gleichen oder bessere Ideen hat.
Definition der Blockentropie:
Ausgehend von einer Symbolfolge A = A_1,…, A_n und einer Blockgröße m:
- Ein Block der Größe m ist ein Segment von m aufeinanderfolgenden Elementen der Symbolsequenz, dh A_i, ..., A_ (i + m - 1) für jedes geeignete i.
- Wenn x eine Symbolfolge der Größe m ist, bezeichnet N (x) die Anzahl von Blöcken von A, die mit x identisch sind.
- p (x) ist die Wahrscheinlichkeit, dass ein Block aus A mit einer Symbolfolge x der Größe m identisch ist, dh p (x) = N (x) / (n - m + 1)
- Schließlich ist die Blockentropie für die Blockgröße m von A der Durchschnitt von –log (p (x)) über alle Blöcke x der Größe m in A oder (was äquivalent ist) die Summe von –p (x) · log (p (x)) über jedes x der Größe m in A. (Sie können einen beliebigen sinnvollen Logarithmus wählen.)
Einschränkungen und Klarstellungen:
- Ihre Funktion sollte die Symbolfolge A sowie die Blockgröße m als Argument verwenden.
- Sie können davon ausgehen, dass die Symbole als Ganzzahlen auf Nullbasis oder in einem anderen geeigneten Format dargestellt werden.
- Ihr Programm sollte in der Lage sein, theoretisch alle vernünftigen Argumente aufzunehmen, und in der Realität sollte es in der Lage sein, den Beispielfall (siehe unten) auf einem Standardcomputer zu berechnen.
- Eingebaute Funktionen und Bibliotheken sind zulässig, solange sie nicht große Teile der Prozedur in einem Aufruf ausführen, dh alle Blöcke der Größe m aus A extrahieren, die Anzahl der Vorkommen eines bestimmten Blocks x zählen oder die Entropien berechnen aus einer Folge von p-Werten - diese Dinge müssen Sie selbst tun.
Prüfung:
[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]
Die ersten Blockentropien dieser Sequenz sind (für den natürlichen Logarithmus):
- 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)))
.Antworten:
Mathematica -
8178757267656256 BytesIch habe noch nie in Mathematica Golf gespielt, daher gibt es wahrscheinlich noch Verbesserungspotenzial. Dieser entspricht aufgrund der
Partition
undTally
Funktionen nicht ganz den Regeln , ist aber recht ordentlich, so dass ich dachte, ich würde ihn trotzdem posten.Dies funktioniert mit jedem Satz von Symbolen und kann wie folgt verwendet werden
Hier ist eine etwas ungolfed Version:
Es wird wahrscheinlich schneller laufen, wenn ich mich
N
direkt auf das Ergebnis von bewerbeTally
.Übrigens hat Mathematica tatsächlich eine
Entropy
Funktion, die dies auf 28 Byte reduziert , aber das verstößt definitiv gegen die Regeln.Auf der anderen Seite gibt es hier eine 128-Byte- Version, die neu implementiert
Partition
undTally
:Ungolfed:
quelle
Partition
undTally
sind keine Grenzfälle, sie brechen die Regeln geradezu, da sie "alle Blöcke der Größe m aus A extrahieren" und "die Anzahl der Vorkommen eines bestimmten Blocks x zählen" in einem Aufruf. Nach allem, was ich über Mathematica weiß, wäre ich nicht überrascht, wenn es ohne sie eine vernünftige Lösung gäbe.Partition
undTally
.Perl, 140 Bytes
Das folgende Perl-Skript definiert eine Funktion
E
, die die Symbolsequenz gefolgt von der Segmentgröße als Argument verwendet.Ungolfed Version mit Test
Ergebnis:
Symbole:
Die Symbole sind nicht auf Ganzzahlen beschränkt, da ein auf Zeichenfolgen basierender Mustervergleich verwendet wird. Die Zeichenfolgendarstellung eines Symbols darf kein Komma enthalten, da es als Trennzeichen verwendet wird. Natürlich müssen verschiedene Symbole unterschiedliche Zeichenfolgendarstellungen haben.
In der Golfversion sollte die Zeichenfolgendarstellung der Symbole keine Sonderzeichen von Mustern enthalten. Die zusätzlichen vier Bytes
\Q
...\E
werden für Zahlen nicht benötigt.quelle
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}
; wo$s
ist ein Verweis,$r
und%h
werden mit 1. Zuweisung auf undef zurückgesetzt , Listen sind Hash-Schlüssel (mit etwas Hilfe von$;
und einigenx
- leider) und etwas weniger kompliziert im Allgemeinen, denke ich.values %h
wird nicht benötigt, daher benötigt Ihre Lösung nur 106 Bytes.Python
127 152B138BAngepasst, um die Regeln nicht mehr zu brechen und einen etwas niedlicheren Algorithmus zu haben. Angepasst, um kleiner zu sein
Ältere Version:
Mein erstes Python-Skript! Sehen Sie es in Aktion: http://pythonfiddle.com/entropy
quelle
count
ist das nett , aber leider verstößt die Verwendung der Funktion direkt gegen die Regeln, da sie "die Anzahl der Vorkommen eines bestimmten Blocks x zählt".;
ggf. durch Trennzeichen getrennt ). Auch die eckigen Klammern in der letzten Zeile werden nicht benötigt.and 1 or 0
) ist nicht erforderlich. Sie können auch einige Zeichen speichern, indem Sie diese vordefinierenrange(N)
.Python mit Numpy,
146143 BytesWie versprochen, hier ist meine eigene Lösung. Es erfordert die Eingabe von nicht negativen ganzen Zahlen:
Der Nachteil ist, dass dies Ihr Gedächtnis für eine große
m
oder platztmax(A)
.Hier ist die meist ungolfed und kommentierte Version:
quelle
MATLAB
quelle