Hilfe! Ich habe mehr Hausaufgaben!

18

Mein Lehrer war mit meinen Mars-Hausaufgaben mehr als unzufrieden . Ich habe alle Regeln befolgt, aber sie sagt, dass das, was ich ausgegeben habe, Kauderwelsch war. Als sie es sich zum ersten Mal ansah, war sie höchst misstrauisch. "Alle Sprachen sollten Zipfs Gesetz folgen bla bla bla" ... Ich wusste nicht einmal, was Zipfs Gesetz war!

Es stellt sich heraus, dass Zipfs Gesetz besagt, dass, wenn Sie den Logarithmus der Häufigkeit jedes Wortes auf der y-Achse und den Logarithmus der "Stelle" jedes Wortes auf der x-Achse zeichnen (am häufigsten = 1, am zweithäufigsten = 2, dritthäufigstes Kommmon = 3 usw.), dann zeigt der Plot eine Linie mit einer Steigung von ungefähr -1, geben oder nehmen Sie ungefähr 10%.

Zum Beispiel ist hier eine Handlung für Moby Dick:

Bildbeschreibung hier eingeben

Die x-Achse ist das n -häufigste Wort, die y-Achse ist die Anzahl der Vorkommen des n -häufigsten Wortes. Die Steigung der Linie beträgt ca. -1,07.

Jetzt decken wir Venutian ab. Zum Glück benutzen die Venezianer das lateinische Alphabet. Die Regeln sind wie folgt:

  • Jedes Wort muss mindestens einen Vokal enthalten (a, e, i, o, u)
  • In jedem Wort können bis zu drei Vokale hintereinander stehen, jedoch nicht mehr als zwei Konsonanten hintereinander (ein Konsonant ist ein Buchstabe, der kein Vokal ist).
  • Keine Wörter länger als 15 Buchstaben
  • Optional: Gruppieren Sie Wörter in Sätzen mit einer Länge von 3-30 Wörtern, die durch Punkte getrennt sind

Da der Lehrer der Meinung ist, dass ich meine Mars-Hausaufgaben betrogen habe, wurde ich beauftragt, einen Aufsatz zu schreiben, der mindestens 30.000 Wörter lang ist (in venezianischer Sprache). Sie wird meine Arbeit anhand des Zipfschen Gesetzes überprüfen. Wenn also eine Linie (wie oben beschrieben) eingepasst ist, muss die Steigung höchstens -0,9, aber nicht weniger als -1,1 betragen, und sie möchte einen Wortschatz von mindestens 200 Wörtern. Das gleiche Wort sollte nicht mehr als 5 Mal hintereinander wiederholt werden.

Das ist CodeGolf, also gewinnt der kürzeste Code in Bytes. Bitte fügen Sie die Ausgabe in Pastebin oder ein anderes Tool ein, wo ich sie als Textdatei herunterladen kann.

J. Antonio Perez
quelle
Ja, und wenn Sie möchten, können Sie einen Satz mit 32767 Wörtern schreiben. Die Einschränkung besteht darin, dass die Häufigkeit der Wörter im Satz dem zipf-Gesetz entsprechen muss
J. Antonio Perez,
1
Das traditionelle Adjektiv für "from Venus" ist Veneral, aber aus irgendeinem Grund ist es weniger beliebt. Venusian wird häufig in Science-Fiction verwendet.
Peter Taylor
Ich vermute, dass das Bilden einer Liste von Wörtern nach der Zipf-Verteilung und das Mischen mit hoher Wahrscheinlichkeit eine Sequenz mit Paaren aufeinanderfolgender Wörter auch nach der Zipf-Verteilung erzeugen würde. Außerdem wäre die Wahrscheinlichkeit, dass dasselbe Wort mehr als fünf Mal hintereinander wiederholt wird, bei genügend verschiedenen Wörtern in der Liste sehr gering. Wenn ich diesen Ansatz ausprobiert und einen gültigen Aufsatz verfasst habe, wird er akzeptiert?
Leo
Ihre Vermutung ist vernünftig, obwohl die Steigung -0,35
J. Antonio Perez
Es würde immer noch wie eine gerade Linie aussehen; Es ist nur die Steigung wäre zu groß
J. Antonio Perez

Antworten:

3

Mathematica, 102 Bytes

""<>RandomChoice[1/Range@215->Rest@Flatten@Outer[StringJoin,a={"v","a","e","i","o","u"},a,a,{" "}],8!]

Unbenannte Funktion, die keine Eingabe annimmt und eine Zeichenfolge zurückgibt, die aus 40.320 venusianischen Wörtern mit drei Buchstaben und nachgestellten Leerzeichen besteht.

