Dopasuj ciągi, których długość stanowi czwartą potęgę


28

W ramach tego pytania rozważmy tylko ciągi znaków, które składają się ze znaku xpowtarzanego dowolną liczbę razy.

Na przykład:

<empty>
x
xx
xxxxxxxxxxxxxxxx

(Cóż, tak naprawdę nie musi tak być x- każdy znak jest w porządku, o ile cały łańcuch ma tylko 1 typ znaku)

Napisz regex w dowolnym smaku regex, aby dopasować wszystkie ciągi, których długość wynosi n 4 dla niektórych nieujemnych liczb całkowitych n (n> = 0). Na przykład ciągi o długości 0, 1, 16, 81 itd. Są poprawne; reszta jest nieprawidłowa.

Ze względu na ograniczenia techniczne trudno jest przetestować wartości n większe niż 128. Jednak wyrażenie regularne powinno logicznie działać poprawnie niezależnie od tego.

Zauważ, że nie możesz wykonywać dowolnego kodu w wyrażeniu regularnym (dla użytkowników Perla). Każda inna składnia (rozglądanie się, odwołanie do tyłu itp.) Jest dozwolona.

Dołącz także krótkie wyjaśnienie swojego podejścia do problemu.

(Proszę nie wklejać automatycznie generowanego wyjaśnienia składni wyrażenia regularnego, ponieważ są one bezużyteczne)


„xx” jest nieprawidłowe, prawda?
Kendall Frey

@KendallFrey: Nie. To nie jest poprawne.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨d̷̰̀ĥ̷̳

@nhahtdh, czy uważasz, że istnieje możliwa odpowiedź na to pytanie?
xem

1
@Timwi: Tak. Java, PCRE (prawdopodobnie także Perl, ale nie można go przetestować), .NET. Jednak mój nie działa w Ruby / JS.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨d̷̰̀ĥ̷̳

1
To pytanie zostało dodane do często zadawanych pytań dotyczących wyrażeń regularnych przepełnienia stosu w sekcji „Zaawansowane Regex-Fu”.
aliteralmind

Odpowiedzi:


21

To (ir) wyrażenie regularne wydaje się działać.

^((?(1)((?(2)\2((?(3)\3((?(4)\4x{24}|x{60}))|x{50}))|x{15}))|x))*$

Ten wyrażenie regularne jest kompatybilne ze smakami PCRE, Perl, .NET.

Zasadniczo wynika to z „drzewa różnic” (nie jestem pewien, czy jest dla niego odpowiednia nazwa), który mówi regexowi, ile więcej xów ma pasować do następnej czwartej potęgi:

1     16    81    256   625   1296  2401 ...
   15    65    175   369   671   1105 ...
      50    110   194   302   434 ...
         60    84    108   132 ...
            24    24    24 ...  # the differences level out to 24 on the 4th iteration

\2, \3, \4Przechowuje i aktualizuje różnica jak pokazano na 2., 3. i 4. rzędach, odpowiednio.

Konstrukcję tę można łatwo rozbudować o większe moce.

Z pewnością nie jest to eleganckie rozwiązanie, ale działa.


+1. Świetna odpowiedź. Chociaż ta odpowiedź różni się od mojej (używa warunkowego wyrażenia regularnego, podczas gdy moja nie), ma ten sam duch jak moje rozwiązanie (wykorzystując drzewo różnic i wykorzystując zadeklarowane w przód odniesienie niektórych silników wyrażeń regularnych).
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨d̷̰̀ĥ̷̳

fajny pomysł na drzewo różnicowe. dla kwadratów drzewo ma 1 4 9 16 ... 3 5 7 ... 2 2 2, prawda?
Sparr

@Sparr dzięki i tak
Zmienność

24

Inne rozwiązanie

To, moim zdaniem, jeden z najciekawszych problemów na stronie. Muszę podziękować deadcode za podbicie go z powrotem na samą górę.

^((^|xx)(^|\3\4\4)(^|\4x{12})(^x|\1))*$

39 bajtów , bez żadnych warunków i zapewnień ... w pewnym sensie. Alternacje, w miarę ich wykorzystywania ( ^|), są rodzajem warunkowego sposobu wyboru między „pierwszą iteracją” a „nie pierwszą iteracją”.

