Weź pierwiastek kwadratowy z łańcucha

14

Motywacja

W tym wyzwaniu Twoim zadaniem było pomnożenie dwóch łańcuchów, co naturalnie wprowadza sposób na pierwiastek kwadratowy z łańcucha.

Jak to działa?

Biorąc pod uwagę ciąg znaków (na przykład pub) pierwszą rzeczą, którą musisz zrobić, jest określenie kodu ASCII dla każdego znaku:

"pub" -> [112, 117, 98]

Następnie zamapuj te kody do zakresu [0..94], odejmując 32każdą wartość:

[112, 117, 98] -> [80, 85, 66]

Teraz musisz znaleźć dla każdej wartości jego moduł główny 95(np. 40*40 % 95 = 80Możesz również wybrać 55):

[80, 85, 66] -> [40, 35, 16]

I w końcu zamapujesz go z powrotem na zakres [32..126]i przekonwertujesz z powrotem na ciąg:

[40, 35, 16] -> [72, 67, 48] -> "HC0"

Rzeczywiście, "HC0" ⊗ "HC0" = "pub"jak można to sprawdzić za pomocą rozwiązania z innego wyzwania tutaj .


Osoby zaznajomione z arytmetyką modułową prawdopodobnie zauważyły, że moduł pierwiastkowy z kwadratem 95nie zawsze istnieje, na przykład nie ma pierwiastka 2. W takim przypadku pierwiastek kwadratowy ciągu nie jest zdefiniowany, a Twój program / funkcja może ulec awarii, zapętlić się w nieskończoność itp.

Dla Twojej wygody, oto lista znaków, które mają pierwiastek kwadratowy (pierwszy to spacja):

 !$%&)+03489:>CDGLMQVW]`bjlpqu

Zasady

  • Napisz program / funkcję, która pobiera ciąg (lub listę znaków) jako argument i zwraca dowolny pierwiastek kwadratowy, jeśli istnieje
  • Możesz założyć, że dane wejściowe zawsze mają pierwiastek kwadratowy
  • Dane wejściowe mogą składać się z pustego ciągu
  • Dane wejściowe będą w zakresie do wydrukowania ( [32..126])
  • Dane wyjściowe są drukowane w konsoli lub zwracany jest ciąg znaków, jeśli istnieje pierwiastek kwadratowy
  • Jeśli pierwiastek kwadratowy nie istnieje, zachowanie Twojego programu / funkcji pozostaje niezdefiniowane
  • Jeśli zdecydujesz się wydrukować katalog główny na konsoli, końcowe znaki nowego wiersza lub białe znaki są w porządku

Przypadki testowe

Pamiętaj, że niekoniecznie są to jedyne rozwiązania:

''              -> ''
'pub'           -> 'HC0'
'pull!'         -> 'HC33!'
'M>>M'          -> '>MM>'
'49'            -> '4%'
'64'            -> undefined
'Hello, World!' -> undefined
ბიმო
źródło
Wymuszanie stanu błędu na tych znakach bez pierwiastka kwadratowego wydaje się niepotrzebne, zaleciłbym po prostu niezdefiniowane zachowanie.
ATaco
@ATaco Zaktualizowałem wyzwanie.
ბიმო
Co zrobić, jeśli podany ciąg jest kwadratem wielu ciągów?
tsh
@tsh Zwrot dowolny, zaktualizuję wyzwanie.
ბიმო
1
@curiousdannii Właściwie to powinien być zakres 0-94(to jest zakres do wydruku), to literówka - przepraszam za to.
ბიმო

Odpowiedzi:

10

sh + coreutils, 58 bajtów

tr '$%&)+0389:>CDGLMQVW]`bjpqu' 1u.#:BFO%+M/L2Aa,795d0@H=C

Wypróbuj online!

Modułowy pierwiastek kwadratowy zazwyczaj nie jest unikalny; mamy 2 lub 4 opcje dla każdej postaci z wyjątkiem . Nie trzeba tłumaczyć , !, 4, lponieważ każdy z nich jest już samo w sobie pierwiastek kwadratowy. Dla pozostałych postaci wybieramy obrazy, które nie wymagają ucieczki dla powłoki lub tr.

Anders Kaseorg
źródło
6

Python 3, 57 56 bajtów

lambda s:s.translate({k*k%95+32:k+32for k in range(95)})

translateużywa odwzorowania z „Rzędnych Unicode na Rzędy Unicode”. Dlatego nie potrzebujemy chr/ord konwersji. Uwaga: nie ulega awarii, gdy char nie ma roota.

Zaoszczędzono 1 bajt dzięki @ jonathan-allan

Wartość odwzorowania jest największym rdzeniem w zakresie 0..94 klucza. Aby mieć najmniejszy root (jak w przykładach), użyj:

lambda s:s.translate({k*k%95+32:k+32for k in range(95,0,-1)})

(61 bajtów)

