Wszystkie kwadraty pasujące do sekwencji symboli wieloznacznych [zamknięte]

9

Zostało to zainspirowane częścią konkursu ARML 2016 Problem zespołu nr 6.

Oto wyzwanie:

Otrzymujesz „sekwencję symboli zastępczych”, która jest sekwencją cyfr i innego znaku. Ciąg pasuje do tej sekwencji symboli wieloznacznych według następującego pseudokodu:

w = wildcard
s = string
# s matches w iff
for all 0 >= i > wildcard.length, w[i] == '?' or s[i] == w[i]

Gdzie '?' jest postacią twojego wyboru.

Jeśli chodzi o wyrażenia regularne, wyobraź sobie, że '?'jest '.'.

Wyzwanie polega na znalezieniu wszystkich liczb kwadratowych (wymaganie to do 1 miliona), których ciąg dziesiętny odpowiada ciągowi symboli zastępczych. „Znak wieloznaczny” może być dowolnym wybranym przez ciebie znakiem ASCII, o ile oczywiście nie jest cyfrą.

Na przykład, 4096mecze 4**6i 4*9*ale 4114nie pasuje albo.

Wejście

Dane wejściowe zostaną podane jako sekwencja pasująca do wyrażenia regularnego [0-9?]+. Może to być ciąg znaków, tablica znaków lub tablica bajtów znaków w ASCII.

Wynik

Wynikiem będzie dowolna lista / zestaw / tablica liczb, które są idealnymi kwadratami i pasują do sekwencji symboli wieloznacznych.

Przykłady prawidłowych danych wejściowych:

1234567*90
1234567?90
1234567u90
['1', '2', '3', '4', '5', '6', '7', '*', '9', '0']
[49, 50, 51, 52, 53, 54, 55, 42, 57, 48]
[1, 2, 3, 4, 5, 6, 7, '*', 9, 0]

Przykłady prawidłowych wyników:

[1, 4, 9]
1 4 9
1, 4, 9
1-4-9

itp.

Dane techniczne

  • Nie można używać wbudowanych funkcji do znajdowania listy kwadratów w określonym zakresie
  • Obowiązują standardowe luki
  • Musisz być w stanie obsłużyć do 1 000 000 (1 milion)
  • Jeśli jest wyposażony w dane wejściowe 1******, drukowanie jest prawidłowe [1000000]. Prawidłowe jest również drukowanie[1000000, 1002001, 1004004, 1006009, 1008016, 1010025, ...]
  • Sekwencje symboli wieloznacznych nigdy nie zaczynają się od znaku wieloznacznego; oznacza to, że zawsze będą pasować do ciągów o tej samej długości.

Przypadki testowe

4**6  ->  [4096, 4356]
1**1  ->  [1521, 1681]
1**  ->  [100, 121, 144, 169, 196]
9****9  ->  [908209, 915849, 927369, 935089, 946729, 954529, 966289, 974169, 986049, 994009]
9*9***  ->  [919681, 929296]
1**0*  ->  [10000, 10201, 10404, 10609, 12100, 14400, 16900, 19600]
9***4  ->  [91204, 94864, 97344]

Zwycięski

Najkrótsze (ważne) (działające) zgłoszenie do 14 lutego, rozstrzygnięcie po wygraniu najwcześniejszego zgłoszenia.

HyperNeutrino
źródło
1
Myślę, że dobrym początkiem wyjaśnienia byłoby sprecyzowanie, które ?ma wybrać osoba odpowiadająca.
FryAmTheEggman
2
Dlaczego 25ważna jest odpowiedź na, ***ale nie na *2*?
Neil
3
Myślę, że byłoby to czystsze, gdyby liczby nigdy nie miały zer wiodących, więc pasowały tylko sekwencje ich długości.
xnor
@ Neil Byłby to problem z moim własnym rozwiązaniem. Przyjmę sugestię Xnora.
HyperNeutrino,
Czy wejściem może być tablica jednocyfrowych liczb całkowitych i znaku specjalnego, takiego jak {4, "w", "w", 6}(lub jeszcze lepiej {4, w, w, 6}), a nie tablica znaków, na przykład {"4", "w", "w", "6"}?
Greg Martin