Ten regex można zobaczyć tutaj: http://regex101.com/r/qA5pK3/1

Zarówno PCRE, jak i Python poprawnie interpretują wyrażenie regularne, a także zostało przetestowane w Perlu do n = 128 , w tym n 4 -1 i n 4 +1 .


Definicje

Ogólna technika jest taka sama jak w przypadku innych rozwiązań już umieszczone: określenia ekspresji odniesienie lokalne, które przy każdej kolejnej iteracji odpowiada długości równej następnego okresu przedniej funkcji różnicy D f , z nieograniczonym kwantyfikator ( *). Formalna definicja funkcji różnicy w przód:

Definicja 1: funkcja różnicy w przód

Dodatkowo można również zdefiniować funkcje różnic wyższych rzędów:

Definicja 2: funkcja drugiej różnicy naprzód

Lub bardziej ogólnie:

Definicja 3: kth funkcja różnicy do przodu

Funkcja różnicy w przód ma wiele interesujących właściwości; chodzi o sekwencjonowanie pochodnej funkcji ciągłych. Na przykład, D C O mocy n p Wielomian stopnia zawsze będzie N-1 p Wielomian stopnia, a dla każdej I , jeśli D f I = D, F i + 1 , wtedy funkcja f jest wykładniczy, w taki sam sposób, że pochodna e x jest sobie równa. Najprostsza funkcja dyskretna, dla której f = D f wynosi 2 n .


f (n) = n 2

Zanim przeanalizujemy powyższe rozwiązanie, zacznijmy od czegoś nieco łatwiejszego: wyrażenia regularnego, które pasuje do ciągów, których długości są idealnym kwadratem. Analiza funkcji różnicy naprzód:

FDF: n ^ 2

Oznacza to, że pierwsza iteracja powinna pasować do ciągu o długości 1 , drugi ciąg o długości 3 , trzeci ciąg o długości 5 itd. I ogólnie każda iteracja powinna pasować do ciągu o dwa dłuższe niż poprzednie. Odpowiednie wyrażenie regularne wynika prawie bezpośrednio z tego oświadczenia:

^(^x|\1xx)*$

Można zauważyć, że pierwsza iteracja będzie pasować tylko do jednej x, a każda kolejna iteracja będzie pasowała do ciągu dwóch dłuższych niż poprzednie, dokładnie tak, jak określono. Oznacza to również niezwykle krótki idealny test kwadratowy w perlu:

(1x$_)=~/^(^1|11\1)*$/

Wyrażenie regularne może być dalej uogólnione, aby pasowało do dowolnej n -gonal długości:

Liczby trójkątne:
^(^x|\1x{1})*$

Liczby kwadratowe:
^(^x|\1x{2})*$

Liczby pięciokątne:
^(^x|\1x{3})*$

Liczby sześciokątne:
^(^x|\1x{4})*$

itp.


f (n) = n 3

Przechodząc do n 3 , jeszcze raz analizując funkcję różnicy naprzód:

FDF: n ^ 3

Może nie być od razu widoczne, jak to zaimplementować, dlatego badamy również drugą funkcję różnicy:

FDF ^ 2: n ^ 3

Tak więc funkcja różnicy do przodu nie zwiększa się o stałą, ale raczej o wartość liniową. Fajnie, że początkowa („ -1 ”) wartość D f 2 wynosi zero, co oszczędza inicjalizację przy drugiej iteracji. Wynikowe wyrażenie regularne jest następujące:

^((^|\2x{6})(^x|\1))*$

Pierwsza iteracja będzie pasować do 1 , tak jak poprzednio, druga będzie pasować do ciągu 6 dłuższych ( 7 ), trzecia będzie pasowała do ciągu 12 dłuższych ( 19 ) itp.


f (n) = n 4

Funkcja różnicy w przód dla n 4 :

FDF: n ^ 4

Druga funkcja różnicy w przód:

FDF ^ 2: n ^ 4

Trzecia funkcja różnicy w przód:

FDF ^ 3: n ^ 4

