Ist es ein OVSF-Code?

27

Bestimmen Sie anhand einer Liste von 1s und -1s, 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 Xes sich um einen OVSF-Code handelt, sind X ++ Xund X ++ -Xbeide 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 -1und 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
Lynn
quelle
5
Wofür steht "OVSF"?
NoOneIsHere
5
Orthogonaler variabler Spreizfaktor , der sich auf die Art und Weise bezieht, wie sie verwendet werden , und auch auf eine nützliche Eigenschaft, die sie haben. Dies schien nicht sehr relevant zu sein, aber der Wikipedia-Link erklärt alles (vage).
Lynn

Antworten:

8

Jelly , 18 16 14 11 Bytes

^2/Eam2µḊ¿Ṭ

Ausgaben [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

^2/Eam2µḊ¿Ṭ  Main link. Argument: A (array of 1's and -1's)

       µḊ¿   While dequeuing A (removing its first element) yields a non-empty
             array, execute the monadic chain to the left, updating A with the
             return value after each iteration.
^2/            Compute the bitwise XOR of each non-overlapping pair of elements of
               A. Note that 1 ^ 1 = 0 = -1 ^ -1 and 1 ^ -1 = -2 = -1 ^ 1.
               For an array of even length that consists of the same pairs modulo
               the sign, this returns either an array of 0's or an array of -2's.
               If the length is odd, it will also contain the last element, which
               is either a 1 or a -1.
   E           Test the elements of the result for equality. This yields 1 if the
               array consists solely of 0's or solely of -2's, 0 otherwise.
    a          Take the logical AND of the previous result and every element of A.
               This returns A if it passed the previous test, but replaces all of
               its elements with 0's otherwise.
     m2        Modulo 2; select every second element of A, starting with the first.
             At this point, the last return value can be:
               • [  ] if the input was empty
               • [ 1] if the input was a valid OVSF code
               • [-1] if the input was the negative of a valid OVSF code.
               • [ 0] in all other cases.
           Ṭ  Untruth; yield an array with 1's at the specified indices.
              Indexing is 1-based in Jelly, so [1] returns [1], the array with a 1
              at index 1. Since the indices -1 and 0 are non-canonical, the arrays
              [-1] and [0] are mapped to []. The empty array remains empty.
Dennis
quelle
14

Mathematica, 52 47 45 Bytes

Die Byteanzahl setzt die CP-1252-Codierung voraus und $CharacterEncodingauf WindowsANSI(die Standardeinstellung bei Windows-Installationen).

±___=!(±1=1>0)
a__±b__/;a!==b!||{a}==-{b}:=±a

Dies definiert eine Variadische Funktion PlusMinus, die die Eingabeliste als flache Liste der Argumente und gibt einen Booleschen Wert annimmt, zum Beispiel PlusMinus[1, -1, -1, 1]gibt True. 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 wie SubsetQund MatrixRanksind 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 ±:

±___=False;
±1=True;
a__±b__/;a!==b!||{a}==-{b}:=±a

Die ersten beiden Zeilen wurden gekürzt, indem die Definitionen verschachtelt und Trueals ausgedrückt wurden 1>0.

Wir sollten dies weiter dekonstruieren, um zu zeigen, wie dies tatsächlich eine variadci-Funktion definiert, indem wir PlusMinusnur 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 ±entspricht PlusMinus. Der folgende Code entspricht 100%:

PlusMinus[___]=False;
PlusMinus[1]=True;
PlusMinus[a__,b__]/;a!==b!||{a}==-{b}:=PlusMinus[a]

Durch die Verwendung von Sequenzen (in anderen Sprachen ähnlich wie bei Splats) als Operanden ±können wir eine beliebige Anzahl von Argumenten abdecken PlusMinus, 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, ergibt False.

Die zweite Definition ist der Basisfall für den OVSF, wobei die Liste nur enthält 1. Wir definieren dies als True.

Schließlich gilt die dritte Definition nur für Listen, die in X ++ Xoder zerlegt werden können X ++ -X, und verwendet das Ergebnis rekursiv für X. Die Definition ist nicht auf diese beschränkt , indem sichergestellt Listen können sie aufgeteilt in Subsequenzen sein aund bmit a__±b__und dann Anbringen der Bedingung ( /;) , die entweder {a}=={b}oder {a}==-{b}. Das Definieren PlusMinusals 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}ist List[a]. Aber aist eine Sequenz (wie ich sagte, wie eine Art Splat in anderen Sprachen) so , wenn aist 1,-1,1dann bekommen wir List[1,-1,1]. Jetzt Postfix !ist Factorial. Also hier würden wir bekommen Factorial[1,-1,1]. Weiß Factorialaber 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, Falsewenn dies nicht der Fall ist , aber Muster stimmen nicht überein, wenn die Bedingung etwas anderes zurückgibt als True). Die Gleichheitsprüfung funktioniert also weiterhin, wenn die Listen mindestens zwei Elemente enthalten. Was ist, wenn es nur einen gibt? Wenn aes 1dann a!noch ist 1. Wenn aist -1dann a!gibt ComplexInfinity. Jetzt 1funktioniert der Vergleich mit sich selbst natürlich noch gut. Aber ComplexInfinity == ComplexInfinitybleibt unbewertet, und nicht geben gilt , obwohl a == -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 wird True, wird der rekursive Aufruf gemeldetFalsees ist also egal, dass die Prüfung nicht funktioniert.) Wir können nicht denselben Trick anwenden, {a}==-{b}weil der -Thread nicht überlaufen würde Factorial, sondern nur überläuft List.

