Sezaryen Kaydırma


13

Açıklama

Bir Sezar Kayması, her harfin alfabedeki bir harfle değiştirildiği çok basit bir monoalfabetik şifredir. Misal:

Hello world! -> IFMMP XPSME!

( IBSLR, EGUFV!asıl zorluğun çıktısı budur. 1'e geçişin bir örneğiydi.)

Gördüğünüz gibi, boşluk ve noktalama işaretleri dikkate alınmaz. Ancak, mesajı tahmin etmeyi önlemek için tüm harfler büyük yazılır. Harfleri geri kaydırarak mesaj deşifre edildi, kullanışlı, ancak mesajın ne anlama geldiğini bilmemesi gereken diğer kişiler tarafından deşifre edilmesi gerçekten kolay oldu.

Yani, şifrelerinin gelişmiş bir biçimini kullanarak Sezar'a biraz yardım edeceğiz: Kendini değiştiren Sezar Kayması !

Meydan okuma

Göreviniz, şifreleyiciye bir dize verildiğinde, girdiye karşılık gelen şifreli dize çıktısı veren bir program veya işlev yazmaktır. Gelişmiş Sezar Kayması şöyle çalışır:

1. Compute letter differences of all adjacent letters: 
    1.1. Letter difference is computed like this:

         Position of 2nd letter in the alphabet
        -Position of 1st letter in the alphabet
        =======================================
                              Letter difference

    1.2. Example input: Hello
         H - e|e -  l|l  -  l|l  -  o
         7 - 5|5 - 12|12 - 12|12 - 15 Letter differences: 3; -7; 0; -3
            =3|   =-7|     =0|    =-3

2. Assign the letters continously a letter difference from the list,
   starting at the second letter and inverting the differences:
    2.1. 2nd letter: first difference, 3rd letter: second difference, etc.

    2.2. The first letter is assigned a 1.

    2.3. Example input: Hello with differences 3; -7; 0; -3

         Letter || Value
         =======||======
            H   ||   1
            E   ||  -3
            L   ||   7
            L   ||   0
            O   ||   3

3. Shift the letters by the value x they have been assigned:
    3.1. In case of a positive x, the letter is shifted x letters to the right.
    3.2. In case of a negative x, the letter is shifted |x| letters to the left.
    3.3. In case of x = 0, the letter is not shifted.

    3.4. If the shift would surpass the limits of the alphabet, it gets wrapped around
         Example: Y + Shift of 2 --> A

    3.5. Example input: See the table under 2.3.

                ||       || Shifted
         Letter || Value || Letter
         =======||=======||=========
            H   ||   1   ||    I
            E   ||  -3   ||    B     Program output:
            L   ||   7   ||    S     IBSLR
            L   ||   0   ||    L
            O   ||   3   ||    R

Bu işlemde boşluklar ve noktalama işaretleri gibi diğer özel simgeler atlanır. Programınıza yalnızca yazdırılabilir ASCII karakterleri içeren bir dize verileceği garanti edilir. İşlevinizin / programınızın çıktısı yalnızca büyük harf olmalıdır.

Bu , bu yüzden standart boşluklar geçerlidir ve bayttaki en kısa cevap kazanabilir!


2
Değil E -3mi?
Leaky Nun

3
Harf farkı, harfi alfabeden çıkarırsa ne olur? Gibi ZEN, mesela. Z1 ile kaydırılır ... A? (Bir yan not olarak, 05AB1E cevap dönüşler Ziçine A)
Sayın Xcoder

6
Test senaryoları lütfen. Ayrıca, hangi karakterler tam olarak atlanır? Ve bunların atlanması ne anlama geliyor? Tamamen çıkarıldılar mı, yoksa çıktıda mı kalmalılar?
Luis Mendo

1
@Giuseppe test senaryoları için yükseltilmiş cevapları görüyorlar, OP tarafından doğru olarak onaylandılar, sanırım ya da aşağı oyları olacaktı.
Sihirli Ahtapot Urn

2
Eğer gibi kelimeleri kastettiniz RELIEFve RELIESaynı sonuca hem encipher için SRSFAG?
Anders Kaseorg

Yanıtlar:


5

05AB1E , 28 27 24 bayt

láÇ¥R`XIlvyaiAyk+Aèëy}u?

Çevrimiçi deneyin!

açıklama

l                          # convert input to lower case
 á                         # keep only letters
  ǥ                       # compute deltas of character codes
    R`                     # reverse and push separated to stack
      X                    # push 1
       Ilv                 # for each char y in lower case input
          yai              # if y is a letter
             Ayk           # get the index of y in the alphabet
                +          # add the next delta
                 Aè        # index into the alphabet with this
            ëy             # else push y
              }            # end if
            u?             # print as upper case