To brzydkie. Początkowe wartości D f 2 i D f 3 są niezerowe, odpowiednio 2 i 12 , co należy uwzględnić. Prawdopodobnie już zorientowałeś się, że wyrażenie regularne będzie zgodne z następującym wzorcem:

^((^|\2\3{b})(^|\3x{a})(^x|\1))*$

Ponieważ D f 3 podczas drugiej iteracji musi mieć długość 12 , a to koniecznie 12 . Ponieważ jednak zwiększa się o 24 w każdym członie, kolejne głębsze zagnieżdżenie musi dwukrotnie użyć poprzedniej wartości, co oznacza b = 2 . Ostatnią rzeczą do zrobienia jest zainicjowanie D f 2 . Ponieważ D f 2 wpływa bezpośrednio na D f , co ostatecznie chcemy dopasować, jego wartość można zainicjować, wstawiając odpowiedni atom bezpośrednio do wyrażenia regularnego, w tym przypadku (^|xx). Ostateczne wyrażenie regularne staje się wtedy:

^((^|xx)(^|\3\4{2})(^|\4x{12})(^x|\1))*$

Wyższe zamówienia

Wielomian piątego rzędu można dopasować za pomocą następującego wyrażenia regularnego:
^((^|\2\3{c})(^|\3\4{b})(^|\4x{a})(^x|\1))*$

f (n) = n 5 jest dość łatwym ćwiczeniem, ponieważ początkowe wartości zarówno dla drugiej, jak i czwartej funkcji różnicy w przód wynoszą zero:

^((^|\2\3)(^|\3\4{4})(^|\4x{30})(^x|\1))*$

Dla wielomianów sześciu rzędów:
^((^|\2\3{d})(^|\3\4{c})(^|\4\5{b})(^|\5x{a})(^x|\1))*$

W przypadku wielomianów siódmego rzędu:
^((^|\2\3{e})(^|\3\4{d})(^|\4\5{c})(^|\5\6{b})(^|\6x{a})(^x|\1))*$

itp.

Zauważ, że nie wszystkie wielomiany można dopasować dokładnie w ten sposób, jeśli którykolwiek z niezbędnych współczynników nie jest liczbą całkowitą. Na przykład n 6 wymaga, aby a = 60 , b = 8 , a c = 3/2 . Można to obejść, w tym przypadku:

^((^|xx)(^|\3\6\7{2})(^|\4\5)(^|\5\6{2})(^|\6\7{6})(^|\7x{60})(^x|\1))*$

Tutaj zmieniłem b na 6 , a c na 2 , które mają ten sam produkt, co wyżej podane wartości. Ważne jest, aby produkt się nie zmieniał, ponieważ · b · c ·… kontroluje funkcję stałej różnicy, która dla wielomianu szóstego rzędu to D f 6 . Obecne są dwa atomy inicjujące: jeden do inicjalizacji D f do 2 , jak w przypadku n 4 , a drugi do inicjalizacji funkcji piątej różnicy do 360 , przy jednoczesnym dodaniu brakujących dwóch z b .


Na jakich silnikach to przetestowałeś?
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨d̷̰̀ĥ̷̳

W końcu rozumiem, co się dzieje. Rzeczywiście jedyne, czego potrzeba, to wsparcie dla odniesienia do przodu. +1
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨d̷̰̀ĥ̷̳

@nhahtdh ahh, masz rację. Odnośniki do przodu niekoniecznie są też cechą uniwersalną.
primo

1
Doskonały! Uwielbiam to, jak krótkie, proste i łatwe do zrozumienia. Dzięki płytkiemu zagnieżdżeniu łatwo jest ręcznie obliczyć, jak się zachowa. Ponadto, jest to równie szybko, jak zmienność „S i nhahtdh s rozwiązań”. Uwielbiam twoje szczegółowe wyjaśnienie, w tym demonstrację, że można to nawet rozszerzyć na wielomiany. Dałbym punkty bonusowe, gdybym mógł.
Deadcode

@ Lynn dzięki! Nie spodziewałam się, że ...
primo

13