Der Pattern Matcher kümmert sich um den Rest und findet einfach die richtige Definition, die angewendet werden soll.

Martin Ender
quelle
9

Haskell, 57 Bytes

q=length
f l=l==until((>=q l).q)(\s->s++map(*l!!q s)s)[1]

Bei leiner gegebenen Eingabeliste wird ein OVSF-Code sdurch Starten [1]und wiederholtes Verketten von entweder soder erhöht -s, je nachdem, welches Element mit dem ersten Element von übereinstimmt l. Überprüft dann, ob das Ergebnis lam Ende ist. Dies wird überprüft, sobald sdie Länge mindestens die von hat l.

Einige alternative rekursive Strukturen ergaben ebenfalls 57:

(s%i)l|length l<=i=s==l|j<-2*i=(s++map(*l!!i)s)%j$l
[1]%1

q=length
s%l|q s>=q l=s==l|r<-s++map(*l!!q s)s=r%l
([1]%)

q=length
g s l|q s<q l=g(s++map(*l!!q s)s)l|1>0=s==l
g[1]
xnor
quelle
6

MATLAB / Octave , 94 Bytes

function a=f(r);n=nnz(r);m=log2(n);a=0;if fix(m)-m==0;for c=hadamard(n);a=a+all(r==c');end;end

Dies wird mit einem neuen Ansatz: Der erlaubte OVSF - Codes der Länge Nerscheint in der log2(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 Nwenn Neine 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önnen hadamard(). Zum Glück für Potenzen von zwei MATLAB's hadamard()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!

Fehler
quelle
5

Python, 64 Bytes

f=lambda l:[]<l[1::2]==[x*l[1]for x in l[::2]]*f(l[::2])or[1]==l

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:

f=lambda l,i=1,s=[1]:l[i:]and f(l,i*2,s+[x*l[i]for x in s])or s==l
xnor
quelle
2

Haskell , 106 91 87 86 Bytes

g n|n<1=[[1]]|m<-g(n-1)=foldl(\a b->[b++map(0-)b,b++b]++a)[]m++m
f l=elem l$g$length l

Die Funktion ggeneriert die nIteration von Listen (relativ ineffizient, da length $ g n == 3^nwir, wenn wir die Duplikate löschen würden, prüfen würden 2^n, fob sich unsere Liste in einer von ihnen befindet). Danke an @Zgrab für ein paar Hinweise!

Probieren Sie es online!

Fehler
quelle
Das Ausführen der letzten 2 Testfälle hat für mich keine Ausgabe erbracht.
Oliver
@obarakon Ja, denn das ist gist sehr ineffizient und produziert eine Tonne von Duplikaten. (Überprüfen Sie den Debug- Abschnitt, es liegt wahrscheinlich an der Zeit- oder Speicherbeschränkung.)
Fehler
2

JavaScript (ES6), 130 93 87 85 83 Byte

f=a=>(b=a.slice(0,l=a.length/2),c=a.slice(l)+"",a==1||l&&b==c|b.map(i=>-i)==c&f(b))

Demo

f=a=>(b=a.slice(0,l=a.length/2),c=a.slice(l)+"",a==1||l&&b==c|b.map(i=>-i)==c&f(b)),[[],[1],[-1],[1,1],[1,-1],[1,1,1,1],[1,1,1,1,1],[1,-1,-1,1,-1,1,1,-1],[1,1,1,1,-1,-1,-1,-1,1,1,1,1],[1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,1],[1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1]].map(a=>console.log(`[${a}] -> ${!!f(a)}`))

Patrick Roberts
quelle
2

JavaScript (ES6), 85 61 Bytes

a=>(l=a.length)&&!(l&l-1)&a.every((e,i)=>e==a[j=i&-i]*a[i-j])

Vorherige Version, in der Elemente überprüft wurden, um sicherzustellen, dass sie vorhanden sind, 1oder -1:

a=>(l=a.length)&&!(l&l-1)&a.every((e,i)=>i?(j=i&-i)<i?e==a[j]*a[i-j]:e==1|e==-1:e==1)

Erläuterung:

  • Die Länge kann nicht Null sein
  • Die Länge muss eine Potenz von 2 sein
  • Das erste Element muss 1 sein
  • Elemente an Stellen mit einer Potenz von 2 müssen entweder 1 oder -1 sein
  • Elemente an anderen Positionen sind das Produkt aller Elemente an den Positionen, die der Bitmaske entsprechen, z a[22] == a[2] * a[4] * a[16]. Da a[20] == a[4] * a[16]bereits geprüft wurde, muss nur a[22] == a[2] * a[20]noch geprüft werden.
  • Die obige Prüfung ergibt entartete Ergebnisse i, wenn nicht mindestens zwei Bits gesetzt sind. Im Falle von Null gesetzten Bits prüft es das a[0] == a[0] * a[0], was falsch ist a[0] == -1, während es im Falle eines gesetzten Bits das prüft a[i] == a[0] * a[i].
Neil
quelle
Sie können ändern (l=a.length)&&!(l&l-1), (l=a.length)&-l==lum 4 Bytes zu speichern
Patrick Roberts
@PatrickRoberts Ist das nicht wahr l==0?
Neil
Oh, du hast Recht. Na dann (l=a.length)&&l&-l==l? um 1 Byte zu sparen ...
Patrick Roberts
Eigentlich egal, Ihre Funktion schlägt für den Fall [1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,1]auch ohne meine Vorschläge fehl .
Patrick Roberts
@PatrickRoberts l&-l==lfunktioniert nicht, da es ==eine höhere Priorität als hat &. Und der Testfall funktioniert nicht wegen eines Tippfehlers, dessen Behebung mich ein Byte kostet.
Neil
2

MATL , 21 20 Bytes

`2eZ}yy=&=tn1>hh]1X=

Probieren 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

  1. Die entsprechenden Einträge der beiden Teile sind entweder alle gleich oder alle verschieden.
  2. Kein Eintrag im zweiten Stück ist Null;
  3. Die Länge der Stücke überschreitet 1.

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.

`        % Do...while loop
  2e     %   Reshape as a two-row matrix, with a padding zero if needed
         %   Row 1 contains the original odd-indexed entries, row 2 the
         %   even-indexed
  Z}     %   Split matrix into two vectors, one corresponding to each row
  yy     %   Duplicate those two vectors
  =      %   Check if corresponding entries are equal or not
  &=     %   Matrix of all pairwise comparisons. This will give a matrix
         %   filled with ones if and only if the previous check gave all
         %   true or all false (condition 1)
  tn1>   %   Duplicate and push true if size exceeds 1, or false otherwise
         %   (condition 3)
  hh     %   Concatenate condition 1, condition 3, and the original copy of
         %   the second piece (condition 2). The resulting vector is truthy
         %   if and only if it doesn't contain any zero
]        % End
1X=      % True if top of the stack is a single 1, false otherwise
Luis Mendo
quelle
2

