Caesar Shifting


22

Un turno di Cesare è probabilmente qualcosa che conosciamo tutti.

(Potresti anche farlo come compito a casa. In tal caso, ti preghiamo di non copiare queste risposte, il tuo insegnante quasi sicuramente non vuole nulla di simile alle risposte qui.)

Nel caso in cui non lo sia, un turno di Cesare è una forma molto semplice di cifra. Ci vuole una stringa per essere cifrato e un numero intero. Quindi, per ogni carattere alfabetico nella stringa, eseguire la seguente trasformazione:

  1. Calcola la posizione del personaggio nell'alfabeto (basato su 0).
  2. Aggiungi a quel numero il numero intero ricevuto all'inizio.
  3. Mentre il numero è maggiore di 25, sottrai 26 da esso.
  4. Calcola la posizione dell'alfabeto in cui si trova.

Lascia il resto dei personaggi libero.

Le lettere maiuscole devono essere rispettate perché cos'è l'inglese senza lettere maiuscole?

Esempi:

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

ipotesi

  • È possibile ricevere qualsiasi carattere ASCII stampabile
  • Il numero di input può essere negativo e sarà sempre maggiore di -128 e inferiore a 128 ( -128<x<128)
  • Devi essere in grado di codificare in modo reversibile lettere maiuscole e non maiuscole.
  • Devi creare un programma completo, non solo una funzione o un frammento
  • Riceverai i tuoi suggerimenti da STDIN o dal supplente più vicino
  • Puoi scegliere il formato per il tuo input, per favore indicalo nella tua risposta
  • I caratteri che devono essere spostati sono punti di codice ASCII 0x41 - 0x5Ae 0x61-0x7A- lettere maiuscole e minuscole

    • Le lettere maiuscole dovrebbero rimanere in maiuscolo
    • Le lettere minuscole dovrebbero rimanere minuscole
    • I personaggi non compresi in questo intervallo devono essere lasciati così come sono
  • Nota per questa sfida, devi solo cifrare le stringhe, non devi essere in grado di risolverle automaticamente (ma dare -xinvertirà la cifra)


Poiché si tratta di un catalogo, le lingue create dopo questa sfida possono competere. Si noti che deve essere presente un interprete per poter testare l'invio. È permesso (e persino incoraggiato) di scrivere questo interprete per una lingua precedentemente non implementata. A parte questo, tutte le regole standard del devono essere rispettate. Le iscrizioni nella maggior parte delle lingue verranno classificate in byte in una codifica preesistente appropriata (di solito UTF-8).

Catalogare

Lo snippet di stack nella parte inferiore di questo post genera il catalogo dalle risposte a) come elenco della soluzione più breve per lingua eb) come classifica generale.

Per assicurarti che la tua risposta venga visualizzata, ti preghiamo di iniziare la risposta con un titolo, usando il seguente modello Markdown:

## Language Name, N bytes

dov'è Nla dimensione del tuo invio. Se si migliora il punteggio, è possibile mantenere i vecchi punteggi nel titolo, colpendoli. Per esempio:

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

Se si desidera includere più numeri nell'intestazione (ad es. Perché il punteggio è la somma di due file o si desidera elencare separatamente le penalità del flag dell'interprete), assicurarsi che il punteggio effettivo sia l' ultimo numero nell'intestazione:

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

Puoi anche rendere il nome della lingua un collegamento che verrà quindi visualizzato nello snippet:

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


8
"Potresti anche farlo come un compito a casa. In tal caso, ti preghiamo di non copiare queste risposte, il tuo insegnante quasi sicuramente non vuole nulla di simile alle risposte qui ." Mi chiedo cosa succederebbe se consegnassi a un insegnante un
kludge di

Risposte:


9

Pyth, 13 byte

uXGH.<HQrBG1z

Suite di test

Fondamentalmente, iniziamo con le due stringhe che vogliamo spostare caesar, gli alfabeti minuscoli e maiuscoli. L'elenco contenente entrambi questi è generato da rBG1, biforcato in maiuscolo. Quindi, riduciamo questo elenco, iniziando con la stringa di input e traducendo prima le lettere minuscole, quindi le lettere maiuscole con lo spostamento appropriato.


Molto bello, continuo a dimenticare che esiste la biforcazione ...: P
FryAmTheEggman,


5

