文字列の平方根を取る


14

動機

、この挑戦あなたのタスクは、2つの文字列を乗算した、これは当然の文字列の平方根を取るための方法を紹介します。

どのように機能しますか?

文字列(たとえばpub)を指定すると、最初に行う必要があるのは、各文字のASCIIコードを決定することです。

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

次に、各値を[0..94]減算してこれらのコードを範囲にマッピングし32ます。

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

ここで、各値のルートモジュロを見つける必要があります95(たとえば40*40 % 95 = 80、を選択することもできます55)。

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

そして最後に、範囲にマッピング[32..126]し直して、文字列に変換します。

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

確かに"HC0" ⊗ "HC0" = "pub"ここで他の課題からのソリューションで検証できるように。


モジュラー演算に精通している人は、おそらく平方根モジュロ95が常に存在するとは限らないことに気付いたでしょう2。たとえば、にはルートがありません。そのような場合、文字列の平方根が定義されておらず、プログラム/関数がクラッシュしたり、無限にループしたりする可能性があります。

便宜上、平方根を持つ文字のリストを示します(最初の文字はスペースです):

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

ルール

  • あなたは、引数として文字列(または文字のリスト)を受け取り、返すプログラム/機能書きます任意のそれが存在する場合は平方根を
  • 入力には常に平方根があると仮定できます
  • 入力は空の文字列で構成できます
  • 入力は印刷可能な範囲([32..126])になります
  • 出力はコンソールに出力されるか、平方根が存在する場合は文字列を返します
  • 平方根が存在しない場合、プログラム/関数の動作は未定義のままになります
  • ルートをコンソールに印刷することを選択した場合、末尾の改行または空白は問題ありません

テストケース

これらは必ずしも唯一のソリューションではないことに注意してください。

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

平方根のないこれらの文字にエラー状態を強制する必要はないようです。未定義の動作をお勧めします。
アタコ

@ATacoチャレンジを更新しました。
ბიმო

指定された文字列が複数の文字列の正方形である場合はどうしますか?
tsh

@tsh anyを返すと、チャレンジを更新します。
ბიმო

1
@curiousdannii実際には範囲0-94(印刷可能な範囲)である必要がありますが、これはタイプミスです-ごめんなさい。
ბიმო

回答:


10

sh + coreutils、58バイト

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

オンラインでお試しください!

通常、モジュラー平方根は一意ではありません。を除く各文字に対して2つまたは4つの選択肢があります。私たちは、翻訳する必要はありません!4lそれぞれがすでに自身の平方根であるから。残りの文字については、シェルまたはのためにエスケープする必要のない画像を選択しますtr


6

Pythonの3、57の 56バイト

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

translate「Unicode序数からUnicode序数へ」からのマッピングを使用します。したがって、chr/ ord変換は必要ありません。注:charにルートがない場合、クラッシュしません。

@ jonathan-allanのおかげで1バイト節約

マッピングの値は、キーの範囲0..94の最大ルートです。(例のように)ルートを最小にするには、次を使用します。

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

(61バイト)

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

ようこそ!素敵な最初の投稿。32との間のスペースを削除できforます。
ジョナサンアラン

...また、ここではオンライン通訳のテストスイートへのリンクです。
ジョナサンアラン


3

Japt16 15バイト

c@H+LDz%95+HÃbX

オンラインでお試しください!

05AB1Eの回答を見て、バイトを保存しました(のL代わりに= 100 を使用95)。現在、Japtは最も短く、非常にまれな発生です:-D

説明

 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

ゼリー18 17 16バイト

95Ḷ²%95+32żØṖFyO

オンラインでお試しください!(テストスイートのフッター付き)

完全な書き換えを行って2バイトを節約しました。また、初めて使用することがわかったとき}

説明

コードは最初にすべての平方文字を計算し、次にそれらをそれぞれの平方根にマッピングします。

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Ọあなたのソリューションは、2バイト短いですが、私のJAPTの答えは...、何を基本的にある
ETHproductions

2

JavaScript、82バイト

@ETHproductionsとのコラボレーション

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

入力と出力は、char配列の形式です。

テストスニペット


2

05AB1E、17バイト

vтLn95%žQykk33+ç?

アルゴリズムはJellyとJaptの回答に非常に似ています(以前に何か他のものがありましたが、それで19バイトになりました)

説明

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

オンラインでお試しください!


1

Mathematica、60バイト

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

無名関数。入力として文字列を受け取り、出力として文字列を返します。無効な入力のエラー。



1

Mathematica 82バイト

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

モジュール演算を実行するSolveの機能を使用します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.