Oto rozwiązanie, które nie wykorzystuje warunkowych, zadeklarowanych do przodu lub zagnieżdżonych odwołań wstecznych, lookbehind, równoważenia grup ani rekursji wyrażeń regularnych. Używa tylko wstecznego i standardowych odwołań wstecznych, które są bardzo szeroko obsługiwane. Zainspirowałem się do działania w tych granicach dzięki Regex Golf , który wykorzystuje silnik regex ECMAScript.

Sposób działania tego 50-bajtowego wyrażenia regularnego jest koncepcyjnie raczej prosty i zupełnie inny niż wszystkie inne przedstawione rozwiązania tej układanki. Zaskakujące było odkrycie, że tego rodzaju logika matematyczna była wyrażona w wyrażeniu regularnym.

      \2                     \4  \5
^((?=(xx+?)\2+$)((?=\2+$)(?=(x+)(\4+)$)\5){4})*x?$

(Grupy przechwytywania są oznaczone powyżej wyrażenia regularnego)

Regex może być uogólnione do dowolnej mocy po prostu przez zastąpienie 4in {4}o pożądanej mocy.

Wypróbuj online!

Działa poprzez wielokrotne dzielenie najmniejszej czwartej potęgi liczby pierwszej, przez którą można podzielić bieżącą wartość. W związku z tym iloraz na każdym kroku jest zawsze czwartą potęgą, jeśli pierwotna wartość była czwartą potęgą. Końcowy iloraz 1 wskazuje, że pierwotna wartość była rzeczywiście czwartą potęgą; to kończy dopasowanie. Zero jest również dopasowane.

Najpierw używa leniwej grupy przechwytywania, \2aby uchwycić najmniejszy czynnik liczby większy niż 1. W związku z tym gwarantuje się, że czynnik ten jest liczbą pierwszą. Na przykład przy 1296 (6 ^ 4) początkowo przechwyci \2= 2.

Następnie na początku powtarzanej 4 razy pętli sprawdza, czy bieżąca liczba jest podzielna przez \2, za pomocą (?=\2+$). Test ten po raz pierwszy jest bezużyteczny, ale jego cel stanie się widoczny później.

Następny wewnątrz tej pętli wewnętrznej, używa chciwy grupę przechwytywania \4uchwycić number największy współczynnik mniejszy niż on sam: (?=(x+)(\4+)$). W efekcie dzieli to liczbę przez jej najmniejszy czynnik pierwszy \2; na przykład 1296 zostanie początkowo przechwycone jako \4= 1296/2 = 648. Zauważ, że podział bieżącej liczby przez \2jest niejawny. Chociaż możliwe jest wyraźne podzielenie bieżącej liczby przez liczbę zawartą w grupie przechwytywania (którą odkryłem dopiero cztery dni po opublikowaniu tej odpowiedzi), zrobienie tego spowodowałoby wolniejsze i trudniejsze do zrozumienia wyrażenie regularne, i nie jest to konieczne, ponieważ najmniejszy współczynnik liczby większy niż 1 zawsze będzie pasował do jego największego współczynnika mniejszego niż on sam (tak, że ich iloczyn jest równy samej liczbie).

Ponieważ ten rodzaj wyrażenia regularnego może „pożreć” ciąg (zmniejszając go), pozostawiając wynik na końcu łańcucha, musimy „przenieść” wynik podziału na koniec łańcucha. Odbywa się to poprzez przechwycenie wyniku odejmowania (bieżąca liczba minus \4), do grupy przechwytywania \5, a następnie poza spojrzeniem, dopasowanie części początku bieżącej liczby odpowiadającej \5. Pozostawia to nieprzetworzony ciąg na końcu o dopasowanej \4długości.

Teraz pętla wraca do początku wewnętrznej pętli, gdzie staje się jasne, dlaczego istnieje test podzielności przez czynnik pierwszy. Właśnie podzieliliśmy przez najmniejszą liczbę pierwszą liczby; jeśli liczba jest nadal podzielna przez ten współczynnik, oznacza to, że pierwotna liczba może być podzielna przez czwartą potęgę tego współczynnika. Przy pierwszym wykonaniu tego testu jest on bezużyteczny, ale kolejne 3 razy określa, czy wynik niejawnego dzielenia przez \2jest nadal podzielny przez \2. Jeśli nadal jest podzielna przez \2na początku każdej iteracji pętli, oznacza to, że każda iteracja dzieli liczbę przez \2.

