Цезар зміщення


22

Зміна Цезаря - це, мабуть, те, що ми всі знайомі.

(Ви можете навіть робити це як домашнє завдання. Якщо це так, будь ласка, не копіюйте ці відповіді, ваш вчитель майже точно не хоче нічого подібного, як відповіді тут.)

На випадок, якщо ви цього не зробите, Цезар зміна - це дуже проста форма шифру. Потрібно зашифрувати рядок і ціле число. Потім для кожного алфавітного символу в рядку виконайте таке перетворення:

  1. Опрацюйте позицію персонажа в алфавіті (на основі 0).
  2. До цього числа додайте ціле число, отримане на початку.
  3. Поки число більше 25, відніміть 26.
  4. Опрацюйте положення алфавіту, в якому він знаходиться.

Решту персонажів залиште не зміненими.

Великі літери повинні дотримуватися, тому що англійська без великих літер?

Приклади:

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

Припущення

  • Ви можете отримати будь-який символ для друку ASCII
  • Число введення може бути негативним і завжди буде більше -128 і менше 128 ( -128<x<128)
  • Ви повинні вміти зворотно кодувати великі літери та великі літери.
  • Ви повинні створити повну програму, а не лише функцію чи фрагмент
  • Ви отримаєте свій внесок від STDIN або найближчого альтернативного
  • Ви можете обрати формат для введення, будь ласка, вкажіть це у своїй відповіді
  • Символи, які потрібно змістити, - це кодові точки ASCII 0x41 - 0x5Aі 0x61-0x7A- великі та малі літери

    • Літери верхнього регістру повинні залишатися верхніми
    • Малі літери повинні залишатися нижчими
    • Символи, що не входять до цього діапазону, повинні залишатися такими, якими вони є
  • Зверніть увагу на цей виклик: вам потрібно лише зашифрувати рядки, вам не потрібно мати можливість їх вирішувати автоматично (але надання -xшифру оберне)


Оскільки це каталог, мови, створені після цього виклику, допускаються до змагань. Зауважте, що повинен бути перекладач, щоб подати заявку можна перевірити. Дозволяється (і навіть рекомендується) писати цього перекладача самостійно для раніше не виконаної мови. Крім цього, повинні дотримуватися всі стандартні правила . Подання на більшості мов будуть оцінюватися в байтах у відповідному попередньому кодуванні (як правило, UTF-8).

Каталог

Фрагмент стека внизу цієї публікації генерує каталог з відповідей а) як список найкоротших варіантів для кожної мови та б) як загальний таблиця лідерів.

Щоб переконатися, що ваша відповідь відображається, будь ласка, почніть свою відповідь із заголовка, використовуючи наступний шаблон Markdown:

## Language Name, N bytes

де Nрозмір вашого подання. Якщо ви покращите свій рахунок, ви можете зберегти старі бали у заголовку, прокресливши їх. Наприклад:

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

Якщо ви хочете включити у свій заголовок декілька чисел (наприклад, тому що ваш показник становить суму двох файлів або ви хочете окремо перерахувати штрафні санкції для перекладача), переконайтеся, що фактичний бал є останнім номером у заголовку:

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

Ви також можете зробити ім'я мови посиланням, яке з’явиться у фрагменті:

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


8
"Ви можете навіть робити це як домашнє завдання. Якщо це так, будь ласка, не копіюйте ці відповіді, ваш вчитель майже точно не хоче нічого подібного, як відповіді ." Цікаво, що трапилося б, якби ти вручив вчителю 90-байтовий глузд безладних персонажів та ярликів ...
ASCIIThenANSI

Відповіді:


9

Pyth, 13 байт

uXGH.<HQrBG1z

Тестовий набір

В основному, ми починаємо з двох рядків, які ми хочемо кесаревої зміни, малі та малі алфавіти. Список, що містить обидва ці, генерується за допомогою rBG1роздвоєння у верхньому регістрі. Потім ми зменшуємо цей список, починаючи з введення рядка і перекладаючи спочатку малі, потім великі літери відповідним зрушенням.


Дуже добре, я забуваю, що біфуркація існує ...: P
FryAmTheEggman


5

Пакет Bash + bsd-ігор, 21

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

Вбудовані FTW! Майже відчуває себе Mathematica. Відповіді Pyth все ще коротші.

Вхідний рядок зчитується з STDIN та ціле число з командного рядка. наприклад:

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

Або якщо вам не подобається вбудований:

Bash + coreutils, 63

printf -va %s {a..z}
t=${a:$1%26}${a:0:$1%26}
tr A-Z$a ${t^^}$t

Мені здається, що версія coreutils не працює з -127 та / або 127?
Ніл

@Neil Так. Хороший улов. Виправлено.
Цифрова травма

5

JavaScript (ES6), 122 118 114 111 байт

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

Збережено 4 байти завдяки @Neil !

Пояснення

Перша підказка приймає рядок введення. Друга - це число, на яке слід перенести кожну букву.

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

1
Дуже хороша! Але він працює не на всіх входах; спробуйте "abcdefg", -26. Це можна виправити, змінивши формулу на (x-a+n+130)%26.
ETHproductions

@ETHproductions Дякуємо, що це зрозуміли!
користувач81655

"Ви повинні створити повну програму, а не лише функцію чи фрагмент"
LegionMammal978

@ LegionMammal978 Спасибі, я цього не помітив.
користувач81655

Чи a=x&96,(x-a+n+129)%26+a+1допомагає?
Ніл

3

CJam, 34 22 21 20 байт

Завдяки FryAmTheEggman за збереження 1 байта.

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

Перевірте це тут.

Введення - це рядок, який слід перенести на першому рядку, а зсув - на другому.

Пояснення

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.

@FryAmTheEggman Це '[,_el^підказка від Денніса. Я не знаю, про що ви хочете сказати, fхоча це здається досить нормальним використанням?
Мартін Ендер

Я думаю, що я просто не прочитав достатньо відповідей CJam: P Це здається дійсно акуратним, щоб використовувати його як карту, але змінити порядок аргументів.
FryAmTheEggman

@FryAmTheEggman насправді мені зовсім не потрібен @. :)
Мартін Ендер

2

Java, 249 байт

Це так коротко, як я міг би його отримати. Читання з stdin з'їдає тонну байтів. Рішення з використанням аргументів командного рядка помітно коротше, але ця задача задала stdin для введення.

Формат введення - це рядок спочатку, а потім номер зсуву в новому рядку.

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

Використовуючи аргументи командного рядка, це рішення становить лише 188 байт. Введення - це рядок як перший аргумент, а зсув - як другий.

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

1

R, 111 байт

код

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

неозорий

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
}

Ця програма приймає користувальницький вхід зі STDIN, спочатку цілочисельним зсувом, а потім рядком, символом за символом.


1

Perl, 81 байт

(+1 для -pпрапора)

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

Все ще працюю над гольфу ...

Тест:

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


1

Python 2, 163 160 байт

Не впевнений, чи зможу я все-таки пограти вниз.

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

Оскільки це досить нечитабельно, ось вам неперевершена версія:

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)

Щодо введення: Очікується два аргументи, перший повинен бути рядком, а другий цілим числом (сума зсуву). Приклади (файл називається csr.py):

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

Примітка. У другому прикладі ""потрібні символи втечі та потрібні


1

Python 2, 118 116 байт

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)

Ви можете використовувати списки замість if/elseекземплярів ( codegolf.stackexchange.com/a/62/36885 ). Наприклад, print''.join([[c,chr((ord(c)-97+n)%26+97)]['~'<c<'{'],chr((ord(c)-65+n)%26+65)]['@'<c<'[']for c in s)трохи коротше, і повинен працювати так само. (За винятком того, як змінити тильду на backtick, як у вас раніше - я не міг зробити зворотний
твір

1

Математика, 117 байт

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

Бере рядок, а потім новий рядок, а потім коефіцієнт зсуву. Можливо, все-таки буде гольфувати ...


1

Perl 6 , 73 + 1 = 74 байти

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

Перший рядок введення - це кількість символів, на які слід пересувати літери вгору.

Використання:

$ 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

1

C ++, 163 154 152 байт

#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;}

Використання:

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

0

k4, 80 байт

Програма приймає номер зсуву як аргумент командного рядка і читає текст з stdin.

Через технічне обмеження негативні зрушення повинні бути закодовані підкресленням замість дефісу. (Без аналізатора для інтерпретації цього кодування рішення було б 64 байти.)

% 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;}
% 

Ось наведені приклади:

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

А ось і дурний маленький тестовий джгут, який перевіряє і кодування, і декодування. (Це zsh; для bashабо ksh, змініть forіндексацію циклу на ((i=0;i<5;i++)). Один базирований масив, тфу ....)

% 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
% 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.