Pergeseran Caesars Pergeseran


13

Deskripsi

Caesar Shift adalah cipher monoalphabetic yang sangat sederhana di mana setiap huruf diganti dengan yang setelah itu dalam alfabet. Contoh:

Hello world! -> IFMMP XPSME!

( IBSLR, EGUFV!adalah output untuk tantangan yang sebenarnya, ini adalah contoh dari pergeseran oleh 1.)

Seperti yang Anda lihat, spasi dan tanda baca tetap tidak terputus. Namun, untuk mencegah menebak pesan, semua huruf ditulis dengan huruf besar. Dengan menggeser kembali surat-surat itu, pesan itu diartikan, nyaman, tetapi juga sangat mudah diuraikan oleh orang lain yang seharusnya tidak tahu apa arti pesan itu.

Jadi, kami akan sedikit membantu Caesar dengan menggunakan bentuk sandi canggihnya: Caesar Shift yang Bergeser Sendiri !

Tantangan

Tugas Anda adalah menulis program atau fungsi, yang, diberi string untuk dienkripsi, mengeluarkan string terenkripsi yang sesuai dengan input. Caesar Shift canggih berfungsi seperti ini:

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

Spasi dan simbol khusus lainnya, seperti tanda baca dilewati dalam proses ini. Dijamin bahwa program Anda akan diberikan string yang hanya berisi karakter ASCII yang dapat dicetak. Output dari fungsi / program Anda hanya harus dalam huruf besar.

Ini adalah , jadi celah standar berlaku, dan semoga jawaban tersingkat dalam byte menang!


2
Bukan E -3?
Leaky Nun

3
Bagaimana jika perbedaan huruf mengeluarkan huruf dari alfabet? Seperti ZEN, misalnya. Zdigeser 1 adalah ... A? (sebagai catatan, jawaban 05AB1E berubah Zmenjadi A)
Tn. Xcoder

6
Mohon uji kasusnya. Juga, karakter mana yang dilompati dengan tepat? Dan apa artinya bagi mereka untuk dilewati? Apakah mereka dihapus sama sekali, atau haruskah mereka tetap di output?
Luis Mendo

1
@ Giuseppe melihat jawaban yang dipilih untuk kasus uji, mereka telah divalidasi oleh OP sebagai benar, saya berasumsi, atau mereka akan memiliki downvotes.
Magic Gurita Guci

2
Apakah Anda bermaksud untuk kata-kata seperti RELIEFdan RELIESuntuk menyandikan hasil yang sama SRSFAG?
Anders Kaseorg

Jawaban:


5

05AB1E , 28 27 24 byte

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

Cobalah online!

Penjelasan

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

Kami berdua mendapatkan IBSLR, EGUFV!untuk Hello, World!, apakah itu benar? Apakah OP hanya mengacaukan contoh itu?
Magic Gurita Guci

1
@MagicOctopusUrn: Contohnya di awal hanya menunjukkan apa itu pergeseran. Hanya bergeser 1 huruf sehingga cukup menyesatkan.
Emigna

4

Python 3 , 100 byte

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))

Cobalah online!

bmelacak kode ASCII huruf terakhir, atau awalnya nol; rumusnya c+c-(b or~-x)berarti huruf dengan kode ASCII cakan bergeser c-bjika btidak nol, dan c-(c-1) == +1jika bnol (untuk huruf pertama).

btidak akan pernah menjadi nol lagi, karena string dijamin terdiri dari karakter ASCII yang dapat dicetak .

Akhirnya, 64<c<91periksa apakah churuf ASCII huruf besar, dan (…-65)%26+65kembalikan semuanya ke dalam A-Zjangkauan.

ovs menyimpan satu byte. Terima kasih!





1

MATL , 27 byte

tXkt1Y2mXH)tlwdh+64-lY2w)H(

Cobalah online!

Saya pikir ini adalah yang terpendek yang bisa saya dapatkan, tetapi ada banyak varietas yang berbeda karena ada banyak penggunaan ulang 'variabel' (ada 3 t(duplikasi), dan 2 woperasi (swap), clipboard Hdigunakan, dan itupun masih ada duplikat 1Y2...). Sayangnya, saya tidak bisa menyimpan byte dengan Mclipboard otomatis .

Lebih dari setengah dari program ini didedikasikan untuk membuatnya menjadi huruf besar dan mengabaikan karakter non-alfabet - hanya sandi tidak lebih dari 13 byte ( Coba online! )


1

Perl, 90 89

Meskipun bahasa non-codegolf jarang kompetitif, kita dapat mencapai di bawah 100;)

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

Saya telah memutuskan untuk ungolf ini:

@a = split//,<>; Mengambil input dari STDIN, menyimpan daftar karakter (dengan baris baru!) Di @a.

say uc(++$a[0])Output huruf besar digeser dengan 1. Ternyata Anda bisa menambah huruf dalam perl jika Anda menggunakan awalan ++. Ini adalah mutator ofc.

2*ord($a[$_+1])-ord($a[$_])+!$_Kita diminta untuk mengambil karakter pada x, dan menambahkan perbedaan + (x- (x-1)). Ya itu 2x - (x-1). Namun: Saya mengubah huruf pertama! Jadi saya harus memperbaiki kesalahan itu, karenanya +!$_, yang akan mengoreksi karena telah mengurangi satu terlalu banyak pada posisi 0 (hanya case! $ _ Tidak undef). Kami kemudian uc chrmendapatkan huruf besar dari nilai ASCII yang dihitung.

map{ ... } $#a-2- $#aadalah posisi untuk mengakses elemen array terakhir. Karena saya menambahkan yang saya inginkan $#a-1, tetapi karena baris baru dari input perlu diabaikan, ini $#a-2.

Ini digabungkan dengan huruf pertama, dan kita selesai :)


Ini tampaknya memiliki beberapa masalah berurusan dengan offset yang membungkus alfabet dan dengan karakter non-alfabet. Cobalah online!
Xcali

1

Perl 5 -F , 73 77 74 byte

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

Cobalah online!


Ini tidak sepenuhnya melompati bukan huruf; itu hanya tidak mengubahnya. Saya pikir Hello, World!harus menghasilkan IBSLR, EGUFV!, bukan IBSLR, XGUFV!.
Titus

Kamu benar. Memperbaikinya dengan 4 byte lebih untuk mempertahankan surat sebelumnya.
Xcali

1

PHP, 106 98 byte

cukup jahat satu itu ... jika tidak base_convertselama itu (atau ctype_alpha) ...
tapi saya mendapatkannya di bawah 100. puas.

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

Jalankan sebagai pipa dengan -nRatau coba online .


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.