W naszym przykładzie z wejściem 1296 nastąpi pętla w następujący sposób:

\2= 2
\4= 1296/2 = 648
\4= 648/2 = 324
\4= 324/2 = 162
\4= 162/2 = 81

Teraz wyrażenie regularne może powrócić do pierwszego kroku; to właśnie *robi finał . W tym przykładzie 81 stanie się nowym numerem; następna pętla przebiegnie w następujący sposób:

\2= 3
\4= 81/3 = 27
\4= 27/3 = 9
\4= 9/3 = 3
\4= 3/3 = 1

Powróci teraz ponownie do pierwszego kroku, z 1 jako nowym numerem.

Liczby 1 nie można podzielić przez żadną liczbę pierwszą, przez co byłaby niepasująca (?=(xx+?)\2+$), więc wychodzi ona z pętli najwyższego poziomu (tej z *końcem). Teraz osiąga x?$. Może to być tylko zero lub jeden. Obecna liczba w tym punkcie będzie wynosić 0 lub 1 tylko wtedy, gdy pierwotna liczba była doskonałą czwartą potęgą; jeśli w tym momencie jest 0, oznacza to, że pętla najwyższego poziomu nigdy niczego nie pasowała, a jeśli jest 1, oznacza to, że pętla najwyższego poziomu dzieliła idealną czwartą moc w dół, dopóki nie była już przez nic podzielna (lub było 1 w pierwszej kolejności, co oznacza, że ​​pętla najwyższego poziomu nigdy niczego nie pasowała).

Możliwe jest również rozwiązanie tego w 49 bajtach przez powtarzanie jawnego podziału (który jest również uogólniony dla wszystkich mocy - zamień pożądaną moc minus jeden na {3}), ale ta metoda jest znacznie wolniejsza i objaśnia algorytm, którego używa wykracza poza zakres tej odpowiedzi:

^((x+)((\2(x+))(?=(\4*)\2*$)\4*(?=\5$\6)){3})?x?$

Wypróbuj online!


Z moich testów (do długości 1024) wydaje się, że jest poprawny. Jednak wyrażenie regularne jest zbyt wolne - zajmuje dużo czasu, aby dopasować długość 16 ^ 4, więc bardzo trudno jest zweryfikować dużą liczbę. Ale ponieważ wydajność nie jest wymagana, będę głosować, gdy zrozumiem twoje wyrażenie regularne.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨d̷̰̀ĥ̷̳

1
Twoje wyrażenia regularne i zmienność są niesamowite. Zadziwiają mnie ich szybkość i zwięzłość, obie pasujące do 100000000 w 7,5 sekundy na moim i7-2600k, znacznie szybciej niż oczekiwałbym tego wyrażenia regularnego. Moje rozwiązanie ma zupełnie inny rząd wielkości, ponieważ dopasowanie do 50625 zajmuje 12 sekund. Ale moim celem nie była szybkość, ale raczej wykonanie zadania przy minimalnej długości kodu przy użyciu znacznie bardziej ograniczonego zestawu operacji.
Deadcode

Nasze odpowiedzi są szybkie, ponieważ prawie nie cofają się. Twoi ludzie często się wycofują ((((x+)\5+)\4+)\3+)\2+$. Twój jest również niesamowity na swój sposób, ponieważ nie mogę nawet wymyślić, jak dopasować liczbę kwadratową bez zadeklarowanego wstecz odniesienia.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨d̷̰̀ĥ̷̳

Nawiasem mówiąc, to pytanie nie jest golfem, ale zagadką. Nie oceniam rozwiązania według długości kodu.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨d̷̰̀ĥ̷̳

O. To wyjaśnia, dlaczego użyłeś (?:). Czy więc powinienem edytować swoją odpowiedź, aby ustawić wersję zoptymalizowaną jako podstawową?
Deadcode

8

Rozwiązanie

^(?:(?=(^|(?<=^x)x|xx\1))(?=(^|\1\2))(^x|\3\2{12}xx))*$