Outer[StringJoin,a={"v","a","e","i","o","u"},a,a,{" "}]erzeugt die 216 möglichen Wörter mit drei Buchstaben, wobei nur die Buchstaben "vaeiou" verwendet werden, von denen jedes ein eigenes nachgestelltes Leerzeichen hat. Das erste dieser Wörter, "vvv", ist kein gültiges venusianisches Wort, sondern Restwirft es weg.

Dann RandomChoice[1/Range@215->...,8!]macht 8! = 40.320 zufällige Auswahlen aus der resultierenden 215-Wort-Liste, wobei die Häufigkeitsgewichte durch die Kehrwerte der ersten 215 Ganzzahlen ( 1/Range@215) bestimmt werden. Schließlich <>""...verkettet die Zeichenfolgen in der Ergebnisliste.

Die Ausgabe ist alles andere als deterministisch; Ein Durchgang ergab diesen venusianischen Aufsatz .

Mathematica, 129 Bytes

#2&@@@Sort[Join@@Table[{i,Rest@Flatten@Outer[StringJoin,a={"v","a","e","i","o","u"},a,a,{" "}]~Part~j},{j,215},{i,0,1,j/7!}]]<>""

Dieser ist deterministisch. Die Basismenge von 215 Wörtern ist dieselbe, aber jetzt wird jedes Wort genau so oft wiederholt (Wort #j wird ungefähr 7! / J-mal wiederholt), damit das zipf-Gesetz gilt. Dann werden die Wörter gleichmäßig verschachtelt, um Wiederholungen zu vermeiden. (Stellen Sie sich vor, jedes Wort wird auf einem Lineal mit gleichem Abstand von allen Kopien dieses Wortes angeordnet. Wenn alle Wörter der Reihe nach gelesen werden, wiederholt sich kein bestimmtes Wort viel, vielleicht gar nicht.) Das Ergebnis ist ein 30.117-Wort Venusianischer Aufsatz .

Greg Martin
quelle
Macht nicht 8! Pseudozufallswahl bedeutet, dass Sie mit 6 aufeinanderfolgenden Wiederholungen desselben Wortes enden könnten?
Dennis
Ja, theoretisch.
Greg Martin
@ GregMartin Eigentlich ... ist der Essay, mit dem Sie verlinkt haben, nicht konform. vvaErscheint sechsmal hintereinander. Ich denke, es gibt möglicherweise ein größeres Problem ... sollten Sie nicht jedes Mal die Arbeit herausfordern? (Und wenn nicht, wie bestimmen Sie, wie wahrscheinlich es ist, dass sie arbeiten?)
H Walters,
Dies ist eine faire Kritik, und ich bin gespannt, wie sie sich auswirkt.
Greg Martin
2

05AB1E ,34 33 32 Bytes

525DL/9*vNy<FD}})žMDâžNâJè3ô.rðý

525DL                            Yield [1, ..., 525]
     /                           Yield [525/1, ..., 525/525]
      9*                         Yield [4725/1, ..., 4725/525]. It's the number of occurences of each word. The sum of this array is greater than 30000
        v                        For each value (y = value, N = iteration counter starting from 0)
         N                       Push iteration counter
          y<FD}                  Push an array of "int(value)" times the iteration counter
               }                 End for
                )                Wrap everything in an array. At this point the array countains the sorted indices of all words that matches the frequency specs
                 žM              Push "aeiou"
                   Dâ            Cartesian product with itself (["aa", "ae", ...])
                     žN          Push the consonants
                       âJ        Cartesian product and join the values to make valid venutian words
                         è       Compute a big string with all words that correspond to the formerly computed indices
                          3ô     Since all words are concatenated, separate them into blocks of 3 letters
                            .r   Shuffle
                              ðý Join with whitespaces and implicitly display

Probieren Sie es online!

Ich finde es ist immer noch ziemlich golffähig! Zum Beispiel vNy<FD}könnten die numerischen Konstanten und golfable sein.

Ausgabebeispiel

Wie funktioniert es?

Es werden alle Wortkombinationen nach der Regel "Vokal + Vokal + Konsonant" generiert, wodurch 525 eindeutige gültige Wörter (mehr als 200) erstellt werden. Dann ordnet es jedem von ihnen eine Frequenz zu, die dem Gesetz entspricht, f(x) = 4725/xwoxist der Rang des aktuellen Wortes, der bei 1 beginnt und bei 525 endet. Dann werden die Frequenzen normalisiert und multipliziert, so dass es mindestens 30000 Wörter gibt. Dieser Code ergibt immer 32074 Wörter, um die beteiligten Konstanten golfbar zu machen (siehe Code-Erklärung). So wird jedes Wort so oft wiederholt, wie es der Häufigkeit desselben Wortes entspricht. Schließlich werden die Wörter gemischt. Es kann jedoch nicht garantiert werden, dass ein Wort niemals fünf Mal hintereinander wiederholt wird. Daher erzeugt das Programm mehr als die benötigten 200 eindeutigen Wörter, um die Wahrscheinlichkeit zu verringern, dass ein Wort fünfmal hintereinander wiederholt wird. Bitte beachten Sie, dass dieser Code immer die gleiche Wortfolge generiert. Das einzige, was sich zwischen zwei Läufen unterscheidet, ist das Ergebnis des Mischvorgangs.