Haskell, 66 Bytes

Ja, unendlich viele Listen!

o=[1]:(o>>= \x->[x++map(0-)x,x++x])
f l=l`elem`take(2*2^length l)o

Alternative Versionen:

o=[1]:(o<**>map(>>=flip(++))[map(0-),id])
f=Data.List.Ordered.hasBy(comparing length)o
Bergi
quelle
Danke für den (0-)Trick, ich war fest mit negateoder((-1)*)
Bergi
1

APL, 46 Bytes

{0::0⋄⍵≡,1:1⋄⍬≡⍵:0⋄(∇Z↑⍵)∧(∇Y)∨∇-Y←⍵↓⍨Z←.5×⍴⍵}

Ziemliech direkt:

  • Basisfälle:
    • 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ückgegeben
  • Rekursiver Fall:
    • Z←.5×⍴⍵: Zist die halbe Länge der Eingabe
    • Y←⍵↓⍨Z: Yist 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.
Marinus
quelle
1
Ich denke nicht, dass es ausreicht, die OVSF-Codeness für die zweite Hälfte zu überprüfen. es sollte gleich der ersten Hälfte oder seiner Verneinung sein.
Zgarb
1
Sie sagen, BASIC ist ein hohes Maß an Schmach und APL ist ein hohes Maß an Qual: ')
Katze
Sie sagen, BASIC ist ein hohes Maß an Schmach und APL ist ein hohes Maß an Qual: ')
Katze
1