İkimiz de bu işe IBSLR, EGUFV!yarıyor Hello, World!, doğru mu? OP sadece bu örneği bozdu mu?
Sihirli Ahtapot Urn

1
@MagicOctopusUrn: Başlangıçtaki örneği sadece bir değişimin ne olduğunu gösteriyor. Sadece 1 harf kaydırır, bu yüzden oldukça yanıltıcıdır.
Emigna

4

Python 3 , 100 bayt

b=0
for c in map(ord,input().upper()):
 if 64<c<91:b,c=c,(c+c-(b or~-c)-65)%26+65
 print(end=chr(c))

Çevrimiçi deneyin!

bson harfin ASCII kodunu izler veya başlangıçta sıfırdır; Formül c+c-(b or~-x)ASCII kod içeren bir mektup anlamına ckaydırılır alır c-bise bsıfır olmayan ve c-(c-1) == +1eğer b(ilk harf için) sıfırdır.

bdizenin yazdırılabilir ASCII karakterlerinden oluşması garanti edildiği için bir daha asla sıfır olmaz .

Son olarak, büyük harfli bir ASCII harfi 64<c<91olup olmadığını kontrol eder cve (…-65)%26+65her şeyi tekrar A-Zaralığa sarar .

ovs bir bayt kaydetti. Teşekkürler!





1

MATL , 27 bayt

tXkt1Y2mXH)tlwdh+64-lY2w)H(

Çevrimiçi deneyin!

Sanırım bu alabileceğim en kısa şey, ama 'değişkenlerin' çok fazla yeniden kullanımı olduğundan (3 t(çoğaltma) ve 2 w(takas) işlemleri, pano Hkullanılıyor ve o zaman bile hala bir kopya var 1Y2...). Ne yazık ki, otomatik Mpano ile bayt kaydedemedim .

Programın yarısından fazlası onu büyük harf yapmaya ve alfabetik olmayan karakterleri görmezden gelmeye adamıştır - sadece şifre 13 bayttan fazla değildir ( Çevrimiçi deneyin! )


1

Perl, 90 89

Codegolf olmayan diller nadiren rekabetçi olsa da, 100'ün altına gidebiliriz;)

@a=split//,<>;say uc(++$a[0]).join'',map{uc chr(2*ord($a[$_+1])-ord($a[$_])+!$_)}0..$#a-1

Bunu çözmeye karar verdim:

@a = split//,<>; STDIN'den girdi alır, karakter listesini (newline ile!) @A'da saklar.

say uc(++$a[0])çıktı büyük harf ilk harf 1 kaydırılır. Bir önek ++ kullanırsanız perl'de bir harf artırabilirsiniz. Bu bir mutatördür.

2*ord($a[$_+1])-ord($a[$_])+!$_Bizden x karakterini almamız ve + (x- (x-1)) farkını eklememiz istenir. Bu 2x - (x-1). Ancak ilk harfi değiştirdim! Bu yüzden bu hatayı düzeltmem gerekiyor, bu nedenle +!$_, 0 konumunda çok fazla çıkardığınız için düzeltilecek (sadece durum! $ _ Undef değil). Sonra uc chrhesaplanan ASCII değerinden büyük harf alırız.

map{ ... } $#a-2- $#ason dizi öğesine erişim konumudur. İstediğim bir tane eklediğim için $#a-1, ancak girişteki yeni satırın göz ardı edilmesi gerektiğinden, bu $#a-2.

Bu ilk harfle birleştirildi ve işimiz bitti :)


Bu, alfabenin etrafına dolanan ofsetlerle ve alfabetik olmayan karakterlerle ilgili bazı problemlere sahip gibi görünüyor. Çevrimiçi deneyin!
Xcali

1

Perl 5 -F , 73 77 74 bayt

/\w/&&($_=chr 65+(2*($n=ord uc)-65-($!||-1+ord uc))%26)&($!=$n)for@F;say@F

Çevrimiçi deneyin!


Bu, harf olmayanları tamamen atlamaz; sadece onları dönüştürmez. Bence Hello, World!sonuç vermeli IBSLR, EGUFV!, değil IBSLR, XGUFV!.
Titus

Haklısın. Önceki harfi korumak için 4 bayt daha düzeltildi.
Xcali

1

PHP, 106 98 bayt

oldukça kötü biri ... eğer base_converto kadar uzun olmasaydı (ya da ctype_alpha... ...
ama 100'ün altına aldım. memnunum.

for(;$a=ord($c=$argn[$i++]);print ctype_alpha($c)?chr(65+($p?(25-$p+2*$p=$a)%26:$p=$a)):$c)$a&=31;

Pipo ile çalıştırın -nRveya çevrimiçi deneyin .


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.