Biorąc pod uwagę listę 1
S i -1
S, określić, czy jest to prawidłowy kod OVSF (przez wyprowadzanie truthy lub wartości falsey).
Kody OVSF są zdefiniowane w następujący sposób:
[1]
to kod OVSF.Jeśli
X
jest to kod OVSF, toX ++ X
iX ++ -X
oba są kodami OVSF.Oto
++
konkatenacja listy i-
neguje każdy element na liście.Żadne inne listy nie są prawidłowymi kodami OVSF.
Możesz założyć, że lista wejściowa zawiera tylko -1
i 1
, ale musisz poprawnie obsługiwać pustą listę, a także listy, których długość nie jest potęgą 2.
Najkrótszy kod (w bajtach) wygrywa.
Przypadki testowe
[] -> 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
Odpowiedzi:
Galaretka ,
18161411 bajtówWyjścia
[1]
(prawda) dla kodów OVSF,[]
(fałsz) w przeciwnym razie.Wypróbuj online!
tło
Jak @ LuisMendo za Mátl odpowiedź i użytkownika @ XNOR Python odpowiedź , ten argument weryfikuje tablicy wejście „od wewnątrz out”.
Każda (nie nakładająca się) para elementów kodu OVSF o długości dwa lub większej jest zasadniczo kopią pierwszej pary, z tymi samymi znakami lub z zamienionymi obydwoma znakami. Podobnie, każda (nie nakładająca się) 4-krotna część elementów kodu OVSF o długości czterech lub większej jest zasadniczo kopią pierwszego 4-krotnego, z tymi samymi znakami lub z zamienionymi obydwoma znakami. To samo dotyczy 8-krotek, 16-krotek itp., Aż do długości kodu OVFS.
Jednym ze sposobów na sprawdzenie tego jest sprawdzenie najpierw wszystkich par dla znaku równości modulo, a następnie usunięcie drugiego elementu z każdej pary (która jest teraz informacją redundantną). Jeśli powtórzymy ten proces jeszcze raz, zasadniczo sprawdzamy wszystkie 4-krotki. W następnej iteracji porównujemy 8 krotek itp.
Wreszcie, jeśli wszystkie wymagane 2 k- pary były równe modulo znakowi, a tablica została zredukowana do singletonu, wystarczy sprawdzić, czy pozostały element to 1 .
Jak to działa
źródło
Mathematica,
524745 bajtówLiczba bajtów zakłada kodowanie CP-1252 i jest
$CharacterEncoding
ustawiona naWindowsANSI
(ustawienie domyślne w instalacjach Windows).Definiuje to funkcję wariadyczną
PlusMinus
, która przyjmuje listę wejściową jako płaską listę argumentów i zwraca wartość logiczną, np .PlusMinus[1, -1, -1, 1]
DajeTrue
. To teoretycznie również użyteczny jako operator±
, ale tylko, że operator jest składniowo poprawny w kontekstach jednoargumentowych i binarnych, więc konwencja powołanie dostanie dziwne:±##&[1,-1,-1,1]
. Wyrzuci kilka ostrzeżeń, które można zignorować.Spowoduje to także wyświetlenie kilku ostrzeżeń, które można zignorować.
Nie może być z dala, aby skrócić nieco irytujące
a!==b!||{a}==-{b}
część, ale nie jestem znalezienie czegokolwiek teraz. Słowa kluczowe lubiąSubsetQ
iMatrixRank
są po prostu za długie. : /Wyjaśnienie
Rozwiązanie zasadniczo odkłada wszystkie trudne rzeczy na dopasowywanie wzorców Mathematica, a zatem ma bardzo deklaratywny styl. Oprócz nieco golfa w pierwszej linii, to naprawdę dodaje tylko trzy różne definicje dla operatora
±
:Pierwsze dwa wiersze zostały skrócone przez zagnieżdżenie definicji i wyrażenie
True
jako1>0
.Powinniśmy dalej to zdekonstruować, aby pokazać, jak to faktycznie definiuje funkcję variadci,
PlusMinus
używając tylko jednoargumentowej i binarnej notacji operatora. Chodzi o to, że wszyscy operatorzy są po prostu cukrem syntaktycznym dla pełnych wyrażeń. W naszym przypadku±
odpowiadaPlusMinus
. Poniższy kod jest w 100% równoważny:Wykorzystując sekwencje (coś w rodzaju spacji w innych językach) jako argumenty do
±
możemy objąć dowolną liczbę argumentówPlusMinus
, nawet jeśli±
nie można ich użyć z więcej niż dwoma argumentami. Podstawowym powodem jest to, że cukier syntaktyczny jest najpierw rozstrzygany, zanim dowolna z tych sekwencji zostanie rozwinięta.Do definicji:
Pierwsza definicja jest po prostu rezerwą (
___
pasuje do dowolnej listy argumentów). Daje wszystko, co nie pasuje do bardziej szczegółowych definicji poniżejFalse
.Druga definicja jest podstawowym przypadkiem OVSF, lista zawiera tylko
1
. Określamy to jakoTrue
.Wreszcie trzecia definicja dotyczy tylko list, które można rozłożyć na
X ++ X
lubX ++ -X
rekurencyjnie wykorzystuje wynik dlaX
. Definicja ogranicza się do tych wykazów poprzez zapewnienie mogą być podzielone na podciągówa
ib
za__±b__
a następnie dołączenie warunku (/;
), które albo{a}=={b}
albo{a}==-{b}
. ZdefiniowaniePlusMinus
w ten dziwny sposób funkcji variadic za pomocą operatora pozwala zaoszczędzić aż 5 bajtów przed zdefiniowaniem jednego operatora±
na listach.Ale czekaj, jest więcej. Używamy
a!==b!
zamiast{a}=={b}
. Oczywiście robimy to, ponieważ jest on o dwa bajty krótszy, ale interesujące pytanie brzmi, dlaczego to działa. Jak wyjaśniłem powyżej, wszyscy operatorzy to tylko cukier syntaktyczny dla pewnej ekspresji z głową.{a}
jestList[a]
. Alea
jest to sekwencja (jak powiedziałem, coś w rodzaju innych języków), więc jeśli tak,a
to1,-1,1
otrzymamyList[1,-1,1]
. Teraz!
jest postfiksFactorial
. Więc tutaj dostaniemyFactorial[1,-1,1]
. AleFactorial
nie wie, co zrobić, gdy ma inną liczbę argumentów niż jeden, więc po prostu pozostaje to bezcenne.==
tak naprawdę nie dba o to, czy po obu stronach są listy, po prostu porównuje wyrażenia, a jeśli są równe, dajeTrue
(w tym przypadku nie da się,False
jeśli tak nie jest, ale wzorce nie pasują, jeśli warunek zwraca coś innego niżTrue
). Oznacza to, że kontrola równości nadal działa, jeśli na liście znajdują się co najmniej dwa elementy. Co jeśli jest tylko jeden? Jeślia
jest,1
toa!
jest nadal1
. Jeślia
tak-1
toa!
dajeComplexInfinity
. Teraz porównywanie1
do siebie nadal działa dobrze. AleComplexInfinity == ComplexInfinity
pozostaje nieoceniony i chociaż nie daje prawdya == -1 == b
. Na szczęście to nie ma znaczenia, ponieważ jedyna sytuacja, wPlusMinus[-1, -1]
której się pojawia, to i tak nie jest prawidłowy OVSF! (Jeśli warunek powróciTrue
, połączenie rekurencyjne zgłosi sięFalse
w końcu, więc nie ma znaczenia, że sprawdzenie się nie powiedzie.) Nie możemy użyć tej samej sztuczki,{a}==-{b}
ponieważ-
nie chce się przewinąćFactorial
, tylko się przewracaList
.Dopasowujący wzór zajmie się resztą i po prostu znajdzie właściwą definicję do zastosowania.
źródło
Haskell, 57 bajtów
Biorąc pod uwagę listę danych wejściowych
l
, rozwija kod OVSFs
, zaczynając od[1]
i wielokrotnie łącząc jedens
lub jeden-s
, w zależności od tego, który pierwszy element pasuje do tegol
. Następnie sprawdza, czy wynik jestl
na końcu. Jest to sprawdzane, gdys
ma co najmniej długośćl
.Niektóre alternatywne struktury rekurencyjne również dały 57:
źródło
MATLAB / oktawa , 94 bajty
Wykorzystuje to nowe podejście: Dozwolone kody długości OVSF
N
pojawiają się wlog2(N)
-tej macierzy Walsha , ponieważ są one zasadniczo zdefiniowane przez tę samą rekurencję:Macierze Walsha są szczególnymi przypadkami macierzy Hadamarda wielkości,
N x N
jeśliN
jest potęgą dwóch. (Istnieją również macierze Hadamarda o innych rozmiarach.) MATLAB i Octave mają wiele wbudowanych funkcji, które generują macierze testowe do testowania właściwości algorytmów numerycznych, między innymihadamard()
. Na szczęście dla mocy dwóch zastosowań MATLABahadamard()
właśnie konstrukcja walijskich matryc.Ta funkcja najpierw sprawdza, czy długość wejściowa jest potęgą dwóch, a jeśli tak, to sprawdza, czy jest to rząd o odpowiedniej wielkości matrycy walijskiej.
Wypróbuj online!
źródło
Python, 64 bajty
Dzieli listę na elementy parzyste i nieparzyste za pomocą plasterków. Sprawdza, czy wektory wynikowe są równe lub ujemne, mnożąc jeden przez znak wymuszony przez jego pierwszy element. Następnie wykonuje tę samą rekurencyjną kontrolę elementów parzysto indeksowanych.
W przypadku podstawowym, jeśli sprawdzenie się nie powiedzie, odrzuca, chyba że lista jest
[1]
. Pusta lista jest również specjalnie odrzucana, aby uniknąć nieskończonej pętli.Inna strategia, taka jak moja odpowiedź Haskella, daje 66 bajtów:
źródło
Haskell ,
106 91 8786 bajtówTa funkcja
g
generujen
iterację list (stosunkowo nieefektywnie, ponieważlength $ g n == 3^n
jeśli jednak usuniemy duplikaty, dostaniemy2^n
),f
sprawdza, czy nasza lista znajduje się na którejkolwiek z nich. Dzięki @Zgrab za kilka wskazówek!Wypróbuj online!
źródło
g
jest bardzo nieefektywny i produkuje mnóstwo duplikatów. (Sprawdź sekcję debugowania , prawdopodobnie wynika to z ograniczeń czasowych lub pamięciowych).JavaScript (ES6),
13093878583 bajtówPróbny
źródło
JavaScript (ES6),
8561 bajtówPoprzednia wersja, która sprawdzała elementy, aby upewnić się, że były
1
lub-1
:Wyjaśnienie:
a[22] == a[2] * a[4] * a[16]
. Ponieważa[20] == a[4] * a[16]
zostało już sprawdzone,a[22] == a[2] * a[20]
wystarczy je sprawdzić.i
brak ustawienia co najmniej dwóch bitów. W przypadku zestawu bitów zerowych sprawdza toa[0] == a[0] * a[0]
, co jest fałszema[0] == -1
, natomiast w przypadku zestawu bitów sprawdza toa[i] == a[0] * a[i]
.źródło
(l=a.length)&&!(l&l-1)
aby(l=a.length)&-l==l
zapisać 4 bajtyl==0
?(l=a.length)&&l&-l==l
? zaoszczędzić 1 bajt ...[1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,1]
nawet bez moich sugestii.l&-l==l
nie działa, ponieważ==
ma wyższy priorytet niż&
. A przypadek testowy nie działa z powodu literówki, którą naprawienie kosztuje mnie bajtem.MATL ,
2120 bajtówWypróbuj online! Lub sprawdź wszystkie przypadki testowe .
Jak to działa
Kod dzieli tablicę na dwie równe części: pierwsza z nieparzystymi indeksami, druga z nieparzystymi indeksami. Dwa elementy są zmuszone do równej długości, z wypełnieniem zero w drugim w razie potrzeby. Następnie kod to sprawdza
Jeśli te trzy warunki zostaną spełnione, proces zostanie ponownie zastosowany do pierwszego elementu. Jeśli pętla zostanie zakończona, ponieważ długość wynosiła już 1, wejściem jest kod OFSV. W przeciwnym razie tak nie jest.
Iteracja warunku 1 jest równoważną wersją właściwości definiującej kodów OVSF. Dla tablicy o powiedzmy długości 8 najprostszym podejściem byłoby sprawdzenie, czy wszystkie wpisy 1,2,3,4 są równe lub wszystkie różnią się odpowiednio od wpisów 5,6,7,8 (jest to właściwość definiująca). Ale możemy w równoważny sposób sprawdzić, czy wpisy 1,3,5,7 są równe lub wszystkie różnią się odpowiednio od wpisów 2,4,6,8; i okazuje się, że używa mniej bajtów.
Warunek 2 upewnia się, że długość wejściowa jest potęgą 2: jeśli nie, dopełnienie zerowe zostanie wprowadzone na pewnym etapie.
źródło
Haskell, 66 bajtów
Tak, nieskończone listy!
Alternatywne wersje:
źródło
(0-)
podstęp, utknąłem znegate
lub((-1)*)
APL, 46 bajtów
Dość bezpośredni:
0::0
: jeśli wystąpi błąd, zwróć 0⍵≡,1:1
: jeśli dane wejściowe są dokładnie[1]
, zwróć 1⍬≡⍵:0
: jeśli wejście jest pustą listą, zwróć 0Z←.5×⍴⍵
:Z
to połowa długości wejściaY←⍵↓⍨Z
:Y
jest ostatnią połową danych wejściowych (nie powiedzie się, jeśli⍴⍵
jest nierówna, co powoduje uruchomienie procedury obsługi wyjątków)(∇Y)∨∇-Y
: ostatnia połowa listy lub negacja ostatniej połowy listy musi być kodem OVSF(∇Z↑⍵)∧
: a pierwsza połowa listy musi być kodem OVSF.źródło
Haskell,
6968 bajtówPrzykład użycia:
g [-1,1]
->False
.Jeszcze bardziej nieefektywna niż odpowiedź @ flawr . Zajmuje zbyt dużo czasu i pamięci dla list 4-elementowych. Aby zobaczyć, że lista kodów OVSF (z dużą liczbą duplikatów) jest rzeczywiście utworzona, spróbuj:
który zwraca
tzn. lista zaczyna się od wszystkich 16 list elementów (z 4 razy połączonych
[1..4]
), kontynuuje od wszystkich 8 list elementów i tak dalej, aż do końca[1]
.Edycja: @xnor zapisał bajt. Dzięki!
źródło
scanr
!any(elem x)
zamiastelem x$c
definiowaćc
.Python 2 ,
7875 bajtówWypróbuj online!
źródło
JavaScript (ES6), 80
Rekurencyjnie buduje i sprawdza każdą listę do długości listy danych wejściowych, zaczynając od
[1]
.Zwracana jest wartość JS truthy lub falsey, specjalnie
1
lubtrue
jeśli ważny,0
lubfalse
lubundefined
jeśli nie ważne.Test
źródło
Clojure, 118 bajtów
Dzieli dane wejściowe
c
na dwie połowya
ib
sprawdza, czy wszystkie ich produkty są identyczne. Jeśli tak, sprawdza, czy pierwsza połowa jest prawidłową sekwencją.Ten ma 142 bajty, ale uważam, że jest bardziej interesujący:
loop
obliczalog_2
długość wejściową,iterate
generuje sekwencje z wielu iteracji na podstawie definicji. Zwraca argument wejściowy, jeśli jest to poprawna sekwencja inil
inaczej.źródło