Prenez la racine carrée d'une chaîne

14

Motivation

Dans ce défi, votre tâche consistait à multiplier deux chaînes, ce qui introduit naturellement un moyen de prendre la racine carrée d'une chaîne.

Comment ça marche?

Étant donné une chaîne (par exemple pub), la première chose que vous devez faire est de déterminer le code ASCII pour chaque caractère:

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

Ensuite, vous mappez ces codes à la plage [0..94]en soustrayant 32chaque valeur:

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

Maintenant, vous devez trouver pour chaque valeur son module racine 95(par exemple 40*40 % 95 = 80, vous pouvez également choisir 55):

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

Et enfin, vous allez le mapper à la plage [32..126]et le reconvertir en chaîne:

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

En effet, "HC0" ⊗ "HC0" = "pub"comme vous pouvez le vérifier avec une solution de l'autre défi ici .


Ceux qui connaissent l'arithmétique modulaire ont probablement remarqué que la racine carrée modulo 95n'existe pas toujours, par exemple il n'y a pas de racine pour 2. Dans un tel cas, la racine carrée d'une chaîne n'est pas définie et votre programme / fonction peut se bloquer, boucler indéfiniment, etc.

Pour votre commodité, voici la liste des caractères qui ont une racine carrée (la première est un espace):

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

Règles

  • Vous écrirez un programme / fonction qui prend une chaîne (ou une liste de caractères) comme argument et renvoie toute racine carrée si elle existe
  • Vous pouvez supposer que l'entrée a toujours une racine carrée
  • L'entrée peut être constituée d'une chaîne vide
  • L'entrée sera dans la plage imprimable ( [32..126])
  • La sortie est imprimée sur la console ou vous retournez une chaîne si la racine carrée existe
  • Dans le cas où la racine carrée n'existe pas, le comportement de votre programme / fonction n'est pas défini
  • Si vous choisissez d'imprimer la racine sur la console, les sauts de ligne ou les espaces blancs sont corrects

Cas de test

Notez que ce ne sont pas nécessairement les seules solutions:

''              -> ''
'pub'           -> 'HC0'
'pull!'         -> 'HC33!'
'M>>M'          -> '>MM>'
'49'            -> '4%'
'64'            -> undefined
'Hello, World!' -> undefined
ბიმო
la source
Forcer un état d'erreur sur ces caractères sans racine carrée semble inutile, je recommanderais simplement un comportement non défini.
ATaco
@ATaco J'ai mis à jour le défi.
ბიმო
Que faire si la chaîne donnée est le carré de plusieurs chaînes?
tsh
@tsh Retourne tout, je mettrai à jour le défi.
ბიმო
1
@curiousdannii En fait, ce devrait être la plage 0-94(c'est la plage imprimable), c'est une faute de frappe - désolé.
ბიმო

Réponses:

10

sh + coreutils, 58 octets

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

Essayez-le en ligne!

La racine carrée modulaire n'est généralement pas unique; nous avons 2 ou 4 choix pour chaque personnage sauf . On n'a pas besoin de traduire , !, 4, lpuisque chacun est déjà une racine carrée de lui - même. Pour les caractères restants, nous choisissons des images qui n'ont pas besoin d'être échappées pour le shell ou tr.

Anders Kaseorg
la source
6

Python 3, 57 56 octets

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

translateutilise un mappage des "ordinaux Unicode aux ordinaux Unicode". Ainsi, nous n'avons pas besoinchr / ordconversions. Remarque: il ne plante pas lorsque le caractère n'a pas de racine.

1 octet enregistré grâce à @ jonathan-allan

La valeur du mappage est la plus grande racine dans la plage 0..94 de la clé. Pour avoir le moins de racine (comme dans les exemples), utilisez:

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

(61 octets)

>>> [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
la source
Bienvenue! Bon premier post. Vous pouvez supprimer l'espace entre 32et for.
Jonathan Allan
... également, voici un lien vers une suite de tests d'interprètes en ligne.
Jonathan Allan
3

Python 2 , 80 octets

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

Essayez-le en ligne!

Lève IndexError si aucune racine n'existe.

Chas Brown
la source
3

Japt , 16 15 octets

c@H+LDz%95+HÃbX

Essayez-le en ligne!

Enregistré un octet en regardant la réponse 05AB1E (en utilisant L= 100 au lieu de 95). Maintenant, Japt est le plus court, une occurrence assez rare :-D

Explication

 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
ETHproductions
la source
2

Mathematica, 94 octets

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


Essayez-le en ligne!

J42161217
la source
2

Gelée , 18 17 16 octets

95Ḷ²%95+32żØṖFyO

Essayez-le en ligne!(livré avec le pied de page de la suite de tests)

Sauvegardé 2 octets en effectuant une réécriture complète. Aussi la première fois que j'ai trouvé une utilisation pour }.

Explication

Le code calcule d'abord tous les caractères carrés, puis les mappe à leurs racines carrées respectives.

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
la source
95Ḷ²%95+32iЀO+31Ọest essentiellement ce que fait ma réponse Japt, bien que votre solution soit plus courte de deux octets ...
ETHproductions
2

JavaScript, 82 octets

Collaboration avec @ETHproductions

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

L'entrée et la sortie se présentent sous la forme d'un tableau de caractères.

Extrait de test

Oliver
la source
2

05AB1E , 17 octets

vтLn95%žQykk33+ç?

L'algorithme est très similaire à la réponse de Jelly et Japt (il y avait autre chose auparavant mais cela ne m'a fait que 19 octets)

Explication

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

Essayez-le en ligne!

Datboi
la source
1

Mathematica, 60 octets

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

Fonction anonyme. Prend une chaîne en entrée et renvoie une chaîne en sortie. Erreurs sur une entrée invalide.

LegionMammal978
la source
1

Mathematica 82 octets

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

Utiliser la capacité de Solve à faire de l'arithmétique modulaire.

Kelly Lowder
la source