Ambil akar kuadrat dari sebuah string

14

Motivasi

Dalam tantangan ini, tugas Anda adalah mengalikan dua string, ini secara alami memperkenalkan cara untuk mengambil akar kuadrat dari string.

Bagaimana cara kerjanya?

Diberikan string (misalnya pub) hal pertama yang perlu Anda lakukan, adalah menentukan kode ASCII untuk setiap karakter:

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

Selanjutnya Anda memetakan kode-kode ini ke kisaran [0..94]dengan mengurangi 32setiap nilai:

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

Sekarang Anda perlu menemukan untuk setiap nilai modulo root-nya 95(mis. 40*40 % 95 = 80, Anda juga bisa memilih 55):

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

Dan akhirnya Anda akan memetakannya kembali ke rentang [32..126]dan mengubahnya kembali menjadi string:

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

Memang "HC0" ⊗ "HC0" = "pub"Anda bisa memverifikasi dengan solusi dari tantangan lain di sini .


Yang akrab dengan aritmatika modular mungkin memperhatikan bahwa modulo root kuadrat 95tidak selalu ada, misalnya tidak ada root untuk 2. Dalam kasus seperti itu, akar kuadrat dari suatu string tidak didefinisikan dan program / fungsi Anda mungkin crash, loop tanpa batas dll.

Untuk kenyamanan Anda, inilah daftar karakter yang memiliki akar kuadrat (yang pertama adalah spasi):

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

Aturan

  • Anda akan menulis sebuah program / fungsi yang mengambil string (atau daftar karakter) sebagai argumen dan mengembalikan setiap akar kuadrat jika ada
  • Anda dapat berasumsi bahwa input selalu memiliki akar kuadrat
  • Input dapat terdiri dari string kosong
  • Input akan berada dalam kisaran yang dapat dicetak ( [32..126])
  • Outputnya dicetak ke konsol atau Anda mengembalikan string jika akar kuadrat ada
  • Jika akar kuadrat tidak ada, perilaku program / fungsi Anda dibiarkan tidak terdefinisi
  • Jika Anda memilih untuk mencetak root ke konsol, baris baru atau spasi putih tidak apa-apa

Uji kasus

Perhatikan bahwa ini bukan satu-satunya solusi:

''              -> ''
'pub'           -> 'HC0'
'pull!'         -> 'HC33!'
'M>>M'          -> '>MM>'
'49'            -> '4%'
'64'            -> undefined
'Hello, World!' -> undefined
ბიმო
sumber
Memaksa status kesalahan pada karakter ini tanpa akar kuadrat tampaknya tidak perlu, saya akan merekomendasikan perilaku yang tidak terdefinisi.
ATaco
@ATaco Saya memperbarui tantangan.
ბიმო
Apa yang harus dilakukan jika string yang diberikan adalah kuadrat dari beberapa string?
tsh
@tsh Kembali, saya akan memperbarui tantangan.
ბიმო
1
@curiousdannii Sebenarnya itu harus kisaran 0-94(itu kisaran yang dapat dicetak), itu salah ketik - maaf tentang itu.
ბიმო

Jawaban:

10

sh + coreutils, 58 byte

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

Cobalah online!

Akar kuadrat modular biasanya tidak unik; kami memiliki 2 atau 4 pilihan untuk setiap karakter kecuali . Kita tidak perlu untuk menerjemahkan , !, 4, lkarena masing-masing sudah merupakan akar kuadrat dari dirinya sendiri. Untuk karakter yang tersisa, kami memilih gambar yang tidak perlu melarikan diri untuk shell atau tr.

Anders Kaseorg
sumber
6

Python 3, 57 56 byte

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

translatemenggunakan pemetaan dari "ordinal Unicode ke ordinal Unicode". Jadi, kita tidak perlu chr/ ordkonversi. Catatan: tidak mogok saat char tidak memiliki root.

Disimpan 1 byte berkat @ jonathan-allan

Nilai pemetaan adalah root terbesar di kisaran 0..94 dari kunci. Untuk mendapatkan root paling sedikit (seperti pada contoh), gunakan:

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

(61 byte)

>>> [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
sumber
Selamat datang! Posting pertama yang bagus. Anda dapat menghapus ruang antara 32dan for.
Jonathan Allan
... juga, berikut ini tautan ke rangkaian uji juru bahasa online.
Jonathan Allan
3

Python 2 , 80 byte

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

Cobalah online!

Melempar IndexError jika tidak ada root.

Chas Brown
sumber
3

Japt , 16 15 byte

c@H+LDz%95+HÃbX

Cobalah online!

Menyimpan byte dengan melihat jawaban 05AB1E (menggunakan L= 100 alih-alih 95). Sekarang Japt adalah yang terpendek, kejadian yang cukup langka :-D

Penjelasan

 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
Produksi ETH
sumber
2

Mathematica, 94 byte

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


Cobalah online!

J42161217
sumber
2

Jelly , 18 17 16 byte

95Ḷ²%95+32żØṖFyO

Cobalah online! (dilengkapi dengan footer test-suite)

Disimpan 2 byte dengan melakukan penulisan ulang lengkap. Juga pertama kali saya menemukan digunakan untuk }.

Penjelasan

Kode pertama menghitung semua karakter persegi, dan kemudian memetakannya ke akar kuadrat masing-masing.

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
sumber
95Ḷ²%95+32iЀO+31Ọpada dasarnya apa jawaban Japt saya lakukan, meskipun solusi Anda dua byte lebih pendek ...
ETHproduk
2

JavaScript, 82 byte

Berkolaborasi dengan @ETHproductions

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

Input dan output dalam bentuk array char.

Cuplikan tes

Oliver
sumber
2

05AB1E , 17 byte

vтLn95%žQykk33+ç?

Algoritma ini sangat mirip dengan jawaban Jelly dan Japt (Punya sesuatu yang lain sebelumnya tapi itu hanya membuat saya sampai 19 byte)

Penjelasan

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

Cobalah online!

Datboi
sumber
1

Mathematica, 60 byte

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

Fungsi anonim. Mengambil string sebagai input dan mengembalikan string sebagai output. Kesalahan pada input yang tidak valid.

LegionMammal978
sumber
1

Perl 6 , 53 byte

{[~] .comb.map({32+first *²%95==.ord-32,^95})».chr}

Cobalah online!

Sean
sumber
1

Mathematica 82 Bytes

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

Menggunakan kemampuan Solve untuk melakukan aritmatika modular.

Kelly Lowder
sumber