Bir dizenin karekökünü al


14

Motivasyon

Gelen bu meydan senin görevin bu doğal bir dize karekökünü almak için bir yol sunar, iki dizeyi çoğalmaya oldu.

O nasıl çalışır?

Bir dize (örneğin pub) yapmanız gereken ilk şey, her karakter için ASCII kodunu belirlemektir :

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

Daha sonra , her bir değeri [0..94]çıkararak bu kodları aralıkla eşlersiniz 32:

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

Şimdi her bir değer için kök modulo'unu bulmanız gerekir 95(örneğin 40*40 % 95 = 80, ayrıca seçebilirsiniz 55):

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

Ve son olarak, onu tekrar aralığa eşleyecek [32..126]ve bir dizeye geri dönüştüreceksiniz:

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

Nitekim "HC0" ⊗ "HC0" = "pub"diğer meydan gelen bir solüsyon ile doğrulayabilir olarak burada .


Modüler aritmetiğe aşina olanlar muhtemelen kare kök modulo'nun 95her zaman mevcut olmadığını fark etmişlerdir, örneğin kök yoktur 2. Böyle bir durumda, bir dizenin karekökü tanımlanmamıştır ve programınız / fonksiyonunuz çökebilir, süresiz döngü yapabilir.

Size kolaylık sağlamak için, karekökü olan karakterlerin listesi (birincisi boşluktur):

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

kurallar

  • Bir dizeyi (veya karakter listesini) bağımsız değişken olarak alan ve varsa herhangi bir karekökü döndüren bir program / işlev yazacaksınız.
  • Girdinin her zaman bir kare kökü olduğunu varsayabilirsiniz.
  • Giriş boş bir dizeden oluşabilir
  • Giriş yazdırılabilir aralıkta olacaktır ( [32..126])
  • Çıktı konsola yazdırılır veya kare kök varsa bir dize döndürürsünüz
  • Karekök yoksa, programınızın / fonksiyonunuzun davranışı tanımlanmamış olarak kalır
  • Kökleri konsola yazdırmayı seçerseniz satır sonları veya boşluklar iyi

Test senaryoları

Bunların mutlaka tek çözüm olmadığını unutmayın:

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

Bir kare kökü olmadan bu karakterlerde bir hata durumunu zorlamak gereksiz görünüyor, sadece tanımsız davranış tavsiye ederim.
ATaco

@ATaco Meydan okumayı güncelledim.
ბიმო

Verilen dize birden çok dizenin karesi ise ne yapmalı?
tsh

@tsh Herhangi birini iade edin, mücadeleyi güncelleyeceğim.
ბიმო

1
@curiousdannii Aslında bu aralık olmalı 0-94(yazdırılabilir aralık), bu bir yazım hatası - bunun için üzgünüm.
ბიმო

Yanıtlar:


10

sh + coreutils, 58 bayt

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

Çevrimiçi deneyin!

Modüler karekök tipik olarak benzersiz değildir; dışında her karakter için 2 veya 4 seçeneğimiz var . Biz çevirmek gerekmez , !, 4, lher biri kendince bir karekök zaten olduğundan. Kalan karakterler için, kabuk veya için kaçması gerekmeyen görüntüler seçiyoruz tr.


6

Python 3, 57 56 bayt

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

translate"Unicode ordinals ile Unicode ordinals" arasında bir eşleme kullanır. Böylece, gerek yok chr/ orddönüşümleri. Not: Kökün kökü olmadığında çökmez.

@ Jonathan-allan sayesinde 1 bayt kaydedildi

Eşlemenin değeri, anahtarın 0..94 aralığında en büyük köküdür. En küçük köke sahip olmak için (örneklerde olduğu gibi) şunu kullanın:

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

(61 bayt)

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

Hoşgeldiniz! Güzel ilk gönderi. 32Ve arasındaki boşluğu kaldırabilirsiniz for.
Jonathan Allan

... ayrıca burada bir çevrimiçi tercüman test takımına bir bağlantı var.
Jonathan Allan


3

Japt , 16 15 bayt

c@H+LDz%95+HÃbX

Çevrimiçi deneyin!

05AB1E yanıtına bakarak bir bayt kaydedildi ( Lyerine = 100 kullanılarak 95). Şimdi Japt en kısa, oldukça nadir bir olay :-D

açıklama

 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

Jöle , 18 17 16 bayt

95Ḷ²%95+32żØṖFyO

Çevrimiçi deneyin! (test paketi altbilgisi ile birlikte gelir)

Tam bir yeniden yazma işlemi yaparak 2 bayt kaydedildi. Ayrıca ilk kez kullanıyorum }.

açıklama

Kod önce tüm kare karakterleri hesaplar ve sonra bunları ilgili kare kökleriyle eşler.

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 cevabımın temelde yaptığı şey, çözümünüz iki bayt daha kısa olsa da ...
ETHproductions

2

JavaScript, 82 bayt

@ETHproductions ile işbirliği yaptı

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

Giriş ve çıkış karakter dizisi şeklindedir.

Test snippet'i


2

05AB1E , 17 bayt

vтLn95%žQykk33+ç?

Algoritma Jelly ve Japt cevabına çok benziyor (Daha önce başka bir şey vardı ama bu beni sadece 19 bayta getirdi)

açıklama

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

Çevrimiçi deneyin!


1

Mathematica, 60 bayt

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

Anonim işlev. Bir dizeyi girdi olarak alır ve bir dizeyi çıktı olarak döndürür. Geçersiz girişteki hatalar.



1

Mathematica 82 Bayt

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

Solve'un modüler aritmetik yapabilme yeteneğini kullanma.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.