>>> [s.translate({k*k%95+32:k+32for k in range(95,0,-1)}) for s in ['','pub','pull!','M>>M','49','64','Hello, World!']]
['', 'HC0', 'HC33!', '>MM>', '4%', '64', 'He33o,\x7f9or3d!']
Jferard
źródło
Witamy! Niezły pierwszy post. Możesz usunąć spację między 32i for.
Jonathan Allan
... również tutaj jest link do internetowego zestawu testów tłumacza.
Jonathan Allan
3

Python 2 , 80 bajtów

lambda s:''.join([chr(i+32)for i in range(95)if i*i%95==ord(c)-32][0]for c in s)

Wypróbuj online!

Zgłasza błąd IndexError, jeśli nie istnieje root.

Chas Brown
źródło
3

Japt , 16 15 bajtów

c@H+LDz%95+HÃbX

Wypróbuj online!

Zapisano bajt, patrząc na odpowiedź 05AB1E (używając L= 100 zamiast 95). Teraz Japt jest najkrótszym, dość rzadkim zjawiskiem :-D

Wyjaśnienie

 c@ H+LÇ   ²  %95+HÃ bX
UcX{H+LoZ{Zp2 %95+H} bX}   Ungolfed
                           Implicit: U = input string, H = 32, L = 100
UcX{                   }   Map each charcode X in the input to the following:
      Lo                     Create the array [0, 1, ..., 98, 99]
        Z{         }         and map each item Z to
          Zp2                  Z ** 2
              %95              mod 95
                 +H            plus 32.
                     bX      Find the first index of X in this array. This gives the
                             smallest square root (mod 95) of (X - 32).
    H+                       Add 32 to map this back into the printable range.
                           Implicit: output result of last expression
ETHprodukcje
źródło
2

Mathematica, 94 bajty

(R[x_]:=Min@Select[Range@45,Mod[#^2,95]==x&];FromCharacterCode[R/@(ToCharacterCode@#-32)+32])&


Wypróbuj online!

J42161217
źródło
2

Galaretka , 18 17 16 bajtów

95Ḷ²%95+32żØṖFyO

Wypróbuj online!(dostarczany ze stopką pakietu testowego)

Zaoszczędzono 2 bajty, wykonując kompletne przepisanie. Również po raz pierwszy znalazłem zastosowanie }.

Wyjaśnienie

Kod najpierw oblicza wszystkie znaki kwadratowe, a następnie odwzorowuje je na odpowiednie pierwiastki kwadratowe.

95Ḷ²%95+32żØṖFyO    Main link. Argument: S (string)
95                    Take 95.
  Ḷ                   Get the array [0, 1, ..., 94].
   ²                  Square each to get [0, 1, ..., 8836].
    %95               Get each square modulo 95 to get [0, 1, ..., 1].
       +32            Add 32 to get [32, 33, ..., 33].
           ØṖ         Get the list of printables [" ", "!", ..., "~"].
          ż           Interleave with printables to get [[32, " "], ..., [33, "~"]].
             F        Flatten the mapping to [32, " ", ..., 33, "~"].
               O      Get the code point of each character in input.
              y       Map the code points to the correct output characters using the map.
PurkkaKoodari
źródło
95Ḷ²%95+32iЀO+31Ọjest w zasadzie tym, co robi moja odpowiedź Japt, chociaż twoje rozwiązanie jest o dwa bajty krótsze ...
ETHproductions
2

JavaScript, 82 bajty

Współpracował z @ETHproductions

s=>s.map(x=>(g=z=>z*z%95==x.charCodeAt(0)-32?String.fromCharCode(z+32):g(z+1))(0))

Dane wejściowe i wyjściowe mają postać tablicy char.

Testowy fragment kodu

Oliver
źródło
2

05AB1E , 17 bajtów

vтLn95%žQykk33+ç?

Algorytm jest bardzo podobny do odpowiedzi Jelly i Japt (Miałem już coś innego, ale to tylko mnie do 19 bajtów)

Wyjaśnienie

vтLn95%žQykk33+ç?
v                 # For each character of the input...
 тL                # Push [1..100]
   n               # Square every element of the list
    95%            # And take it modulo 95
       žQyk        # Push the index of the current character in the printable ascii range
           k       # Push the index of that in the list created earlier
            33+    # Add 33 to the result
               ç   # And convert it back to a character
                ?  # Print the character

Wypróbuj online!

Datboi
źródło
1

Mathematica, 60 bajtów

FromCharacterCode[PowerMod[ToCharacterCode@#-32,1/2,95]+32]&

Funkcja anonimowa. Pobiera ciąg jako dane wejściowe i zwraca ciąg jako dane wyjściowe. Błędy przy nieprawidłowym wprowadzeniu.

LegionMammal978
źródło
1

Perl 6 , 53 bajtów

{[~] .comb.map({32+first *²%95==.ord-32,^95})».chr}

Wypróbuj online!

Sean
źródło
1

Mathematica 82 bajtów

FromCharacterCode[Solve[x^2==#,Modulus->95][[1,1,2]]+32&/@(ToCharacterCode@#-32)]&

Wykorzystanie zdolności Solve do wykonywania arytmetyki modułowej.

Kelly Lowder
źródło