Caesar Shifting

22

Pergeseran Caesar mungkin adalah sesuatu yang kita semua kenal.

(Anda mungkin bahkan melakukannya sebagai tugas pekerjaan rumah. Jika demikian, tolong jangan menyalin jawaban ini, guru Anda hampir pasti tidak menginginkan yang seperti jawaban di sini.)

Kalau-kalau Anda tidak, pergeseran Caesar adalah bentuk sandi yang sangat sederhana. Dibutuhkan sebuah string untuk diacak dan integer. Kemudian untuk setiap karakter alfabet dalam string, lakukan transformasi berikut:

  1. Cari tahu posisi karakter dalam alfabet (berbasis 0).
  2. Tambahkan ke nomor itu bilangan bulat diterima di awal.
  3. Sementara jumlahnya lebih besar dari 25, kurangi 26 dari itu.
  4. Cari tahu posisi alfabet yang digunakan.

Biarkan sisa karakter tidak terangkat.

Huruf kapital harus dihormati karena apa bahasa Inggris tanpa huruf kapital?

Contoh:

abcdefghijklmnopqrstuvwxyz 1 -> bcdefghijklmnopqrstuvwxyza
Spam spam spam sausage and spam! 13 -> Fcnz fcnz fcnz fnhfntr naq fcnz!
abcdefghijklmnopqrstuvwxyz 52 -> abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz -1 -> zabcdefghijklmnopqrstuvwxy
ABCxyz 3 -> DEFabc

Asumsi

  • Anda dapat menerima karakter ASCII yang dapat dicetak
  • Nomor input bisa negatif dan akan selalu lebih besar dari -128 dan kurang dari 128 ( -128<x<128)
  • Anda harus dapat menyandikan huruf kapital dan huruf non-kapital secara terbalik.
  • Anda harus membuat program lengkap, bukan hanya fungsi atau cuplikan
  • Anda akan mendapatkan input dari STDIN atau alternatif terdekat
  • Anda dapat memilih format untuk input Anda, sebutkan ini dalam jawaban Anda
  • Karakter yang perlu digeser adalah codepoint ASCII 0x41 - 0x5Adan 0x61-0x7A- huruf besar dan kecil

    • Huruf besar harus tetap di atas
    • Huruf kecil harus lebih rendah
    • Karakter yang tidak berada dalam rentang ini harus dibiarkan apa adanya
  • Catatan untuk tantangan ini, Anda hanya perlu mengacak string, Anda tidak harus dapat menyelesaikannya secara otomatis (tetapi memberi -xakan membalikkan sandi)


Karena ini adalah katalog, bahasa yang dibuat setelah tantangan ini diizinkan untuk bersaing. Perhatikan bahwa harus ada juru bahasa sehingga pengajuan dapat diuji. Diperbolehkan (dan bahkan dianjurkan) untuk menulis sendiri penerjemah ini untuk bahasa yang sebelumnya tidak diterapkan. Selain itu, semua aturan standar harus dipatuhi. Kiriman dalam sebagian besar bahasa akan dinilai dalam byte dalam pengkodean yang sudah ada sebelumnya (biasanya UTF-8).

Katalog

Cuplikan Stack di bagian bawah posting ini menghasilkan katalog dari jawaban a) sebagai daftar solusi terpendek per bahasa dan b) sebagai leaderboard keseluruhan.

Untuk memastikan bahwa jawaban Anda muncul, silakan mulai jawaban Anda dengan tajuk utama, menggunakan templat Penurunan harga berikut:

## Language Name, N bytes

di mana Nukuran kiriman Anda. Jika Anda meningkatkan skor Anda, Anda dapat menyimpan skor lama di headline, dengan mencoretnya. Contohnya:

## Ruby, <s>104</s> <s>101</s> 96 bytes

