Hinweis : Gemäß Konsens über Meta , Challenge-Response-Schreiben Fragen zum Thema finden Sie hier.
Angesichts dieser "Sache, die man beim Schreiben von Herausforderungen vermeiden sollte" , begann ich über Herausforderungen nachzudenken, bei denen bestimmte Arten von Objekten zufällig generiert wurden.
Es kommt manchmal vor, dass ich eine Code-Golf- Herausforderung posten möchte , bei der zufällig ein Foo generiert wird
- Es ist sehr einfach zu überprüfen, ob eine bestimmte Sache ein Foo ist, und
- Es ist etwas schwieriger, schnell einen zufälligen Foo mit "guter Qualität" zu generieren.
Zum Beispiel könnte ein foo eine binäre Matrix sein, in der es in keiner Richtung Segmente mit 4 gleichen Bits gibt. Es ist leicht zu überprüfen, ob eine gegebene binäre Matrix ein Foo ist, aber das Erzeugen eines zufälligen Foo mit einer gut verteilten Verteilung scheint einen Backtracking-Algorithmus oder etwas Ähnliches zu erfordern.
Wie auch immer, jetzt muss ich objektiv angeben, was als zufälliges Foo zu bezeichnen ist, und ich möchte, dass es in dem intuitiven Sinne "unvorhersehbar" ist, dass die Ergebnisse immer unterschiedlich aussehen, wenn ich das Programm mehrmals ausführe. Der restriktivste Ansatz besteht darin, eine gleichmäßig zufällige Ausgabe zu verlangen: Alle gültigen Foos haben die gleiche Wahrscheinlichkeit, generiert zu werden. Dies ist in der Regel zu restriktiv, da ich keine Ahnung habe, wie es gemacht werden soll, um alle gültigen Foos zu generieren, Duplikate zu entfernen und eines auszuwählen, das langweilig und langsam ist.
Meine nächste Idee ist, vorauszusetzen, dass alle gültigen Foos eine positive Wahrscheinlichkeit haben, generiert zu werden. Dies bedeutet jedoch, dass der folgende Ansatz gültig ist: Erzeugen Sie ein zufälliges foo-ähnliches Objekt (in unserem Beispiel eine zufällige binäre Matrix). Wenn es ein foo ist, geben Sie es zurück, andernfalls geben Sie ein fest codiertes foo zurück (z. B. die Identitätsmatrix) ). Dies ist auch etwas langweilig, da es im Grunde nur ein Erkennungsmerkmal für Foos ist, die an einem Zufallsmatrixgenerator befestigt sind.
Könnte es eine schöne allgemeine Definition für ein unvorhersehbares zufälliges Foo geben?
TL; DR
Gibt es eine gute Möglichkeit, ein "unvorhersehbares" zufällig generiertes Objekt anzugeben, das die Verteilung nicht repariert, aber von der Hardcodierung abhält?
Antworten:
Gib tausend verschiedene Foos zurück
Dies macht es unmöglich, fest codierte Werte zurückzugeben und ein halbwegs anständiges Golf zu haben. Ein legitimer Foo-Generator hat jedoch eine geringe Chance, doppelte Foos auszugeben, es sei denn, er überprüft sie tatsächlich. Um die Last der Überprüfung zu beseitigen, könnte eine empirisch getestete Fehlerrate von beispielsweise 10% als akzeptabel angegeben werden.
Beachten Sie das Geburtstagsparadoxon , dass die Wahrscheinlichkeit von Duplikaten höher sein kann, als Sie denken. Wenn es nur eine Million mögliche Foos gibt, haben tausend zufällige Foos eine Wahrscheinlichkeit von ungefähr 0,6, dass sich irgendwo ein Duplikat befindet, und das unter der Annahme, dass die FOO-Erzeugung völlig gleichmäßig ist. Wenn dies ein Problem sein könnte, benötigen Sie 900 eindeutige Foos pro 1000 generierte, was für einen echten Foo-Generator weitaus großzügiger ist, für die Hardcodierung jedoch immer noch unpraktisch.
Dies ermöglicht Ihnen auch, wiederholt foo-ähnliche Dinge zu generieren und Fooness zu überprüfen, bis Sie Foos bekommen. Ich denke, das ist eine gültige Lösung, aber wenn Sie es nicht mögen:
Mach es schnell
Die Wahrscheinlichkeit, dass eine völlig zufällige foo-artige Sache foo ist, ist wahrscheinlich sehr gering. Die Angabe eines Zeitlimits erzwingt also wahrscheinlich einen echten Versuch, foo zu generieren.
Um die Geschwindigkeitsunterschiede zwischen verschiedenen Sprachen auszugleichen, möchten Sie möglicherweise unterschiedliche Zeitlimits festlegen, abhängig von der Sprache wie Hackerrank: https://www.hackerrank.com/environment . Wenn Sie jedoch groß genug angeben, ist die Wahrscheinlichkeit, dass zufällige foo-ähnliche Dinge foo werden, sehr gering. Daher ist möglicherweise eine Regel "vor dem Tod des Universums" ausreichend.
quelle
Ich behaupte nicht, die ultimative Lösung für das Problem zu haben (oder dass diese Liste vollständig ist), aber ich möchte einige mögliche Ansätze skizzieren, die mir in den Sinn kommen und warum sie funktionieren würden oder nicht. Ich werde auch nicht auf tangentiale Probleme eingehen, wie die Frage, ob die Verwendung des aktuellen Zeitstempels als Zufallsquelle ausreichend "unvorhersehbar" ist und wie bestimmte Eigenschaften der Wahrscheinlichkeitsverteilung erzwungen werden können. Ich werde mich nur darauf konzentrieren, Lösungen zu vermeiden, die Hardcoding verwenden.
Keine Lösung: Festcodierung explizit nicht zulassen
Das ist eine schlechte Idee. Es ist eine nicht beobachtbare Anforderung (was bedeutet, dass Sie nicht feststellen können, ob sie nur durch Ausführen des Programms erfüllt ist), von der in PPCG dringend abgeraten wird und die möglicherweise völlig unmöglich ist, wenn das Programm auf einer anderen Plattform ausgeführt wird, auf der die Einreichungen in einem verifiziert werden automatisierte Weise. Das Problem bei einer solchen Anforderung ist, dass Sie zunächst eine objektive Definition für "Hardcodierung" finden müssen. Wenn Sie dies versuchen, werden Sie die Dinge im Allgemeinen nur noch schlimmer machen.
Mach Hard-Coding unmöglich
Wenn Sie es nicht vollständig verbieten können, aber nicht möchten, dass Benutzer es verwenden, können Sie versuchen, die Herausforderung so zu gestalten, dass Hardcodierung einfach kein wettbewerbsorientierter Ansatz ist. Dies ist möglich, wenn die Objekte, die generiert werden sollen, ausreichend groß und inkomprimierbar sind, sodass das Einfügen eines Beispiels in den Code viel mehr Bytes erfordert als das Schreiben eines Algorithmus, der zufällig gültige Lösungen generiert. In Ihrem speziellen Beispiel ist dies natürlich nicht der Fall, da Identitätsmatrizen gültig und im Allgemeinen leicht zu generieren sind. Bei anderen Problemen ist dies möglicherweise nicht der Fall. Wenn die Zielobjekte ausreichend unregelmäßig sind, müssen sie nur eine große Größe haben, was wahrscheinlich die Byteanzahl eines tatsächlichen Algorithmus nicht beeinflusst, aber den hartcodierten Teil in die Luft sprengt.
Ausgang parametrieren
Häufig hängen diese Probleme mit einem oder mehreren natürlichen Parametern zusammen, z. B. der Größe der Matrix in Ihrem Beispiel. In diesem Fall kann die Eingabe dieses Parameters ausreichen, um eine harte Codierung unmöglich oder zumindest unpraktisch zu machen. In einigen Fällen ist es möglicherweise einfach, eine bestimmte Lösung für einen bestimmten Parameterwert, der manuell oder über eine umfangreiche Suche gefunden wurde, fest zu codieren. Es gibt jedoch möglicherweise keine einfache geschlossene Form für eine Instanz dieser Lösung im Allgemeinen, sodass dies nicht der Fall ist leicht einen Standardwert für beliebige Eingaben zu generieren. Auch dies ist für das von Ihnen erwähnte Beispiel nicht der Fall, da die Identitätsmatrix in jeder Größe funktioniert, sondern eine optimale Lösung für dieses verwandte Problemist normalerweise sehr unregelmäßig, daher ist es nicht möglich, einen Standardwert zu haben, ohne aktiv nach gültigen Werten zu suchen. Sie können dies mit einem Zeitlimit kombinieren, um eine Brute-Force-Suche nach einem Standardwert zu vermeiden.
Legen Sie eine Beschränkung für die Wahrscheinlichkeitsverteilung
Wenn Sie bereit sind, auf eine völlig uneingeschränkte Wahrscheinlichkeitsverteilung zu verzichten, können Sie einige Einschränkungen festlegen, die den Antwortenden noch viel Freiheit bei der Auswahl ihrer Verteilung einräumen, die das Hardcodieren jedoch erschweren oder unmöglich machen:
Das Hauptproblem bei diesen Ansätzen ist, dass es viel schwieriger ist, darüber nachzudenken, dass es schwierig ist, die Richtigkeit der Antworten zu beweisen, und das experimentelle Überprüfen der Richtigkeit kann für große Ausgaberäume unmöglich sein. Dennoch stellen sie eine grundsätzlich beobachtbare Anforderung an das Programm dar, die eine Hardcodierung unmöglich machen kann.
Diese Ansätze können auch eine zeitliche Begrenzung erfordern, da eine Möglichkeit zur Erhöhung der Wahrscheinlichkeit der Nicht-Standardwerte darin besteht, zu versuchen, ein zufälliges foo mehrmals zu finden, bevor auf den Standardwert zurückgegriffen wird.
quelle