Odpowiedzi:

0

05AB1E , 22 bajty

Prawdopodobnie jest tu dużo miejsca na ulepszenia.
Każda cyfra nie będąca cyfrą jest odpowiednia jako symbol wieloznaczny.

3°LnvyS¹)ø€Æ0QPyg¹gQ&—

Wypróbuj online!

Wyjaśnienie, które nastąpi po dalszej grze w golfa.

Emigna
źródło
Wydaje się, że działa to dla wszystkich danych wejściowych. Dobra robota.
HyperNeutrino,
1

Mathematica, 44 bajty

Print@@@IntegerDigits[Range@1*^3^2]~Cases~#&

Dane wejściowe to lista cyfr z _symbolem wieloznacznym (bez cudzysłowów). na przykład{4, _, _, 6}

Wyjaśnienie

Range@1*^3

Wygeneruj listę {1, 2, 3, ... , 1000}

... ^2

Wyprostuj to. (lista wszystkich kwadratów od 1 do 1 000 000)

IntegerDigits[ ... ]

Podziel każdy kwadrat na listę cyfr.

... ~Cases~#

Znajdź te, które pasują do wzorca określonego przez dane wejściowe.

Print@@@ ...

Wydrukuj je.

JungHwan Min
źródło
Wydaje się, że działa to dla wszystkich przypadków testowych. Dobra robota.
HyperNeutrino,
1

Brachylog , 23 bajty

@e:{@$|,}a#0:{c.~^#I,}f

Wypróbuj online!

Wyjaśnienie

@e                        Split into a list of characters
  :{@$|,}a                Replace each digit char by the corresponding digit, and each things
                            that are ot digits into variables
          #0              All elements of the resulting list must be digits
            :{       }f   Output is the result of finding all...
              c.            ...concatenations of those digits which...
               .~^#I,       ...result in a number which is the square of an integer #I

Inny format wejściowy, 13 bajtów

W zależności od tego, co uważasz za ważne jako dane wejściowe, możesz to zrobić:

#0:{c.~^#I,}f

Wypróbuj online!

który jest w zasadzie drugą częścią powyższej odpowiedzi, z listą jako danymi wejściowymi zawierającymi cyfry i zmienne, w których znajdują się symbole wieloznaczne.

Nie uważam tego za ważne, ponieważ w Brachylog jest tylko 26 nazw zmiennych (wielkie litery), więc nie zadziałałoby, gdybyś miał więcej niż 26 wilcards.

Fatalizować
źródło
Wydaje się, że działa to dla wszystkich danych wejściowych. Dobra robota. Uważałbym jednak, że to 24 bajty, ponieważ wymagany jest argument 1-bajtowy. Nie jestem jednak pewien, jak by to działało.
HyperNeutrino,
1
@AlexL. Argument służy tylko do podania nazwy zmiennej wyjściowej (jeśli chcesz, możesz użyć innej dużej litery). Jest to podobne do odpowiedzi w Prologu / językach z funkcjami, w których nazwano predykat / funkcję, ale tak naprawdę nie liczymy bajtów używanych podczas wywoływania.
Fatalize
W porządku. Nie jestem pewien, czy należy go ocenić jako 24, ponieważ argument jest konieczny (w przeciwnym razie po prostu zwraca true.), ale wcześniej nie używałem języków, które tego wymagają. Spróbuję znaleźć jakieś odniesienie, aby ustalić, jak powinienem to zdobyć, ale sensowne byłoby przyznanie go jako 23, więc zachowam to.
HyperNeutrino,
1

Perl 6 , 30 26 bajtów

Dzięki @ b2gills za -4 bajty!

{grep /^<$_>$/,map * **2,^1e4}

{grep /^<$_>$/,(^1e4)»²}

Używa kropki jako znaku wieloznacznego, dzięki czemu dane wejściowe można wykorzystać jako wyrażenie regularne:

