Caesar Shifting


22

Um turno de César é provavelmente algo com o qual todos estamos familiarizados.

(Você pode até fazer isso como uma tarefa de casa. Se sim, por favor, não copie essas respostas, seu professor quase certamente não quer nada parecido com as respostas aqui.)

Caso não esteja, um turno de César é uma forma muito simples de cifra. É preciso uma string para ser cifrada e um número inteiro. Em seguida, para cada caractere alfabético na sequência, execute a seguinte transformação:

  1. Calcule a posição do personagem no alfabeto (com base em 0).
  2. Adicione a esse número o número inteiro recebido no início.
  3. Enquanto o número for maior que 25, subtraia 26 dele.
  4. Calcule a posição do alfabeto em que está.

Deixe o restante dos caracteres sem deslocamento.

As letras maiúsculas devem ser respeitadas porque o que é inglês sem letras maiúsculas?

Exemplos:

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

Suposições

  • Você pode receber qualquer caractere ASCII imprimível
  • O número de entrada pode ser negativo e sempre será maior que -128 e menor que 128 ( -128<x<128)
  • Você deve poder codificar letras maiúsculas e não maiúsculas de forma reversível.
  • Você deve criar um programa completo, não apenas uma função ou trecho
  • Você receberá sua entrada do STDIN ou do alternativo mais próximo
  • Você pode escolher o formato para sua entrada, por favor, indique-o na sua resposta
  • Os caracteres que precisam ser deslocados são pontos de código ASCII 0x41 - 0x5Ae 0x61-0x7A- letras maiúsculas e minúsculas

    • Letras maiúsculas devem ficar em maiúsculas
    • Letras minúsculas devem ficar em minúsculas
    • Os caracteres fora desse intervalo devem ser deixados como estão.
  • Nota para este desafio: você só precisa codificar cadeias de caracteres, não precisa resolvê-las automaticamente (mas a doação -xreverterá a codificação)


Por se tratar de um catálogo, os idiomas criados após esse desafio podem competir. Observe que deve haver um intérprete para que o envio possa ser testado. É permitido (e até encorajado) escrever esse intérprete para um idioma anteriormente não implementado. Fora isso, todas as regras padrão do devem ser obedecidas. Os envios na maioria dos idiomas serão pontuados em bytes em uma codificação preexistente apropriada (geralmente UTF-8).

Catálogo

O snippet de pilha na parte inferior desta postagem gera o catálogo a partir das respostas a) como uma lista da solução mais curta por idioma eb) como uma tabela geral de líderes.

Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:

## Language Name, N bytes

onde Nestá o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:

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

Se você quiser incluir vários números no cabeçalho (por exemplo, porque sua pontuação é a soma de dois arquivos ou você deseja listar as penalidades do sinalizador de intérpretes separadamente), verifique se a pontuação real é o último número no cabeçalho:

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

Você também pode transformar o nome do idioma em um link que será exibido no snippet:

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


8
"Você pode até fazer isso como uma tarefa de casa. Se sim, por favor, não copie essas respostas, seu professor quase certamente não quer nada parecido com as respostas aqui ." Eu me pergunto o que aconteceria se você entregou um professor um remendo de 90 bytes de caracteres desarrumado e atalhos ...
ASCIIThenANSI

Respostas:


9

Pitão, 13 bytes

uXGH.<HQrBG1z

Suíte de teste

Basicamente, começamos com as duas strings que queremos alterar em césar, os alfabetos em minúsculas e maiúsculas. A lista que contém ambos é gerada por rBG1, bifurca em maiúsculas. Em seguida, reduzimos essa lista, iniciando com a sequência de entrada e traduzindo primeiro letras minúsculas e depois letras maiúsculas no turno apropriado.


Muito bom, continuo esquecendo que a bifurcação existe ...: P
FryAmTheEggman


5

Pacote Bash + bsd-games, 21

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

Builtins FTW! Quase parece o Mathematica. Respostas Pyth ainda são mais curtas.

String de entrada lida em STDIN e número inteiro na linha de comando. por exemplo:

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

Ou se você não gosta do incorporado:

Bash + coreutils, 63

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

Parece-me que a versão coreutils não funciona com -127 e / ou 127?
Neil