Wie bewerte ich die Frequenz?

Ich habe einen einfachen Python3-Code erstellt, der den Text in der Datei "output" (aus algorithmischer Sicht ist das sinnvoll!) Und die Ausgabe in "stats.csv" aufnimmt.

from collections import Counter
from math import log10

with open("output", "r") as f:
    with open("stats.csv", "w") as stats:
        words = f.read().split()
        freqs = Counter(words)
        freqs = sorted([(i,freqs[i]) for i in freqs],key=lambda x:-x[1])

        print(len(words), "words")
        stats.write("logX;logF\n")
        for i, (key, f) in enumerate(freqs):
            stats.write(str(log10(i+1))+";"+str(log10(f))+"\n")

Was für meinen Code immer die folgende Verteilung ergibt: Frequenzgesetz

Die Steigung beträgt also -1,0138. Dieser Wert liegt jetzt weniger nahe bei -1 als die Steigung des vorherigen Codes, erfüllt jedoch weiterhin die Steigungsbeschränkungen.

Osable
quelle
Vielen Dank, dass das Skript die Häufigkeit bewertet. Beachten Sie, dass Sie am Ende ein zusätzliches `haben. Warum verwenden Sie auch Semikolons als Trennzeichen? csv steht normalerweise für kommagetrennte Werte;)
Leo
1
Ja du hast recht haha! Ich war für eine Sekunde verwirrt von Abschriften. Ich habe zuerst Inline-Code verwendet und dann festgestellt, dass es sinnvoller ist, einen Codeblock zu verwenden, aber ich habe vergessen, den zusätzlichen Code zu entfernen. Ich benutze Semikolons als CSV-Trennzeichen, weil ich Franzose bin und einige Software- oder Firmen es gewohnt sind, Dezimalwerte mit Kommas anstelle von Punkten zu setzen, wie wir es mit handgeschriebenen Dezimalwerten tun. Obwohl ich immer den Punkt verwende, um den ganzzahligen Teil vom gebrochenen Teil zu trennen, verwende ich das Semikolon, ohne weiter darüber nachzudenken. Aber hey, ssv ist auch großartig;)
Osable
0

Bash / Core Utils, 122 110 Bytes

for w in {b,c,d}{a,e,i}{f,g,h}{o,u,a}{j,k,l};{ let ++x;yes $w|head -$[5575/x];}|shuf --random-source=<(yes ae)

Abgerollt:

for w in {b,c,d}{a,e,i}{f,g,h}{o,u,a}{j,k,l};{
    let ++x
    yes $w|head -$[5575/x]
}|shuf --random-source=<(yes ae)

Die for wSchleife erzeugt 243 verschiedene Wörter. let ++x;Inkremente setzen anfangs x nicht fest (Regeln für arithmetische Ausdrücke werden während dieser ersten Ausführung xals 0 behandelt, und daher wird sie durch ihr Inkrement auf 1 gesetzt). Die nächste Zeile erzeugt somit aufeinanderfolgende Wörter mit einer Frequenz von 5575 / x, um die Zipf-Frequenz zu approximieren.

Der nächste Schritt besteht darin, dies deterministisch zu permutieren, um die Wiederholungsanforderung zu erfüllen; Obwohl --random-sourcees sich um einen furchtbar großen Flaggennamen handelt, übertrifft die Verwendung mit shuf die Zeichenanzahl der Hand, die einen Mul-Mod-Selektor rollt. yes aeist eigentlich das kürzeste festgelegte "zufällige" Gerät, das ich als konform befunden habe.

Dies erzeugt diesen 33729-Wort-Aufsatz [Pastebin] .

Bash / Core Utils, 96 84 Bytes (nicht konkurrierend)

Für einen nicht-deterministischen Ansatz hacken Sie einfach die Shuf-Flags ab:

for w in {b,c,d}{a,e,i}{f,g,h}{o,u,a}{j,k,l};{ let ++x;yes $w|head -$[5575/x];}|shuf

Analyse

Die Zipf-Neigung ist so eingestellt, dass sie gerade ist. Verwenden von Excel zum Zeichnen auf logarithmischen Skalen:

Der Lehrer sollte eine zipf-Steigung von = -1.000764 bemerken.

H Walters
quelle