Sie paddeln mit einem Kanu einen ziemlich schnellen Wildwasserfluss hinunter. Plötzlich explodieren Ihre Paddel und Sie befinden sich in einer gefährlichen Situation, die schnell und ohne Paddel den Fluss hinunter rast. Zum Glück haben Sie noch Programmierkenntnisse und beschließen, ein Programm neben Ihrem Kanu zu erstellen, um die Stromschnellen zu überstehen. Es gibt jedoch nicht viel Fläche an der Seite des Kanus, mit der Sie Ihr Programm schreiben können. Daher müssen Sie das Programm so kurz wie möglich halten.
Der Fluss kann als 8 mal 16 Raster dargestellt werden. Wir werden die Spalten mit den Zahlen 0
bis 7
und die Zeilen mit den Zahlen 0
bis beschriften 15
.
y
--------15
--------14
--------13
--------12
--------11
--------10
--------9
--------8
--------7
--------6
--------5
--------4
--------3
--------2
--------1
--------0
01234567
x
Oben: Ein völlig ruhiger, gewöhnlicher Fluss ohne Hindernisse. Dies ist natürlich nicht der Fluss, auf dem Sie sich befinden.
Sie beginnen an der Koordinate (4, 0) und bewegen sich von dort unkontrolliert den Fluss hinauf (dh den Vektor (0,1)
), bis Sie auf einen Felsen stoßen ( o
in diesen Beispielen durch dargestellt). Wenn Sie auf einen Felsen stoßen, haben Sie eine 55% ige Chance, links am Felsen (dh am Vektor (-1,1)
) vorbeizukommen, und eine 45% ige Chance, rechts am Felsen (dh am Vektor (1,1)
) vorbeizukommen . Befindet sich das Kanu in der linken oder rechten Spalte, bewegt es sich immer in die Mitte. Wenn es keine Steine gibt, bewegt es sich gerade nach oben.
y
----x---15
----xo--14
-o--x---13
----x---12
---ox---11
---x----10
---xo---9
---ox---8
----xo--7
-----x--6
----ox--5
-o--x---4
----x---3
----xo--2
----x---1
----x---0
01234567
Oben: Eine mögliche Route, die das Kanu nehmen könnte, dargestellt anhand des Zeichens x
Schreiben Sie auf der Karte des Flusses ein Programm, das die Wahrscheinlichkeit ausgibt, dass das Kanu an einer bestimmten Spalte endet.
Akzeptieren Sie Eingaben in einer für Ihr Programm geeigneten Methode (z. B. STDIN, Befehlszeilenargument raw_input()
, Lesen aus einer Datei usw.). Der erste Teil der Eingabe ist eine einzelne Ganzzahl von 0 bis 7, die die Spalte darstellt, für die das Programm die Wahrscheinlichkeit findet. Darauf folgt eine Liste von Tupeln in der Form, x,y
die die Position der Steine darstellen.
Ein Beispiel:
Eingang:
4 4,1 5,5 3,5
Dies würde einen Fluss mit Steinen an den Positionen (4,1), (5,5) und (3,5) anzeigen und nach der Wahrscheinlichkeit fragen, dass das Kanu an der 4. Säule endet.
Ausgabe:
0.495
Beachten Sie, dass in diesem Beispiel die Positionen der Gesteine symmetrisch waren, sodass das Problem mit einer Binomialverteilung gelöst werden konnte. Dies wird nicht immer der Fall sein!
Auch der Fluss wird immer überquerbar sein. Das heißt, es wird niemals zwei Felsen geben, die horizontal nebeneinander liegen. Ein Beispiel für einen unmöglichen Fall finden Sie in Glenns Kommentar .
Dies ist Codegolf, daher gewinnt die niedrigste Anzahl von Zeichen. Fühlen Sie sich frei, Fragen in den Kommentaren zu stellen, wenn die Spezifikation nicht klar ist.
Antworten:
GolfScript, 105 Zeichen
Eine GolfScript-Version, die viel länger wurde als beabsichtigt - aber jeder Versuch mit einer anderen Herangehensweise war noch länger. Die Eingabe muss auf STDIN erfolgen.
Beispiel:
Kommentierter Code:
quelle
Ruby,
204191172 ZeichenEs simuliert rekursiv alle möglichen Ergebnisse und verfolgt dabei die Wahrscheinlichkeit jedes einzelnen Ergebnisses. Diese Wahrscheinlichkeit wird dann zu einem kumulativen Zähler addiert, wenn
y == 15
.Ausgefallene Tricks:
c,*r=gets.split
- Der "splat" -Operator (*
) nimmt alle verbleibenden Elemente vongets.split
und fügt sie in dasr
Array einnext {something} if {condition}
: im Wesentlichen gleichwertig mit"Entdeckt" durch die Entwicklung vonif condition; something; return; end
nachreturn something if condition
nachbreak something if condition
, und dann dachte ich, ich würde einen kürzeren "Schleifenoperator" ausprobieren, um zu sehen, ob es funktionieren würde (was es natürlich tat).Vielen Dank an @ MartinBüttner, der vorgeschlagen hat, verkettete ternäre Operatoren zu verwenden (die letztendlich die enorme dritte Zeile im oben genannten Code darstellen) und den oben genannten Punkt zu eliminieren (der 19 (!) Zeichen sparte).
Bei diesen habe ich allerdings einen etwas ausgefallenen Trick angewendet: Mir ist aufgefallen, dass
s[foo],s[bar]
das in Ruby für zwei Methodenaufrufe in einer Anweisung nicht funktioniert. Also zuerst habe ich es zu(_=s[foo],s[bar])
(einer Dummy - Variablen), aber dann merkte ich , ich konnte einfach hinzufügen und die Rückgabewerte wegzuwerfen:s[foo]+s[bar]
. Dies funktioniert nur, weil Anrufe ans
immer nur andere Anrufe ans
oder eine Nummer (o[x]+=p
) "zurückgeben" , so dass ich mich nicht darum kümmern muss, nach zu suchennil
.Andere verschiedene Optimierungen:
p
anstattputs
zum Drucken von Zahlen,<1
anstatt==0
(da das Kanu niemals den Fluss verlässt) und ähnliche Vergleiche an anderer Stelle,[0]*8
für anfängliche Wahrscheinlichkeiten, da Rubys Zahlen immer "vorbeigehende Werte" sindUngolfed:
quelle
next X if Y
in verschachtelten ternären Operatoren zusammenzufassen? Eine schöne Entdeckung, vielleicht möchten Sie sie zu den Ruby-Tipps hinzufügen!C #
418364 ByteVollständiges C # -Programm erwartet Eingabe von STDIN. Liest die Felsen in ein Array aller Stellen im Fluss ein, erstellt effektiv eine Karte und führt dann nur 16 Iterationen von Bewegungswahrscheinlichkeiten um ein 8-stelliges Dezimalarray durch, bevor das Ergebnis ausgegeben wird.
Formatierter Code:
quelle
for(;j-->0;)
). Sie können jedoch einige Zeichen entfernen, indem Sie das letzteC.WriteLine
durch ersetzenC.Write
. Wenn Siefloat
stattdessen verwendendecimal
, können Sie auch ein paar weitere Bytes sparen.decimal
weilfloat
nicht genau sein wird, aber Dezimal sollte für diese Probleme tun, könnte aber wahrscheinlich damit durchkommen, wie Sie sagen. Ich setze ein,C.Write
wenn ich es schaffe, weiter Golf zu spielen, da es wahrscheinlich näher an der Spezifikation liegt alsC.WriteLine
ich denke, dass 4 Bytes keine Bearbeitung für dieses GrößenprogrammHaskell, 256 Bytes
Hier ist eine sehr ungolfed Version zusammen mit einigen Tricks, die verwendet wurden:
Der letzte Trick, den ich verwendet habe, war zu bemerken, dass man so tun kann, als ob Steine in einer einzelnen Reihe tatsächlich durch einen infinitesimalen Betrag getrennt sind. Mit anderen Worten, Sie können den Wahrscheinlichkeitsverteilungstransformator für jeden Stein in derselben Reihe nacheinander und in beliebiger Reihenfolge anwenden, anstatt sie alle gleichzeitig anzuwenden. Dies funktioniert nur, weil das Problem zwei horizontal benachbarte Felsen nicht zulässt.
Das Programm wandelt also die Position jedes Felsens in einen Wahrscheinlichkeitsverteilungstransformator um, der nach der y-Koordinate des Felsens geordnet ist. Die Transformatoren werden dann nur der Reihe nach verkettet und auf die anfängliche Wahrscheinlichkeitsverteilung angewendet. Und das ist das!
quelle
Perl 169 Bytes
Liest von STDIN.
Ganz einfach, verwendet implizit die Spalten -1 und 8, um Grenzfälle zu glätten. Wahrscheinlichkeiten können sicher auf jede nächste Ebene übertragen werden, da keine angrenzenden Steine vorhanden sind und somit ein einziger Durchgang ausreicht.
quelle
PHP, 358
Das Ermitteln der möglichen Pfade und ihrer Wahrscheinlichkeiten mithilfe von Brainpower ist schwierig und würde wahrscheinlich mehr Code erfordern, als nur 1.000.000 Kanuunfälle zu simulieren. Oh die Menschlichkeit!
Beispiel:
Golf gespielt:
Diese Version druckt nicht besonders gut und gibt die Wahrscheinlichkeit aus, dass das Kanu an der angegebenen Position landet.
quelle
PHP, 274
Ich kann GolfScript nicht lesen / schreiben, um mein Leben zu retten, aber ein Blick über @ Howards Beitrag zeigte mir eine bessere Richtung, als nur 1 Million Kanuunfälle zu simulieren.
Ausgehend von einer Reihe von Wahrscheinlichkeiten für Startpositionen können wir diese Zahlen einfach bei jedem Auftreffen auf einen Stein aufteilen.
Beispielausgabe:
Golf gespielt:
Beispiellauf:
quelle
Haskell, 237
Ich hoffe nur, das Kanu kommt mit Ghc installiert ...
Der Trick mit der unendlichen Liste ist Matt Noonan gestohlen, ein großes Lob an ihn!
Ich hoffe, ich habe die Logik richtig verstanden, aber Matts Beispiel
"5 4,4 1,5 5,3 3,6 2,9 4,12 3,13"
liefert0.5613750000000001
und OPs Beispiel"4 4,1 5,5 3,5"
liefert0.49500000000000005
, was abgesehen von einigen Gleitkommafehlern korrekt zu sein scheint.Hier ist es in Aktion:
quelle