Bestimmen Sie anhand einer Liste von 1
s und -1
s, ob es sich um einen gültigen OVSF-Code handelt oder nicht (indem Sie einen Wahrheits- oder einen falschen Wert ausgeben).
OVSF-Codes sind wie folgt definiert:
[1]
ist ein OVSF-Code.Wenn
X
es sich um einen OVSF-Code handelt, sindX ++ X
undX ++ -X
beide OVSF-Codes.Hier
++
ist die Listenverkettung und-
negiert jedes Element in der Liste.Keine anderen Listen sind gültige OVSF-Codes.
Sie können davon ausgehen, dass die Eingabeliste nur -1
und enthält 1
, Sie müssen jedoch die leere Liste sowie Listen, deren Länge keine Potenz von 2 ist, korrekt behandeln.
Kürzester Code (in Bytes) gewinnt.
Testfälle
[] -> False
[1] -> True
[-1] -> False
[1, 1] -> True
[1, -1] -> True
[1, 1, 1, 1] -> True
[1, 1, 1, 1, 1] -> False
[1, -1, -1, 1, -1, 1, 1, -1] -> True
[1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1] -> False
[1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1] -> False
[1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1] -> True
Antworten:
Jelly ,
18161411 BytesAusgaben
[1]
(wahr) für OVSF-Codes,[]
sonst (falsch).Probieren Sie es online!
Hintergrund
Wie @ LuisMendo die MATL Antwort und @ xnor Python Antwort , diese Vorlage überprüft die Eingangsanordnung „von innen heraus“.
Jedes (nicht überlappende) Paar von Elementen eines OVSF-Codes der Länge zwei oder höher ist im Wesentlichen eine Kopie des ersten Paares, entweder mit den gleichen Vorzeichen oder mit beiden vertauschten Vorzeichen. Ebenso ist jedes (nicht überlappende) 4-Tupel von Elementen eines OVSF-Codes der Länge vier oder höher im Wesentlichen eine Kopie des ersten 4-Tupels, entweder mit den gleichen Vorzeichen oder mit beiden vertauschten Vorzeichen. Gleiches gilt für 8-Tupel, 16-Tupel usw. bis zur Länge des OVFS-Codes.
Eine Möglichkeit, dies zu überprüfen, besteht darin, zuerst alle Paare auf Gleichheit zu prüfen, und dann das zweite Element jedes Paares (das jetzt redundante Informationen enthält) zu entfernen. Wenn wir diesen Vorgang noch einmal wiederholen, überprüfen wir im Wesentlichen alle 4-Tupel. In der nächsten Iteration vergleichen wir 8-Tupel usw.
Wenn schließlich alle erforderlichen 2 k- Tupel gleich dem Vorzeichen sind und das Array auf einen Singleton reduziert wurde, reicht es aus, zu prüfen, ob das verbleibende Element eine 1 ist .
Wie es funktioniert
quelle
Mathematica,
524745 BytesDie Byteanzahl setzt die CP-1252-Codierung voraus und
$CharacterEncoding
aufWindowsANSI
(die Standardeinstellung bei Windows-Installationen).Dies definiert eine Variadische Funktion
PlusMinus
, die die Eingabeliste als flache Liste der Argumente und gibt einen Booleschen Wert annimmt, zum BeispielPlusMinus[1, -1, -1, 1]
gibtTrue
. Es ist theoretisch auch verwendbar als Operator±
, aber das Operator ist nur syntaktisch gültig in unäre und binäre Kontexte, so würde die Aufrufkonvention seltsam erhalten:±##&[1,-1,-1,1]
. Es werden eine Reihe von Warnungen ausgegeben, die ignoriert werden können.Dadurch werden auch einige Warnungen ausgegeben, die ignoriert werden können.
Es könnte weg sein, um den etwas nervigen
a!==b!||{a}==-{b}
Teil zu verkürzen , aber ich finde im Moment nichts. Stichwörter wieSubsetQ
undMatrixRank
sind einfach zu lang. : /Erläuterung
Die Lösung verschiebt im Grunde alle kniffligen Dinge zu Mathematica Pattern Matcher und ist daher sehr deklarativ im Stil. Abgesehen von einigem Golfgefühl in der ersten Zeile werden hiermit nur drei verschiedene Definitionen für den Bediener hinzugefügt
±
:Die ersten beiden Zeilen wurden gekürzt, indem die Definitionen verschachtelt und
True
als ausgedrückt wurden1>0
.Wir sollten dies weiter dekonstruieren, um zu zeigen, wie dies tatsächlich eine variadci-Funktion definiert, indem wir
PlusMinus
nur die unäre und die binäre Operatornotation verwenden. Der Haken ist, dass alle Operatoren einfach syntaktischer Zucker für vollständige Ausdrücke sind. In unserem Fall±
entsprichtPlusMinus
. Der folgende Code entspricht 100%:Durch die Verwendung von Sequenzen (in anderen Sprachen ähnlich wie bei Splats) als Operanden
±
können wir eine beliebige Anzahl von Argumenten abdeckenPlusMinus
, auch wenn diese±
nicht mit mehr als zwei Argumenten verwendet werden können. Der grundlegende Grund ist, dass syntaktischer Zucker zuerst aufgelöst wird, bevor eine dieser Sequenzen expandiert wird.Zu den Definitionen:
Die erste Definition ist einfach ein Fallback (
___
entspricht einer beliebigen Liste von Argumenten). Alles, was nicht mit den unten angegebenen genaueren Definitionen übereinstimmt, ergibtFalse
.Die zweite Definition ist der Basisfall für den OVSF, wobei die Liste nur enthält
1
. Wir definieren dies alsTrue
.Schließlich gilt die dritte Definition nur für Listen, die in
X ++ X
oder zerlegt werden könnenX ++ -X
, und verwendet das Ergebnis rekursiv fürX
. Die Definition ist nicht auf diese beschränkt , indem sichergestellt Listen können sie aufgeteilt in Subsequenzen seina
undb
mita__±b__
und dann Anbringen der Bedingung (/;
) , die entweder{a}=={b}
oder{a}==-{b}
. Das DefinierenPlusMinus
als variable Funktion auf diese seltsame Weise über einen Operator spart satte 5 Bytes gegenüber dem Definieren eines unären Operators±
in Listen.Aber warte, es gibt noch mehr. Wir verwenden
a!==b!
statt{a}=={b}
. Klar, wir machen das, weil es zwei Bytes kürzer ist, aber die interessante Frage ist, warum es funktioniert. Wie ich oben erklärt habe, sind alle Operatoren nur syntaktischer Zucker für einen Ausdruck mit einem Kopf.{a}
istList[a]
. Abera
ist eine Sequenz (wie ich sagte, wie eine Art Splat in anderen Sprachen) so , wenna
ist1,-1,1
dann bekommen wirList[1,-1,1]
. Jetzt Postfix!
istFactorial
. Also hier würden wir bekommenFactorial[1,-1,1]
. WeißFactorial
aber nicht, was zu tun ist, wenn es eine andere Anzahl von Argumenten als eines gibt, so dass dies einfach unbewertet bleibt.==
Es ist mir egal, ob das Ding auf beiden Seiten Listen sind, es vergleicht nur die Ausdrücke und wenn sie gleich sind, gibt esTrue
(In diesem Fall wird es nicht wirklich geben,False
wenn dies nicht der Fall ist , aber Muster stimmen nicht überein, wenn die Bedingung etwas anderes zurückgibt alsTrue
). Die Gleichheitsprüfung funktioniert also weiterhin, wenn die Listen mindestens zwei Elemente enthalten. Was ist, wenn es nur einen gibt? Wenna
es1
danna!
noch ist1
. Wenna
ist-1
danna!
gibtComplexInfinity
. Jetzt1
funktioniert der Vergleich mit sich selbst natürlich noch gut. AberComplexInfinity == ComplexInfinity
bleibt unbewertet, und nicht geben gilt , obwohla == -1 == b
. Zum Glück spielt das keine Rolle, denn die einzige Situation, in der dies auftaucht, ist,PlusMinus[-1, -1]
dass es sich ohnehin nicht um eine gültige OVSF handelt! (Wenn die Bedingung zurückgegeben wirdTrue
, wird der rekursive Aufruf gemeldetFalse
es ist also egal, dass die Prüfung nicht funktioniert.) Wir können nicht denselben Trick anwenden,{a}==-{b}
weil der-
Thread nicht überlaufen würdeFactorial
, sondern nur überläuftList
.Der Pattern Matcher kümmert sich um den Rest und findet einfach die richtige Definition, die angewendet werden soll.
quelle
Haskell, 57 Bytes
Bei
l
einer gegebenen Eingabeliste wird ein OVSF-Codes
durch Starten[1]
und wiederholtes Verketten von entweders
oder erhöht-s
, je nachdem, welches Element mit dem ersten Element von übereinstimmtl
. Überprüft dann, ob das Ergebnisl
am Ende ist. Dies wird überprüft, sobalds
die Länge mindestens die von hatl
.Einige alternative rekursive Strukturen ergaben ebenfalls 57:
quelle
MATLAB / Octave , 94 Bytes
Dies wird mit einem neuen Ansatz: Der erlaubte OVSF - Codes der Länge
N
erscheint in derlog2(N)
-te Walsh-Matrix , wie sie im Wesentlichen durch die gleiche Rekursion definiert ist:Walsh Matrizen sind Spezialfälle der Hadamard-Matrizen der Größe ,
N x N
wennN
eine Zweierpotenz ist. (Es gibt auch Hadamard-Matrizen anderer Größen.) MATLAB und Octave verfügen über eine Vielzahl integrierter Funktionen, mit denen Testmatrizen zum Testen der Eigenschaften numerischer Algorithmen erstellt werden könnenhadamard()
. Zum Glück für Potenzen von zwei MATLAB'shadamard()
usex genau die Konstruktion der Walisischen-Matrizen.Diese Funktion prüft also zuerst, ob die Länge der Eingaben eine Zweierpotenz ist, und wenn dies der Fall ist, prüft sie, ob es sich um eine Zeile der entsprechenden walisischen Matrix handelt.
Probieren Sie es online!
quelle
Python, 64 Bytes
Teilt die Liste über Slices in geradzahlige und ungeradzahlige Elemente auf. Überprüft, ob die Ergebnisvektoren entweder gleich oder negativ sind, indem eine mit dem Vorzeichen multipliziert wird, das von ihrem ersten Element erzwungen wird. Führt dann dieselbe rekursive Prüfung für die geraden indizierten Elemente durch.
Wenn die Prüfung im Basisfall fehlschlägt, wird sie abgelehnt, sofern die Liste nicht vorhanden ist
[1]
. Die leere Liste wird auch ausdrücklich abgelehnt, um eine Endlosschleife zu vermeiden.Eine andere Strategie wie meine Haskell-Antwort ergibt 66 Bytes:
quelle
Haskell ,
106 91 8786 BytesDie Funktion
g
generiert dien
Iteration von Listen (relativ ineffizient, dalength $ g n == 3^n
wir, wenn wir die Duplikate löschen würden, prüfen würden2^n
,f
ob sich unsere Liste in einer von ihnen befindet). Danke an @Zgrab für ein paar Hinweise!Probieren Sie es online!
quelle
g
ist sehr ineffizient und produziert eine Tonne von Duplikaten. (Überprüfen Sie den Debug- Abschnitt, es liegt wahrscheinlich an der Zeit- oder Speicherbeschränkung.)JavaScript (ES6),
13093878583 ByteDemo
quelle
JavaScript (ES6),
8561 BytesVorherige Version, in der Elemente überprüft wurden, um sicherzustellen, dass sie vorhanden sind,
1
oder-1
:Erläuterung:
a[22] == a[2] * a[4] * a[16]
. Daa[20] == a[4] * a[16]
bereits geprüft wurde, muss nura[22] == a[2] * a[20]
noch geprüft werden.i
, wenn nicht mindestens zwei Bits gesetzt sind. Im Falle von Null gesetzten Bits prüft es dasa[0] == a[0] * a[0]
, was falsch ista[0] == -1
, während es im Falle eines gesetzten Bits das prüfta[i] == a[0] * a[i]
.quelle
(l=a.length)&&!(l&l-1)
,(l=a.length)&-l==l
um 4 Bytes zu speichernl==0
?(l=a.length)&&l&-l==l
? um 1 Byte zu sparen ...[1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,1]
auch ohne meine Vorschläge fehl .l&-l==l
funktioniert nicht, da es==
eine höhere Priorität als hat&
. Und der Testfall funktioniert nicht wegen eines Tippfehlers, dessen Behebung mich ein Byte kostet.MATL ,
2120 BytesProbieren Sie es online! Oder überprüfen Sie alle Testfälle .
Wie es funktioniert
Der Code teilt das Array in zwei gleichlange Teile: den ersten mit den ungeraden Einträgen und den zweiten mit den geraden Einträgen. Die beiden Teile müssen die gleiche Länge haben, bei Bedarf wird in der Sekunde eine Null aufgefüllt. Dann prüft der Code das
Wenn diese drei Bedingungen erfüllt sind, wird der Prozess erneut auf das erste Stück angewendet. Wenn die Schleife verlassen wird, weil die Länge bereits 1 war, ist die Eingabe ein OFSV-Code. Sonst ist es nicht.
Die iterierte Bedingung 1 ist eine äquivalente Version der definierenden Eigenschaft von OVSF-Codes. Für ein Array mit der Sagenlänge 8 würde der einfache Ansatz darin bestehen, zu überprüfen, ob die Einträge 1, 2, 3, 4 alle gleich oder alle verschieden zu den Einträgen 5, 6, 7, 8 sind (dies ist die definierende Eigenschaft). Wir können aber gleichermaßen überprüfen, ob die Einträge 1,3,5,7 alle gleich oder alle verschieden zu den Einträgen 2,4,6,8 sind. und dies stellt sich heraus, weniger Bytes zu verwenden.
Bedingung 2 stellt sicher, dass die Eingangslänge eine Potenz von 2 ist. Wenn dies nicht der Fall ist, wird irgendwann eine Auffüllungsnull eingeführt.
quelle
Haskell, 66 Bytes
Ja, unendlich viele Listen!
Alternative Versionen:
quelle
(0-)
Trick, ich war fest mitnegate
oder((-1)*)
APL, 46 Bytes
Ziemliech direkt:
0::0
: Wenn ein Fehler auftritt, wird 0 zurückgegeben⍵≡,1:1
: Wenn die Eingabe genau ist[1]
, geben Sie 1 zurück⍬≡⍵:0
: Wenn die Eingabe eine leere Liste ist, wird 0 zurückgegebenZ←.5×⍴⍵
:Z
ist die halbe Länge der EingabeY←⍵↓⍨Z
:Y
ist die letzte Hälfte der Eingabe (dies schlägt fehl, wenn sie⍴⍵
ungerade ist und löst den Ausnahmehandler aus)(∇Y)∨∇-Y
: Entweder die letzte Hälfte der Liste oder die Negation der letzten Hälfte der Liste muss ein OVSF-Code sein(∇Z↑⍵)∧
: und die erste Hälfte der Liste muss ein OVSF-Code sein.quelle
Haskell,
69-68BytesAnwendungsbeispiel:
g [-1,1]
->False
.Noch ineffizienter als die Antwort von @flawr . Es dauert zu viel Zeit und Speicher für 4 Elementlisten. Um festzustellen, ob die Liste der OVSF-Codes (mit vielen Duplikaten) tatsächlich erstellt wurde, versuchen Sie Folgendes:
was zurückkehrt
dh die Liste beginnt mit allen 16 Elementlisten (wegen 4 mal verkettet
[1..4]
), fährt mit allen 8 Elementlisten fort und so weiter, bis sie endet mit[1]
.Edit: @xnor hat ein Byte gespeichert. Vielen Dank!
quelle
scanr
!any(elem x)
anstatt zuelem x$c
definieren und nichtc
.Python 2 ,
7875 BytesProbieren Sie es online!
quelle
JavaScript (ES6), 80
Erstellt und überprüft jede Liste rekursiv bis zur Länge der Eingabeliste, beginnend mit
[1]
.Rückgabewert ist JS truthy oder Falsey, speziell
1
odertrue
wenn gültig,0
oderfalse
oder ,undefined
wenn nicht gültig.Prüfung
quelle
Clojure, 118 Bytes
Teilt die Eingabe
c
in zwei Hälftena
undb
und prüft, ob ihre elementweisen Produkte alle identisch sind. Wenn ja, wird überprüft, ob die erste Hälfte der Sequenz gültig ist.Dieser ist 142 Bytes, aber ich fand es interessanter:
loop
Berechnetlog_2
die Länge der Eingabe unditerate
generiert anhand der Definition Sequenzen mit so vielen Iterationen. Dies gibt das Eingabeargument zurück, wenn es eine gültige Sequenz istnil
.quelle