Haskell, 69-68 Bytes

g x=any(elem x)$scanr(\_->concat.mapM(\y->[y++y,y++map(0-)y]))[[1]]x

Anwendungsbeispiel: 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:

take 10 $ c $ scanr(\_->concat.mapM(\y->[y++y,y++map(0-)y]))[[1]] [1..4]

was zurückkehrt

[[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
 [1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1],
 [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
 [1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1],
 [1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1],
 [1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1],
 [1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1],
 [1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1],
 [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
 [1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1]]

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!

nimi
quelle
Ah, das habe ich total vergessen scanr!
Fehler
Ich denke, Sie können ein Byte schneiden, indem Sie tun, any(elem x)anstatt zu elem x$cdefinieren und nicht c.
xnor
0

JavaScript (ES6), 80

f=(l,k=[1])=>l+l==k+k||l[k.length]&&f(l,k.concat(k))|f(l,k.concat(k.map(v=>-v)))

Erstellt und überprüft jede Liste rekursiv bis zur Länge der Eingabeliste, beginnend mit [1].

Rückgabewert ist JS truthy oder Falsey, speziell 1oder truewenn gültig, 0oder falseoder , undefinedwenn nicht gültig.

Prüfung

f=(l,k=[1])=>l+l==k+k||l[k.length]&&f(l,k.concat(k))|f(l,k.concat(k.map(v=>-v)))

test=`[] -> 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`
.split('\n')

test.forEach(r=>{
  input = r.match(/-?1/g)||[]
  check = r.slice(-4) == 'True'
  result = f(input)
  console.log(result, check, '['+input+']')
})

edc65
quelle
0

Clojure, 118 Bytes

(defn f[C](or(=(count C)1)(let[l(/(count C)2)[a b](split-at l C)](and(> l 0)(=(count b)l)(apply =(map * a b))(f a)))))

Teilt die Eingabe cin zwei Hälften aund bund 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:

#((set(nth(iterate(fn[I](mapcat(fn[i][(concat i i)(concat i(map - i))])I))[[1][-1]])(loop[l(count %)i 0](if(< l 2)i(recur(/ l 2)(inc i))))))%)

loopBerechnet log_2die Länge der Eingabe und iterategeneriert anhand der Definition Sequenzen mit so vielen Iterationen. Dies gibt das Eingabeargument zurück, wenn es eine gültige Sequenz ist nil.

NikoNyrh
quelle