Jika Anda ingin memasukkan beberapa angka dalam tajuk Anda (mis. Karena skor Anda adalah jumlah dari dua file atau Anda ingin membuat daftar hukuman penterjemah secara terpisah), pastikan bahwa skor sebenarnya adalah angka terakhir di tajuk:

## Perl, 43 + 2 (-p flag) = 45 bytes

Anda juga dapat membuat nama bahasa menjadi tautan yang kemudian akan muncul di cuplikan:

## [<><](https://esolangs.org/wiki/Fish), 121 bytes

Biru
sumber
8
"Kamu bahkan mungkin melakukannya sebagai pekerjaan rumah. Kalau begitu, tolong jangan menyalin jawaban ini, gurumu hampir pasti tidak menginginkan yang seperti jawaban di sini ." Saya ingin tahu apa yang akan terjadi jika Anda memberi guru kludge karakter dan jalan pintas 90 byte yang kacau ...
ASCIIThenANSI

Jawaban:

9

Pyth, 13 byte

uXGH.<HQrBG1z

Suite uji

Pada dasarnya, kita mulai dengan dua string yang kita ingin caesar shift, huruf kecil dan huruf besar. Daftar yang mengandung keduanya dihasilkan oleh rBG1, bifurcate pada huruf besar. Kemudian, kita mengurangi daftar ini, mulai dengan string input dan menerjemahkan huruf kecil pertama, lalu huruf besar dengan perubahan yang sesuai.

isaacg
sumber
Sangat bagus, saya selalu lupa ada bifurkasi ...: P
FryAmTheEggman
7

Pyth, 16

XXzG.<GQJrG1.<JQ

Cobalah secara online atau jalankan Test Suite

FryAmTheEggman
sumber
1
+1 untuk input Star Wars, meskipun saya benci esolang.
Codefun64
5

Paket Bash + bsd-games, 21

caesar $[($1+130)%26]

Dibangun di FTW! Hampir terasa seperti Mathematica. Jawaban Pyth masih lebih pendek.

Input string dibaca dari STDIN dan integer dari command-line. misalnya:

$ ./caesar.sh 13 <<< "Spam spam spam sausage and spam!"
Fcnz fcnz fcnz fnhfntr naq fcnz!
$

Atau jika Anda tidak suka builtin:

Bash + coreutils, 63

printf -va %s {a..z}
t=${a:$1%26}${a:0:$1%26}
tr A-Z$a ${t^^}$t
Trauma Digital
sumber
Sepertinya saya bahwa versi coreutils tidak berfungsi dengan -127 dan / atau 127?
Neil
@Neil Ya. Tangkapan yang bagus. Tetap.
Digital Trauma
5

JavaScript (ES6), 122 118 114 111 byte

alert((p=prompt)().replace(/[a-z]/gi,c=>String.fromCharCode((x=c.charCodeAt(),a=x&96,x-a+n+129)%26-~a),n=+p()))

Disimpan 4 byte berkat @Neil !

Penjelasan

Prompt pertama mengambil string input. Yang kedua adalah nomor untuk menggeser setiap huruf.

alert(
  (p=prompt)()              // get input string
    .replace(/[a-z]/gi,c=>  // for each letter
      String.fromCharCode((
        x=c.charCodeAt(),   // x = code of character
        a=x&96,             // a = index of letter a (-1) in same capitalisation
        x-a+n+129)%26-~a    // add N to the letter code and wrap at 26
      ),                    // (+129 is needed to make the % work with negative numbers)
      n=+p()                // get number to shift by
    )
)
pengguna81655
sumber
1
Sangat bagus! Tetapi tidak bekerja pada semua input; coba "abcdefg", -26. Ini dapat diperbaiki dengan mengubah rumus ke (x-a+n+130)%26.
ETHproduksi
@ ETHproduk Terima kasih telah menangkap itu!
user81655
"Anda harus membuat program lengkap, bukan hanya fungsi atau cuplikan"
LegionMammal978
@ LegionMammal978 Terima kasih, saya tidak menyadarinya.
user81655
Apakah a=x&96,(x-a+n+129)%26+a+1membantu?
Neil
3

