Возьмите квадратный корень строки

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(это диапазон для печати), это опечатка - извините за это.
მოიმო

Ответы:

10

sh + coreutils, 58 байт

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

Попробуйте онлайн!

Модульный квадратный корень обычно не уникален; у нас есть 2 или 4 варианта для каждого персонажа, кроме . Нам не нужно переводить , !, 4, lтак как каждый из них уже квадратный корень из себя. Для оставшихся символов мы выбираем изображения, которые не нужно экранировать для оболочки или 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преобразования. Примечание: он не падает, когда у символа нет рута.

Сохранено 1 байт благодаря @ jonathan-allan

Значение сопоставления является наибольшим корнем в диапазоне 0,94 ключа. Чтобы иметь наименьший root (как в примерах), используйте:

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!']
jferard
источник
Добро пожаловать! Хороший первый пост. Вы можете удалить пространство между 32и for.
Джонатан Аллан
... также здесь есть ссылка на набор тестов для переводчиков онлайн.
Джонатан Аллан
3

Japt , 16 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
ETHproductions
источник
2

Желе , 18 17 16 байт

95Ḷ²%95+32żØṖFyO

Попробуйте онлайн! (поставляется с нижним колонтитулом test-suite)

Сохранено 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.
PurkkaKoodari
источник
95Ḷ²%95+32iЀO+31Ọэто в основном то, что делает мой ответ Япта, хотя ваше решение на два байта короче ...
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))

Ввод и вывод в виде массива символов.

Тестовый фрагмент

Оливер
источник
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

Попробуйте онлайн!

Datboi
источник
1

Mathematica, 60 байт

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

Анонимная функция. Принимает строку в качестве ввода и возвращает строку в качестве вывода. Ошибки при неверном вводе.

LegionMammal978
источник
1

Mathematica 82 байта

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

Используя способность Solve выполнять модульную арифметику.

Келли Лоудер
источник