Mathematica, 65 Bytes
f[a___,x_,b___]/;NestList[2#-1&,a~Min~b/. 2->0,4]~SubsetQ~{a,b}=x
Dies definiert eine Funktion, f
die mit 5 Argumenten aufgerufen werden soll, z
f[5, 9, 17, 33, 829]
Grundsätzlich kann die Funktion mit einer beliebigen Anzahl von Argumenten (ungleich Null) aufgerufen werden, es kann jedoch zu unerwarteten Ergebnissen kommen ...
Ich denke, dies ist das erste Mal, dass es mir gelungen ist, die gesamte Lösung für eine nicht triviale Herausforderung in die linke Seite von a zu stellen =
.
Erläuterung
Mit dieser Lösung können die Pattern Matching-Funktionen von Mathematica wirklich für uns eingesetzt werden. Das grundlegende Merkmal, das wir verwenden, ist, dass Mathematica nicht nur einfache Funktionen wie definieren kann, f[x_] := (* some expression in x *)
sondern auf der linken Seite beliebig komplexe Muster verwenden kann, z. B. f[{a_, b_}, x_?OddQ] := ...
eine Definition hinzufügen würde, f
die nur verwendet wird, wenn sie mit einem Zwei-Element aufgerufen wird Liste und eine ungerade ganze Zahl. Zweckmäßigerweise können wir Elementen bereits Namen geben, die sich beliebig weit unten auf der linken Seite des Ausdrucks befinden (z. B. könnten wir im letzten Beispiel sofort auf die beiden Listenelemente als a
und verweisen b
).
Das Muster, das wir in dieser Herausforderung verwenden, ist f[a___,x_,b___]
. Hier a___
und b___
sind Folgen von null oder mehr Argumenten und x
ist ein einzelnes Argument. Da die rechte Seite der Definition einfach ist x
, möchten wir etwas Magisches, das sicherstellt, dass x
es für die Eingabe verwendet wird, nach der wir suchen, a___
und b___
einfach Platzhalter sind, die die verbleibenden Elemente abdecken.
Dies geschieht durch Anhängen einer Bedingung an das Muster mit /;
. Die rechte Seite von /;
(alles bis zu =
) muss zurückkehren, True
damit dieses Muster übereinstimmt. Das Schöne ist , dass Mathematicas Musteranpasser jede einzelne Zuordnung versuchen wird a
, x
und b
an die Eingänge für uns, so dass die Suche nach dem richtigen Element ist für uns getan hat . Dies ist im Wesentlichen eine deklarative Lösung des Problems.
Wie für die Bedingung selbst:
NestList[2#-1&,a~Min~b/. 2->0,4]~SubsetQ~{a,b}
Beachten Sie, dass dies überhaupt nicht abhängt x
. Stattdessen hängt diese Bedingung nur von den verbleibenden vier Elementen ab. Dies ist ein weiteres praktisches Merkmal der Mustervergleichslösung: Aufgrund der Sequenzmuster a
und b
enthalten zusammen alle anderen Eingaben.
Diese Bedingung muss also prüfen, ob die verbleibenden vier Elemente zusammenhängende Elemente aus unserer Sequenz mit höchstens einer Lücke sind. Die Grundidee, um dies zu überprüfen, ist, dass wir die nächsten vier Elemente aus dem Minimum (Via ) generieren und prüfen, ob die vier Elemente eine Teilmenge davon sind. Die einzigen Eingaben, bei denen dies zu Problemen führen kann, sind Eingaben mit a , da hierdurch auch gültige Sequenzelemente generiert werden. Daher müssen wir diese separat behandeln.xi+1 = 2xi - 1
2
Letzter Teil: Lass uns den eigentlichen Ausdruck durchgehen, denn hier gibt es etwas mehr lustigen syntaktischen Zucker.
...a~Min~b...
Diese Infixnotation ist eine Abkürzung für Min[a,b]
. Denken Sie jedoch daran, dass a
und b
Sequenzen sind, sodass diese tatsächlich auf die vier Elemente erweitert werden Min[i1, i2, i3, i4]
und uns das kleinste verbleibende Element in der Eingabe liefern.
.../. 2->0
Wenn dies zu einer 2 führt, ersetzen wir sie durch eine 0 (was Werte erzeugt, die nicht in der Reihenfolge sind). Der Raum ist notwendig, weil Mathematica sonst das float-Literal parst .2
.
NestList[...&,...,4]
Wir wenden die unbenannte Funktion links viermal auf diesen Wert an und sammeln die Ergebnisse in einer Liste.
2#-1&
Dies multipliziert einfach seine Eingabe mit 2 und dekrementiert sie.
...~SubsetQ~{a,b}
Zum Schluss überprüfen wir, ob die Liste, die alle Elemente enthält a
und b
eine Teilmenge davon ist.