CJam, 34 22 21 20 byte

Terima kasih kepada FryAmTheEggman karena telah menghemat 1 byte.

l'[,_el^_26/l~fm<ser

Uji di sini.

Input adalah string yang akan bergeser pada baris pertama dan pergeseran pada baris kedua.

Penjelasan

l    e# Read the first line of input.
'[,  e# Push a string with all ASCII characters up to and including Z.
_el  e# Duplicate and convert to lower case. This only affects the letters.
^    e# Symmetric set-difference: except for the letters, each character appears in both
     e# sets and will be omitted from the difference, but all the letters will be included.
     e# This gives us "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
_26/ e# Duplicate and split into chunks of 26 characters, separating lower and upper case.
l~   e# Read the second line of input and evaluate.
fm<  e# Shift each of the two substrings by that many characters to the left.
s    e# Convert to a single string, joining both substrings back together.
     e# On the stack are now the input, the letters in alphabetical order and the letters
     e# in shifted order.
er   e# Character transliteration: replace each occurrence of a letter with the character
     e# at the corresponding position in the shifted string.
Martin Ender
sumber
@FryAmTheEggman The '[,_el^adalah tip dari Dennis. Saya tidak tahu apa yang Anda maksudkan f, sepertinya penggunaannya cukup normal?
Martin Ender
Saya kira saya belum cukup membaca jawaban CJam: P Sepertinya sangat rapi untuk menggunakannya sebagai peta tetapi mengubah urutan argumen.
FryAmTheEggman
@FryAmTheEggman sebenarnya, saya tidak perlu @sama sekali. :)
Martin Ender
2

Java, 249 Bytes

Ini sesingkat yang saya bisa dapatkan. Membaca dari stdin memakan satu ton byte. Sebuah solusi yang menggunakan baris perintah args terasa lebih pendek tetapi, tugas ini menentukan stdin untuk input.

Format input adalah String pertama diikuti oleh nomor shift pada baris baru.

interface C{static void main(String[]a){java.util.Scanner r=new java.util.Scanner(System.in);String s=r.nextLine();int i=(r.nextInt()+26)%26;s.chars().forEach(c->System.out.print((char)(c>64&c<91|c>96&c<123?c<91?65+(c+i-65)%26:97+(c+i-97)%26:c)));}}

Menggunakan Argumen baris perintah, solusi ini hanya 188 byte. Input adalah String sebagai argumen pertama dan pergeseran sebagai argumen kedua.

interface C{static void main(String[]a){int i=(Integer.parseInt(a[1])+26)%26;a[0].chars().forEach(c->System.out.print((char)(c>64&c<91|c>96&c<123?c<91?65+(c+i-65)%26:97+(c+i-97)%26:c)));}}
ankh-morpork
sumber
1

R, 111 byte

kode

n=scan();s=scan(,"");for(l in as.numeric(sapply(s,charToRaw))){v=97;if(l<97)v=65;cat(intToUtf8((l+n-v)%%26+v))}

ungolfed

n <- scan()                           # input integer
s <- scan(,"")                        # input string letter by letter
z <- as.numeric(sapply(s,charToRaw))  # get ASCII index of character
for (l in z){                         # loop through chars
  v=97                                # base index of not capitalized chars
  if(l<97)v=65                        # base index of capitalized chars
  cat(intToUtf8((l+n-v)%%26+v))       # paste the char of the shifted index
}

Program ini mengambil input pengguna dari STDIN, pertama integer shifter dan kemudian string, karakter demi karakter.

Mutador
sumber
1

Perl, 81 byte

(+1 untuk -pbendera)

s/[^ ]+ //;$n=$&%26;eval"y/a-zA-Z/".($x=chr(97+$n)."-za-".chr$n+96).uc$x."/"if$n

