Nehmen Sie die Quadratwurzel einer Zeichenfolge


14

Motivation

Bei dieser Herausforderung bestand Ihre Aufgabe darin, zwei Zeichenfolgen zu multiplizieren. Auf diese Weise können Sie natürlich die Quadratwurzel einer Zeichenfolge ziehen.

Wie funktioniert es?

Wenn Sie beispielsweise eine Zeichenfolge pubangeben, müssen Sie zunächst den ASCII-Code für jedes Zeichen ermitteln:

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

Als nächstes ordnen Sie diese Codes dem Bereich zu, [0..94]indem Sie 32jeden Wert subtrahieren :

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

Jetzt müssen Sie für jeden Wert sein Wurzelmodul finden 95(z. B. 40*40 % 95 = 80könnten Sie auch auswählen 55):

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

Und schließlich ordnen Sie es wieder dem Bereich zu [32..126]und wandeln es wieder in eine Zeichenfolge um:

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

In der Tat, "HC0" ⊗ "HC0" = "pub"wie Sie mit einer Lösung aus der anderen Herausforderung hier überprüfen können .


Diejenigen, die mit modularer Arithmetik vertraut sind, haben wahrscheinlich bemerkt, dass das Quadratwurzel-Modulo 95nicht immer existiert, zum Beispiel gibt es keine Wurzel für 2. In einem solchen Fall ist die Quadratwurzel eines Strings nicht definiert und Ihr Programm / Ihre Funktion kann abstürzen, eine Endlosschleife ausführen usw.

Im Folgenden finden Sie eine Liste der Zeichen mit einer Quadratwurzel (die erste ist ein Leerzeichen):

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

Regeln

  • Sie schreiben ein Programm / eine Funktion, die eine Zeichenfolge (oder eine Liste von Zeichen) als Argument verwendet und eine Quadratwurzel zurückgibt, falls sie existiert
  • Sie können davon ausgehen, dass die Eingabe immer eine Quadratwurzel hat
  • Die Eingabe kann aus einer leeren Zeichenfolge bestehen
  • Die Eingabe liegt im druckbaren Bereich ( [32..126])
  • Die Ausgabe wird entweder an die Konsole ausgegeben oder Sie geben eine Zeichenfolge zurück, wenn die Quadratwurzel vorhanden ist
  • Falls die Quadratwurzel nicht existiert, bleibt das Verhalten Ihres Programms / Ihrer Funktion undefiniert
  • Wenn Sie sich dafür entscheiden, den Stamm auf der Konsole zu drucken, sind nachgestellte Zeilenumbrüche oder Leerzeichen in Ordnung

Testfälle

Beachten Sie, dass dies nicht unbedingt die einzigen Lösungen sind:

''              -> ''
'pub'           -> 'HC0'
'pull!'         -> 'HC33!'
'M>>M'          -> '>MM>'
'49'            -> '4%'
'64'            -> undefined
'Hello, World!' -> undefined

Das Erzwingen eines Fehlerzustands für diese Zeichen ohne Quadratwurzel scheint unnötig zu sein. Ich würde nur undefiniertes Verhalten empfehlen.
ATaco

@ATaco Ich habe die Herausforderung aktualisiert.
26.

Was tun, wenn die angegebene Zeichenfolge ein Quadrat aus mehreren Zeichenfolgen ist?
TSH

@tsh Gib alle zurück, ich aktualisiere die Herausforderung.
26.

1
@curiousdannii Eigentlich sollte es der Bereich sein 0-94(das ist der druckbare Bereich), das ist ein Tippfehler - tut mir leid.
26.

Antworten:


10

sh + coreutils, 58 Bytes

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

Probieren Sie es online!

Die modulare Quadratwurzel ist normalerweise nicht eindeutig. Wir haben 2 oder 4 Auswahlmöglichkeiten für jeden Charakter außer . Wir brauchen nicht zu übersetzen , !, 4, lda jeder bereits eine Quadratwurzel von selbst. Für die restlichen Zeichen wählen wir Bilder aus, die für die Shell oder nicht maskiert werden müssen tr.


6

Python 3, 57 56 Bytes

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

translateverwendet eine Zuordnung von "Unicode-Ordnungszahlen zu Unicode-Ordnungszahlen". Wir brauchen also keine chr/ ordUmbauten. Hinweis: Es stürzt nicht ab, wenn das Zeichen keine Wurzel hat.

1 Byte dank @ jonathan-allan gespeichert

Der Wert der Zuordnung ist die größte Wurzel im Bereich 0..94 des Schlüssels. Um die geringste Wurzel zu haben (wie in den Beispielen), verwenden Sie:

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

(61 Bytes)

>>> [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!']

Herzlich willkommen! Schöner erster Beitrag. Sie können das Leerzeichen zwischen 32und entfernen for.
Jonathan Allan

... hier ist auch ein Link zu einer Online-Dolmetscher-Testsuite.
Jonathan Allan


3

Japt , 16 15 Bytes

c@H+LDz%95+HÃbX

Probieren Sie es online!

Durch Betrachten der 05AB1E-Antwort wurde ein Byte gespeichert (mit L= 100 anstelle von 95). Jetzt ist Japt das kürzeste, ein recht seltenes Ereignis :-D

Erläuterung

 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


2

Jelly , 18 17 16 Bytes

95Ḷ²%95+32żØṖFyO

Probieren Sie es online! (kommt mit Fußzeile der Testsuite)

2 Bytes durch vollständiges Umschreiben gespart. Auch das erste Mal habe ich Verwendung für gefunden }.

Erläuterung

Der Code berechnet zuerst alle quadratischen Zeichen und ordnet sie dann ihren jeweiligen Quadratwurzeln zu.

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.

95Ḷ²%95+32iЀO+31Ọist im Grunde das, was meine Japt-Antwort tut, obwohl Ihre Lösung zwei Bytes kürzer ist ...
ETHproductions

2

JavaScript, 82 Byte

Zusammenarbeit mit @ETHproductions

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

Ein- und Ausgabe erfolgen in Form eines char-Arrays.

Testschnipsel


2

05AB1E , 17 Bytes

vтLn95%žQykk33+ç?

Der Algorithmus ist der Antwort von Jelly und Japt sehr ähnlich (hatte vorher etwas anderes, aber das brachte mich nur auf 19 Bytes)

Erläuterung

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

Probieren Sie es online!


1

Mathematica, 60 Bytes

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

Anonyme Funktion. Nimmt einen String als Eingabe und gibt einen String als Ausgabe zurück. Fehler bei ungültiger Eingabe.



1

Mathematica 82 Bytes

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

Verwendung der Fähigkeit von Solve, modulare Arithmetik durchzuführen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.