@ Neil Yes. Boa pegada. Fixo.
Digital Trauma

5

JavaScript (ES6), 122 118 114 111 bytes

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

Guardado 4 bytes graças a @Neil !

Explicação

O primeiro prompt pega a sequência de entrada. O segundo é o número pelo qual cada letra é deslocada.

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
Muito agradável! Mas não funciona em todas as entradas; tente "abcdefg", -26. Isso pode ser corrigido alterando a fórmula para (x-a+n+130)%26.
ETHproductions

@ETHproductions Obrigado por assistir!
user81655

"Você deve criar um programa completo, não apenas uma função ou trecho"
LegionMammal978

@ LegionMammal978 Obrigado, eu não percebi isso.
user81655

Será que a=x&96,(x-a+n+129)%26+a+1ajuda?
Neil

3

CJam, 34 22 21 20 bytes

Agradecemos a FryAmTheEggman por economizar 1 byte.

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

Teste aqui.

Entrada é a sequência a ser trocada na primeira linha e a troca na segunda.

Explicação

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 The '[,_el^é uma dica de Dennis. Eu não sei o que você quer dizer com fisso, parece um uso bastante normal?
Martin Ender

Acho que simplesmente não li respostas CJam suficientes: P Parece realmente interessante usá-lo como um mapa, mas altere a ordem dos argumentos.
FryAmTheEggman

@FryAmTheEggman, na verdade, eu não preciso do @ nada. :)
Martin Ender

2

Java, 249 bytes

Isso é o mais curto que eu pude entender. A leitura de stdin consome uma tonelada de bytes. Uma solução usando args da linha de comando é visivelmente mais curta, mas esta tarefa especificou stdin para entrada.

O formato de entrada é a String primeiro, seguida pelo número do turno em uma nova linha.

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

Usando argumentos da linha de comando, esta solução tem apenas 188 bytes. Input é a String como o primeiro argumento e a mudança como o segundo.

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 bytes

código

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

destroçado

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
}

Este programa pega a entrada do usuário de STDIN, primeiro o deslocador inteiro e depois a sequência, caractere por caractere.


1

Perl, 81 bytes

(+1 para a -pbandeira)

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

Ainda trabalhando no golfe ...

Teste:

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 bytes

Não tenho certeza se ainda posso jogar golfe ..

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

Já que é bastante ilegível, aqui está uma versão não destruída:

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)

Com relação à entrada: espera dois argumentos, o primeiro deve ser uma sequência e o segundo um número inteiro (a quantidade de turno). Exemplos (o arquivo é chamado csr.py):

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

Nota: No segundo exemplo, um caractere de escape e ""são necessários


1

Python 2, 118 116 bytes

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)

Você pode usar listas em vez das if/elseinstâncias ( codegolf.stackexchange.com/a/62/36885 ). Por exemplo, print''.join([[c,chr((ord(c)-97+n)%26+97)]['~'<c<'{'],chr((ord(c)-65+n)%26+65)]['@'<c<'[']for c in s)é um pouco mais curto e deve funcionar da mesma maneira. (Exceto a mudança o til a um backtick como você tinha antes - eu não poderia começar a crase para display direito.)
mathmandan

1

Mathematica, 117 bytes

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

Pega a sequência, seguida por uma nova linha, seguida pelo fator de mudança. Ainda pode ser jogável ...


1

Perl 6 , 73 + 1 = 74 bytes

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

A primeira linha de entrada é o número de caracteres para aumentar as letras.

Uso:

$ 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 bytes

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

Uso:

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

0

k4, 80 bytes

O programa aceita o número do turno como argumento da linha de comando e lê o texto de stdin.

Devido a uma restrição técnica, as mudanças negativas devem ser codificadas com um sublinhado em vez de um hífen-menos. (Sem o analisador para interpretar essa codificação, a solução seria 64 bytes.)

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

Aqui estão os exemplos executados:

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

E aqui está um pequeno equipamento de teste bobo que verifica tanto a codificação quanto a decodificação. (Isto é zsh; para bashou ksh, altere a forindexação do loop para ((i=0;i<5;i++)). Matrizes baseadas em um, 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
% 
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.