Ten wyrażenie regularne jest kompatybilne ze smakami Java, Perl, PCRE i .NET. Ten regex wykorzystuje całkiem szeroki zakres funkcji: spojrzenie w przyszłość, spojrzenie w przeszłość i zadeklarowane wstecz referencje. Deklarowane z wyprzedzeniem rodzaje referencji ograniczają kompatybilność tego wyrażenia regularnego z kilkoma silnikami.

Wyjaśnienie

To rozwiązanie wykorzystuje następującą pochodną.

Poprzez pełne rozszerzenie sumowania możemy udowodnić następującą równość:

\ sum \ limit_ {i = 1} ^ n (i + 1) ^ 4 - \ sum \ limit_ {i = 1} ^ ni ^ 4 = (n + 1) ^ 4-1
\ sum \ limit_ {i = 1} ^ ni ^ 4 - \ sum \ limit_ {i = 1} ^ n (i-1) ^ 4 = n ^ 4

Połączmy sumę po lewej stronie:

\ sum \ limit_ {i = 1} ^ n (4 (i + 1) ^ 3 - 6 (i + 1) ^ 2 + 4 (i + 1) - 1) = (n + 1) ^ 4-1
\ sum \ limit_ {i = 1} ^ n (4i ^ 3 - 6i ^ 2 + 4i - 1) = n ^ 4

Odejmij 2 równania (równanie górne minus równanie dolne), a następnie połącz sumy po lewej stronie, a następnie uprość:

\ sum \ limit_ {i = 1} ^ n (12i ^ 2 + 2) = (n + 1) ^ 4 - n ^ 4 - 1

Różnicę między kolejnymi czwartymi potęgami uzyskujemy jako sumę mocy:

(n + 1) ^ 4 - n ^ 4 = \ sum \ limit_ {i = 1} ^ n (12i ^ 2 + 2) + 1

Oznacza to, że różnica między kolejnymi czwartymi potęgami wzrośnie o (12n 2 + 2).

Aby ułatwić myślenie, odwołując się do drzewa różnic w odpowiedzi Zmienności :

  • Prawa strona końcowego równania jest drugim rzędem w drzewie różnic.
  • Przyrost (12n 2 + 2) jest trzecim rzędem w drzewie różnic.

Dosyć matematyki. Powrót do powyższego rozwiązania:

  • Pierwsza grupa przechwytująca utrzymuje serię liczb nieparzystych, aby obliczyć i 2, jak widać w równaniu.

    Dokładnie mówiąc, długość 1. grupy przechwytywania będzie wynosić 0 (nieużywane), 1, 3, 5, 7, ... podczas iteracji pętli.

    (?<=^x)xustawia wartość początkową dla serii liczb nieparzystych. ^Jest właśnie tam, aby umożliwić spojrzenie wyprzedzeniem jakie muszą być spełnione w pierwszej iteracji.

    xx\1 dodaje 2 i przechodzi do następnej liczby nieparzystej.

  • Druga grupa przechwytująca utrzymuje serię liczb kwadratowych dla i 2 .

    Dokładnie mówiąc, długość drugiej grupy przechwytywania będzie wynosić 0, 1, 4, 9, ... podczas iteracji pętli.

    ^in (^|\1\2)ustawia wartość początkową szeregu liczb kwadratowych. I \1\2dodaje nieparzystą liczbę do bieżącego numeru kwadratu, aby przejść do następnego numeru kwadratu.

  • Trzecia grupa przechwytywania (poza wszelkim wyprzedzeniem i faktycznie zużywa tekst) pasuje do całej prawej strony równania, które wyprowadziliśmy powyżej.

    ^xin (^x|\3\2{12}xx)ustawia wartość początkową, która jest + 1prawą stroną równania.

    \3\2{12}xxdodaje wzrost różnicy (12n 2 + 2) przy użyciu n 2 z grupy przechwytywania 2 i dopasowuje różnicę w tym samym czasie.

Takie ustawienie jest możliwe, ponieważ ilość tekstu dopasowanego w każdej iteracji jest większa lub równa ilości tekstu potrzebnego do wykonania przewidywania w celu skonstruowania n 2 .

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.