Pacchetto Bash + bsd-games, 21

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

Builtins FTW! Sembra quasi Mathematica. Le risposte di Pyth sono comunque più brevi.

Stringa di input letta da STDIN e numero intero dalla riga di comando. per esempio:

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

O se non ti piace il builtin:

Bash + coreutils, 63

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

Mi sembra che la versione coreutils non funzioni con -127 e / o 127?
Neil,

@Neil Sì. Buona pesca. Fisso.
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()))

4 byte salvati grazie a @Neil !

Spiegazione

Il primo prompt richiede la stringa di input. Il secondo è il numero per cui spostare ciascuna lettera.

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
Molto bella! Ma non funziona su tutti gli input; provare "abcdefg", -26. Questo può essere risolto cambiando la formula in (x-a+n+130)%26.
ETHproductions

@ETHproductions Grazie per averlo colto!
user81655

"Devi creare un programma completo, non solo una funzione o uno snippet"
LegionMammal978,

@ LegionMammal978 Grazie, non me ne sono accorto.
user81655

Does a=x&96,(x-a+n+129)%26+a+1aiuto?
Neil,

3

CJam, 34 22 21 20 byte

Grazie a FryAmTheEggman per aver salvato 1 byte.

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

Provalo qui.

Input è la stringa che deve essere shifte sulla prima riga e lo shift sulla seconda.

Spiegazione

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^è un consiglio di Dennis. Non capisco cosa intendi per f, sembra un uso abbastanza normale?
Martin Ender,

Immagino di non aver letto abbastanza risposte di CJam: P Sembra davvero pulito usarlo come una mappa ma cambiare l'ordine degli argomenti.
FryAmTheEggman,

@FryAmTheEggman in realtà, non mi serve @affatto. :)
Martin Ender,

2

Java, 249 byte

Questo è il più breve possibile. La lettura da stdin consuma una tonnellata di byte. Una soluzione che utilizza args da riga di comando è notevolmente più breve ma, questa attività specifica lo stdin per l'input.

Il formato di input è la stringa seguita prima dal numero di spostamento su una nuova riga.

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

Utilizzando gli argomenti della riga di comando questa soluzione è di soli 188 byte. Input è la stringa come primo argomento e lo spostamento come secondo.

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 byte

codice

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
}

Questo programma prende l'input dell'utente da STDIN, prima il cambio intero e poi la stringa, carattere per carattere.


1

Perl, 81 byte

(+1 per la -pbandiera)

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

Sto ancora lavorando sul golf ...

Test:

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 byte

Non sono sicuro di poter ancora giocare a 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])

Dal momento che è piuttosto illeggibile, ecco una versione non golfata:

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)

Per quanto riguarda l'input: prevede due argomenti, il primo deve essere una stringa e il secondo un numero intero (la quantità di spostamento). Esempi (viene chiamato il filecsr.py ):

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

Nota: nel secondo esempio ""sono necessari un carattere di escape


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)

È possibile che si desideri utilizzare elenchi anziché le if/elseistanze ( codegolf.stackexchange.com/a/62/36885 ). Ad esempio, print''.join([[c,chr((ord(c)-97+n)%26+97)]['~'<c<'{'],chr((ord(c)-65+n)%26+65)]['@'<c<'[']for c in s)è un po 'più corto e dovrebbe funzionare allo stesso modo. (Tranne cambiare la tilde in un backtick come avevi prima - non sono riuscito a visualizzare correttamente il
backtick

1

Mathematica, 117 byte

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

Prende la stringa, seguita da una nuova riga, seguita dal fattore di spostamento. Potrebbe essere ancora golfabile ...


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

La prima riga di input è il numero di caratteri per cui spostare le lettere in alto.

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

Uso:

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

0

k4, 80 byte

Il programma accetta il numero di turno come argomento della riga di comando e legge il testo dallo stdin.

A causa di un vincolo tecnico, i turni negativi devono essere codificati con un trattino basso anziché un trattino-meno. (Senza il parser per l'interpretazione di questa codifica, la soluzione sarebbe di 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;}
% 

Ecco gli esempi eseguiti:

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

Ed ecco un piccolo test stupido che verifica sia la codifica che la decodifica. (Questo è zsh; per basho ksh, cambia l' forindicizzazione del loop in ((i=0;i<5;i++)). Array a una base, 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
% 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.