取字符串的平方根


14

动机

挑战中,您的任务是将两个字符串相乘,这自然会引入一种取字符串平方根的方法。

它是如何工作的?

给定一个字符串(例如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

@ATaco我更新了挑战。
ბიმო

如果给定的字符串是多个字符串的平方,该怎么办?
tsh

@tsh返回任何内容,我将更新挑战。
ბიმო

1
@curiousdannii实际上应该是范围0-94(这是可打印的范围),这是一个错字-对此感到抱歉。
ბიმო

Answers:


10

sh + coreutils,58个字节

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

在线尝试!

模平方根通常不是唯一的。除了,我们每个字符有2或4个选择。我们不需要翻译!4l因为每个已经是其自身的平方根。对于其余字符,我们选择不需要为shell或进行转义的图像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!']

欢迎!不错的第一篇文章。您可以删除之间的空间32for
乔纳森·艾伦

...此外,是指向在线口译员测试套件的链接。
乔纳森·艾伦


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

Mathematica,94个字节

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


在线尝试!


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Ọ基本上是我的Japt回答所做的,尽管您的解决方案要短两个字节……
ETHproductions '17

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]&

匿名函数。将字符串作为输入并返回字符串作为输出。输入无效时出错。



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.