{                            }   # a lambda
                         ^1e4    # range from 0 to 9999
               map * **2,        # square each value
 grep /      /,                  # filter numbers that match this regex:
        <$_>                     #   lambda argument eval'ed as sub-regex
       ^    $                    #   anchor to beginning and end

Wypróbuj online .

Wariant, który akceptuje gwiazdkę jako symbol wieloznaczny (jak sugerowano w poprzedniej wersji opisu zadania), miałby 42 bajty:

{grep /^<{.trans("*"=>".")}>$/,(^1e4)»²}
smls
źródło
Przekształciłem zasady i możesz wybrać dowolny znak wieloznaczny. Zaliczam to jako 38 bajtów.
HyperNeutrino
Jak tego używasz? Nic nie wiem o Perlu.
HyperNeutrino,
@AlexL .: Dziękuję, zaktualizowałem odpowiedź (i dodałem też wyjaśnienie). To lambda; możesz wywołać go bezpośrednio (np. { ... }("9*9***")) lub przypisać do zmiennej / symbolu do późniejszego wykorzystania. Zauważ, że Perl 6 jest językiem innym niż Perl, więc nie będzie działał z interpretatorem Perla.
smls
Kiedyś sudo apt-get install rakudodostawałem rzekomy interpreter Perl6 ... Kiedy wstawiam perl6jako polecenie do mojego terminala, zaczyna się coś, co wydaje się być interpreterem Perl6, ale nie wiem, jak go używać. Wiem, że to lambda, ale nie wiem jak to nazwać.
HyperNeutrino
@AlexL .: Dodałem link „Wypróbuj online”, który pokazuje go jako pełny skrypt, który można uruchomić jako perl6 foo.p6. Możesz również przetestować go w skorupie oneliner, na przykładperl6 -e 'say {grep /^<$_>$/,map * **2,^1e4}( "9.9..." )'
sms
1

Rubinowy, 54 bajty

Funkcja, która pobiera argument ciągu. Wypróbuj online.