Masih bekerja untuk bermain golf ...

Uji:

llama@llama:...code/perl/ppcg67044caesar$ printf '1 abcdefghijklmnopqrstuvwxyz\n13 Spam spam spam sausage and spam!\n52 abcdefghijklmnopqrstuvwxyz\n-1 abcdefghijklmnopqrstuvwxyz\n3 ABCxyz' | perl -p caesar.pl; echo
bcdefghijklmnopqrstuvwxyza
Fcnz fcnz fcnz fnhfntr naq fcnz!
abcdefghijklmnopqrstuvwxyz
zabcdefghijklmnopqrstuvwxy
DEFabc
Gagang pintu
sumber
1

Python 2, 163 160 byte

Tidak yakin apakah saya masih bisa bermain golf ..

import sys;k=sys.argv
def f(x,n):r=chr((ord(x.lower())-97+n)%26+97);return(x,[r,r.upper()][x.isupper()])
print''.join(f(x,int(k[2]))[x.isalpha()] for x in k[1])

Karena ini sangat tidak dapat dibaca, ini adalah versi yang tidak diklik:

import sys

def shift(x,n):
    # shift character x by n (all in lowercase)
    r = chr((ord(x.lower())-97+n)%26+97)
    if x.isalpha() and x.islower():
        return r
    elif x.isalpha() and x.isupper():
        return r.upper()
    else:
        return x

# 'map' the function shift to each character of the input   
output = ''.join(shift(x,int(sys.argv[2])) for x in sys.argv[1])
print(output)

Mengenai input: Ini mengharapkan dua argumen, yang pertama harus berupa string dan yang kedua adalah integer (jumlah shift). Contoh (file disebut csr.py):

$ python csr.py gnu 9
pwd
$ python csr.py "Spam spam spam sausage and spam\!" 13
Fcnz fcnz fcnz fnhfntr naq fcnz!

Catatan: Pada contoh kedua ""diperlukan karakter pelarian dan diperlukan

ბიმო
sumber
1

Python 2, 118 116 byte

s,n=input()
print''.join([[c,chr((ord(c)-97+n)%26+97)]['`'<c<'{'],chr((ord(c)-65+n)%26+65)]['@'<c<'[']for c in s)
TFeld
sumber
Anda mungkin ingin menggunakan daftar alih-alih if/elseinstance ( codegolf.stackexchange.com/a/62/36885 ). Misalnya, print''.join([[c,chr((ord(c)-97+n)%26+97)]['~'<c<'{'],chr((ord(c)-65+n)%26+65)]['@'<c<'[']for c in s)sedikit lebih pendek, dan harus bekerja sama. (Kecuali mengubah tilde menjadi backtick seperti yang Anda miliki sebelumnya - saya tidak bisa mendapatkan backtick untuk ditampilkan dengan benar.)
mathmandan
1

Mathematica, 117 byte

Echo[InputString[]~StringReplace~Thread[Join[a=Alphabet[],b=ToUpperCase@a]->(c=RotateLeft)[a,d=Input[]]~Join~c[b,d]]]

Mengambil string, diikuti oleh baris baru, diikuti oleh faktor pemindahan. Mungkin masih bisa golf ...

LegionMammal978
sumber
1

Perl 6 , 73 + 1 = 74 byte

$ perl6 -pe 's:g:i/<[a..z]>/{chr ((my$o=ord ~$/)-(my$a=$o+&96+1)+BEGIN get%26)%26+$a}/' # 73+1

Baris input pertama adalah jumlah karakter untuk menggeser huruf ke atas.

Pemakaian:

$ perl6 -pe 's:g:i/<[a..z]>/{...}/' <<< \
'1
abcdefghijklmnopqrstuvwxyz'
bcdefghijklmnopqrstuvwxyza
$ perl6 -pe 's:g:i/<[a..z]>/{...}/' <<< \
'13
Spam spam spam sausage and spam!'
Fcnz fcnz fcnz fnhfntr naq fcnz!
$ perl6 -pe 's:g:i/<[a..z]>/{...}/' <<< \
'52
abcdefghijklmnopqrstuvwxyz'
abcdefghijklmnopqrstuvwxyz
$ perl6 -pe 's:g:i/<[a..z]>/{...}/' <<< \
'-1
abcdefghijklmnopqrstuvwxyz'
zabcdefghijklmnopqrstuvwxy
$ perl6 -pe 's:g:i/<[a..z]>/{...}/' <<< \
'3
ABCxyz'
DEFabc
$ perl6 -pe 's:g:i/<[a..z]>/{...}/' <<< \
'1000000000000000000000000000000000000000
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ'
mnopqrstuvwxyzabcdefghijkl
MNOPQRSTUVWXYZABCDEFGHIJKL
Brad Gilbert b2gills
sumber
1

C ++, 163 154 152 byte

#include<cstdio>
#include<cstdlib>
int main(int x,char**a){for(int c,b,s=atoi(a[1]);1+(c=getchar());putchar(c<b|c>b+26?c:(c+s-b+26)%26+b))b=c<97?65:97;}

Pemakaian:

$ ./caesar -1 <<< "123 a A z Z aBcDeFgHiKlMnOpQrStUvWxYz"
123 z Z y Y zAbCdEfGhJkLmNoPqRsTuVwXy
Simon D.
sumber
0

k4, 80 byte

Program menerima nomor shift sebagai argumen baris perintah dan membaca teks dari stdin.

Karena kendala teknis, pergeseran negatif harus dikodekan dengan garis bawah, bukan tanda hubung minus. (Tanpa parser untuk menafsirkan encoding ini, solusinya akan menjadi 64 byte.)

% wc -c c.k
80 c.k
% cat c.k
c:{x;,/x{y!(x_y),x#y}'.Q`a`A}
.z.pi:{1@x^c[.q.mod[.*{x^((!).$"_-")x}.z.x]26]x;}
% 

Inilah contoh-contoh yang dieksekusi:

% echo abcdefghijklmnopqrstuvwxyz|q c.k 1
bcdefghijklmnopqrstuvwxyza
% echo 'Spam spam spam sausage and spam!'|q c.k 13
Fcnz fcnz fcnz fnhfntr naq fcnz!
% echo abcdefghijklmnopqrstuvwxyz|q c.k 52
abcdefghijklmnopqrstuvwxyz
% echo abcdefghijklmnopqrstuvwxyz|q c.k _1
zabcdefghijklmnopqrstuvwxy
% echo ABCxyz|q c.k 3
DEFabc
%

Dan ini adalah test harness kecil konyol yang memverifikasi encode dan decode. (Ini zsh; untuk bashatau ksh, ubah forpengindeksan loop ke((i=0;i<5;i++)) . Array berbasis satu, ugh ....)

% a=(abcdefghijklmnopqrstuvwxyz 'Spam spam spam sausage and spam!' abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz ABCxyz)
% b=(1 13 52 _1 3)
% c=(bcdefghijklmnopqrstuvwxyza 'Fcnz fcnz fcnz fnhfntr naq fcnz!' abcdefghijklmnopqrstuvwxyz zabcdefghijklmnopqrstuvwxy DEFabc)
% for ((i=1;i<=5;i++))
for> do
for>     r=$(echo "${a[i]}"|q c.k "${b[i]}")
for>     s=$(echo "$r"|if [[ ${b[i]} == _* ]]; then q c.k "${b[i]/_}"; else q c.k "_${b[i]}"; fi)
for>     printf '%s\t%s\n' "$([[ ${c[i]} == $r ]] && echo good || echo bad)" "$([[ ${a[i]} == $s ]] && echo good || echo bad)"
for> done
good    good
good    good
good    good
good    good
good    good
% 
Aaron Davies
sumber