Bewerten Sie einen Minimax-Baum


16

Alice und Bob spielen ein kleines Spiel. Zuerst zeichnen sie einen Baum von einem Wurzelknoten (angezeigt durch einen dicken Punkt) ohne interne Knoten mit Zahlen an den Blättern. Jeder Knoten kann eine beliebige Anzahl von untergeordneten Knoten haben.

Baum

Wir beginnen an der Wurzel und spielen zuerst Alice (A). Sie muss eines der untergeordneten Elemente des aktuellen Knotens auswählen. Dann ist Bob an der Reihe und wählt auf ähnliche Weise einen untergeordneten Knoten aus. Dies wird fortgesetzt, bis ein Blattknoten erreicht ist.

Wenn ein Blattknoten erreicht ist, ist das Spiel beendet. Es ist Alices Ziel, an einem Knoten mit einem möglichst großen Wert zu enden, und Bobs Ziel, an einem Knoten mit einem möglichst kleinen Wert zu enden.

Geben Sie bei einem Baum in Form eines verschachtelten Arrays den Wert des Blatts zurück, der erreicht wird, wenn sowohl Alice als auch Bob perfekt spielen.


Beispiele:

18: [[67, [[100, [[67, 47], [86], 21, 16], [[46, [14], 35, 85], [71, [18, 63, 69], 99, 22], 3]]], [[18, 32, 42, 80]], [[36, 70], [86, 53, 46, 59], [[41], 86, 35]]], 3]
60: [[[84, 35], [44, 60]], [[24, 98], [16, 21]]]
58: [[53, 77], [58, [82, 41]], 52]
59: [[93, [100, 53], 58, 79], [63, 94, 59], [9, [55, 48]], [40, 10, 32]]
56: [[20, 10, [[[89, 22, 77, 10], 55], [24, 28, 30, 63]]], [[49, 31]], 17, 56]
0: [0]

Sie können davon ausgehen, dass der Stammknoten niemals ein Blattknoten ist und auf mindestens einen Blattknoten verweist. Sie können davon ausgehen, dass Blätter nichtnegative Zahlen sind.


Kürzester Code in Bytes gewinnt.


Antworten:


2

Gelee , 7 Bytes

N߀¬¡ṂN

Probieren Sie es online! oder überprüfen Sie alle Testfälle .

Dies verwendet den Algorithmus aus der Antwort von @ xnor . Zu Vergleichszwecken wiegt ein einfacher Ansatz, der abwechselnd Minima und Maxima berechnet, 8 Bytes :

߀¬¡€Ṃ€Ṁ

Wie es funktioniert

N߀¬¡ṂN  Main link. Argument: x (array or integer)

N        Negate. For an array, this negates all integers in it.
   ¬     Logical NOT. For an array, this applies to all integers in it.
    ¡    Apply the second link to the left once if ¬ returned an array or 1, or not
         at all if it returned 0.
 ߀      Recursively call the main link on all elements at depth 1 of -x.
         If -x == 0, € will cast 0 to range before mapping ß over it. 
         Since the range of 0 is [], mapping ß over it simply yields [].
     Ṃ   Minimum.
         For an integer, Ṃ simply returns the integer. For [], Ṃ returns 0.
      N  Negate the minimum.

8

Python 2, 53 Bytes

f=lambda l,c=1:c*l if l<[]else-min(f(x,-c)for x in l)

Die Hauptfrage ist, wie zwischen maxund minjeder Schicht gewechselt werden soll. Mit der Tatsache, dass max(l) == -min([-x for x in l])wir stattdessen jede zweite Ebene negieren und mit rekursieren -min. Um jede zweite Schicht zunichte machen, geben wir einen Multiplikator nach unten , cdass wechselt +1und -1, und , wenn wir ein Blatt erreichen, wir seinen Wert durch den Multiplikator einzustellen. Wir erkennen an der Bedingung l<[], dass wir an einem Blatt sind , da Python 2 Zahlen als weniger als Listen behandelt.

Es ist schwierig, den else/ifternären Wert zu verkürzen, da jeder Zweig einen Wahrheitswert (ungleich Null) oder einen Falschwert (Null) liefern kann.


1

JavaScript (ES6), 53 Byte

f=(a,s=1)=>a.map?s*Math.max(...a.map(b=>s*f(b,-s))):a

Verwendet einen ähnlichen Ansatz wie die Antwort von @ xnor. Wenn die Zahlen ungleich Null sind, dann nur 49 Bytes:

f=(a,s=1)=>+a||s*Math.max(...a.map(b=>s*f(b,-s)))

1

Pyth, 21 Bytes

M?sIG*GH_hSmgd_HGLgb1

Meine erste Pyth-Antwort! Danke an Dennis für die Hilfe :).

M                      # define a binary function (G, H)
 ?sIG                  # if G (first argument) is the same with s applied
                       # (check if it's an integer, so, a leaf node)
     *GH               # in such a case, calculate G*H
        _              # negation
         hS            # take the first element of the sorted list (that's the min)
           mgd_HG      # map over G, applying ourself (g) recursively,
                       # with the current lambda's value (d)
                       # and the negation of H
                 Lgb1  # Define a unary function to call our previous
                       # one with the correct base argument (1)

Für diese Map gibt es eine kürzere Syntax: mgd_Hkann sein gR_H. Auch stattdessen eine Funktion definieren , können Sie nehmen Eingang mit Qund ersetzen Lgb1mit gQ1.
Lirtosiast

1

Mathematica, 13 Bytes

-Min[#0/@-#]&

oder äquivalent

Max[-#0/@-#]&

Dies ergibt eine unbenannte Funktion, die den Baum aufnimmt und das Ergebnis zurückgibt.

Dies entspricht im Wesentlichen auch der Lösung von xnor: Auf jeder Ebene tauschen wir das Vorzeichen der Liste und das Ergebnis aus und verwenden es Minganz nach unten. Dies stellte sich in Mathematica als unglaublich golfen heraus, weil:

  • MinEs können entweder einzelne Nummern oder Listen oder auch mehrere Listen verwendet werden. Es gibt Ihnen nur den Mindestwert für alle Argumente. Das heißt, es funktioniert sowohl auf Listen als auch auf Blättern (wobei es nur das Blatt zurückgibt).
  • /@was kurz für Mapist, ist eine sehr allgemeine Funktion höherer Ordnung in Mathematica. Es ordnet eine Funktion nicht nur Listen zu, sondern kann sie jedem beliebigen Ausdruck zuordnen. Zahlen sind ein solcher Ausdruck, enthalten jedoch keine Elemente, die zugeordnet werden müssen. Das heißt, wir können jede Funktion sicher auf Zahlen abbilden, was sich überhaupt nicht auf die Zahl auswirkt.

Beides zusammen bedeutet, dass wir den Code ohne Bedingungen schreiben können, da die Operationen Minund Mapkeine Operationen für Zahlen sind. Anschließend heben sich die beiden Negationen auf, sodass die Funktion die Identität wird, wenn eine Zahl vergeben wird.

Schließlich ist es dank#0 Mathematica möglich, unbenannte rekursive Funktionen zu schreiben, wodurch einige Bytes mehr gespart werden.


0

Ruby, 46 Bytes

Benutzt @ xnors Trick mit, minum zwischen max und min zu wechseln.

f=->n,a=1{n==[*n]?-n.map{|c|f[c,-a]}.min: a*n}

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.