->s{(0..1e3).map{|i|"#{i**2}"[/^#{s.tr ?*,?.}$/]}-[p]}
Wartość tuszu
źródło
Możesz zapisać bajt, używając i * i zamiast i ** 2
GB
To nie wydaje się działać, ponieważ drugi #powoduje, że reszta linii jest komentarzem.
HyperNeutrino,
@AlexL Oh, działa dobrze. repl.it/FJCV
Wartość tuszu
ohhhh ok, po prostu nie wiedziałem, jak przetestować Ruby. Przepraszam. To wydaje się działać dla wszystkich danych wejściowych. Dobra robota!
HyperNeutrino
0

Partia, 109 bajtów

@for /l %%i in (0,1,999)do @set/aj=%%i*%%i&call copy nul %%j%%.%%j%%$>nul
@for %%s in (%1.%1$)do @echo %%~ns

Używa ?jako symbolu wieloznacznego. Działa, tworząc 1000 plików. Nazwa pliku to liczba kwadratowa, a rozszerzenie pliku to liczba kwadratowa z $sufiksem. Wynika to z faktu, że dopasowanie wzorca Batch liczy końcowe ?s jako opcjonalne, więc 1?dopasuje oba 1i 16; $dlatego zmusza mecz mają być dokładne. Jednak nie chcemy $wyprowadzać pliku, więc po prostu wypisujemy nazwę pliku tylko bez rozszerzenia.

Neil
źródło
0

JavaScript (ES6), 68 66 bajtów

EDYCJA: Zaktualizowałem moje rozwiązanie poniżej po zainspirowaniu odpowiedzią JungHwan Min . Jest teraz zgodny z ES6.

Pobiera dane wejściowe w formacie, w '1..4'którym .znajduje się symbol wieloznaczny.

Zamiast iteracji do 1e6 i kwadratowego zrootowania ten iteruje do 1e3 i kwadratów.

p=>[...Array(1e3)].map((_,n)=>''+n*n).filter(n=>n.match(`^${p}$`))

JavaScript (ES7), 71 69 bajtów

p=>[...Array(1e6).keys()].filter(n=>n**.5%1?0:(''+n).match(`^${p}$`))

Tworzy tablicę liczb od 0 do 1e6, a następnie filtruje ją według liczb, które są kwadratowe i pasują do wzorca.

Jest strasznie powolny, ponieważ zawsze iteruje do 1e6.

George Reith
źródło
Nie sądzę, że **działa, ponieważ daje mi to "SyntaxError: expected expression, got '*'".
HyperNeutrino,
@AlexL. Wydaje się, że zasady się zmieniły. Poprzednie zasady sugerowały, że mogłem wybrać znak wieloznaczny.
George Reith,
Musisz wesprzeć tylko do 1e6...
HyperNeutrino 13.01.17
Dodatkowo zmieniłem zasady z powrotem; problem nie dotyczy reguł, to dlatego, że **operator nie istnieje, przynajmniej nie w moim systemie.
HyperNeutrino,
@AlexL. Ach, przepraszam, myślałem, że masz na myśli wkład **. Tak, to ES7. Zaktualizuję tytuł. Oto lista obecnie obsługiwanych przeglądarek developer.mozilla.org/en/docs/Web/JavaScript/Reference/...
George Reith
0

Perl, 42 45 38 bajtów

EDYCJA: wyjaśnienie Alexa, możemy użyć kropki jako znaku wieloznacznego, który goli operację y //.

perl -pe 's|.*|@{[grep/^$&$/,map$_*$_,1..1e3]}|'

EDYCJA: rozwiązanie wykorzystujące gwiazdkę jako znak wieloznaczny i oczekuje sekwencji symboli wieloznacznych na STDIN

perl -pe 'y/*/./;s|.*|@{[grep/^$&$/,map$_*$_,1..1e3]}|'

Ten pozostawia niewątpliwie dużo miejsca na ulepszenia, jest całkiem prosty. Wyrażenie symbolu wieloznacznego jest oczekiwane jako argument wiersza polecenia, z kropkowym znakiem wieloznacznym okresu (co jeszcze?).

say"@{[grep/^$ARGV[0]$/,map$_*$_,1..1e3]}"
Daniel
źródło
Pytanie określa, że ​​symbole wieloznaczne są podawane jako gwiazdki. Czy wcześniejsza wersja pytania pozwalała na wybranie własnego znaku wieloznacznego?
smls
1
@smls: Pytanie nadal określa, jak wybrać własną symbol wieloznaczny, chociaż nie ma go w sekcji reguł: Znak użyty jako symbol wieloznaczny niekoniecznie musi być gwiazdką, może to być dowolna postać ASCII, o ile oczywiście nie jest cyfrą.
Emigna
Tak, byłem tym zmieszany. Później wyraźnie mówi, że znak wieloznaczny musi być gwiazdką. Wydaje mi się, że definicja z wyrażeniem regularnym jest wiodąca. Poprawię moje rozwiązanie.
Daniel
1
Hm faktycznie zdanie cytowane przez @Emigna jest całkiem jasne, że można wybrać własną wieloznaczny, prawda?
smls
Aby wyjaśnić, znak wieloznaczny może być tym, czego chcesz. Przypadkowo zawiodłem zasady podczas przekształcania wyjaśnienia.
HyperNeutrino,
0

Python 3 - 98 97 bajtów

import re;print(re.findall(r"\b"+input()+r"\b",("\n".join([str(x*x) for x in range(1,1001)]))))

Wymaga danych wejściowych takich jak „4..6”.

Carra
źródło
Możesz zapisać 3 bajty za pomocą import rei re.findall; from...import *w tym przypadku optymalizacja za pomocą parametru faktycznie nie jest optymalizowana.
HyperNeutrino,
Pod warunkiem wejścia 1...., to daje 1 4 9i 16 25jak poprawnych odpowiedzi, która nie jest poprawna. Popraw swój program.
HyperNeutrino,
Napraw skrzynkę, dołączając do „\ n”.
Carra,
To nie działa dla 1....... Wraca [], ale powinien dać [1000000]. Można to naprawić kosztem 0 bajtów za pomocą range(0, 1001)zamiast range(0, 1000).
HyperNeutrino,
Dobrze, właśnie sprawdziłem wszystkie przypadki testowe z opisu :)
Carra,
0

k - 28 znaków

{s(&:)($:s:s*s:!1001)like x}

Używa ?jako znaku wieloznacznego. Do likezastosowania funkcyjne ?jak maska, a funkcja ta tworzy listę pierwszych 1001 kwadratów (być inclusive do 1M), rzuca je wszystkie do ciągów, a następnie sprawdza, gdzie oni pasują do wzorca.

    {s(&:)($:s:s*s:!1001)like x} "1??"
100 121 144 169 196
C. Quilley
źródło
Dostaję ten błąd za to: type error {s(&:)($:s:s*s:!1001)like x} "1" at execution instance 2 of ":". Czy możesz podać link do działającego zestawu testów lub sprawdzić, czy występuje problem?
HyperNeutrino
@AlexL. Działa dla mnie w trybie k kdb +
C. Quilley
Hmm Spróbuję przetestować go z różnymi tłumaczami.
HyperNeutrino
0

narzędzia bash + Unix, 33 bajty

dc<<<'0[2^pv1+lax]dsax'|grep ^$1$

To używa „.” jako znak wieloznaczny.

Program DC drukuje liczby kwadratowe w nieskończonej pętli:

0     Push 0 on the stack.

[     Start a macro (called a).

2^    Square the number at the top of the stack.

p     Print the number at the top of the stack, followed by a newline.

v     Replace the number at the top of the stack (a square number) with its square root.

1+    Increment the number at the top of the stack.

lax   Run the macro again (looping).

]     End of the macro.

dsax  Store the macro in register a and run it.

Wyjście prądu stałego jest przesyłane w potoku do grep, który drukuje tylko kwadraty pasujące do wymaganego wzorca.

Działa to, gdy uruchamiam go na rzeczywistym systemie Linux lub OS X (ale to nie działa w TIO, prawdopodobnie dlatego, że program dc próbuje powtarzać się w nieskończoność, i podejrzewam, że TIO zabrakło miejsca na stos dla rekurencji i / lub ma problem z niekończącą się rurą).

Mitchell Spector
źródło
Używam tego z Linux Mint 17.3 Rosa i to się nie kończy. Myślę, że problem tkwi w niekończącym się dcpoleceniu.
HyperNeutrino
Podejrzewam, że to właśnie buforowanie powoduje problem. Nie mam tej wersji Linuksa, ale możesz spróbować zastąpić grep grep - buforowanym wierszem (aby spowodować wypisanie każdej linii, gdy jest grep). [Oczywiście, że to dodaje liczbę bajtów.]
Mitchell Spector
Dodałem argument grep, ale to nie robi różnicy. Próbowałem umieścić --line-bufferedpo obu stronach ^$1$, ale to nie działa w żaden sposób.
HyperNeutrino
@ AlexL. Dziękuję za próbę. Nie wiem, czy różnica jest w jądrze, czy w wersji bash, którą uruchamiam. Zmusiłem go do pracy w TIO, wymuszając zakończenie polecenia grep za pomocą head, w następujący sposób: dc <<< '0 [2 ^ pv1 + lax] dsax' | head -1 sed s/./0/g<<<$1| grep ^ $ 1 $ Używa długości wzorzec, aby ograniczyć liczbę testowanych liczb (wzorce 4-znakowe sprawdzają tylko do 9999 itd.). Oto link do TIO: tio.run/nexus/…
Mitchell Spector
Dziękuję za poprawkę. Nie sądzę, aby obecne rozwiązanie faktycznie działało (chociaż nie mam zbyt dużej wiedzy na temat bash), ponieważ wydaje się, że musi obliczyć wszystkie wartości przed wprowadzeniem tego grep. Ponieważ jednak nie jest to obecnie najkrótsze rozwiązanie, zachowam 33 bajty do oceny. Wygląda na to, że działa dla wszystkich wejść, więc dobra robota!
HyperNeutrino,