Shifting Caesars Shift


13

Descrizione

A Caesar Shift è una cifra monoalfabetica molto semplice in cui ogni lettera viene sostituita da una dopo l'alfabeto. Esempio:

Hello world! -> IFMMP XPSME!

( IBSLR, EGUFV!è l'output per la vera sfida, questo è stato un esempio di spostamento di 1.)

Come puoi vedere, la spaziatura e la punteggiatura rimangono intatte. Tuttavia, per evitare di indovinare il messaggio, tutte le lettere sono in maiuscolo. Spostando indietro le lettere, il messaggio è stato decifrato, conveniente, ma anche molto facile da decifrare da altre persone che dovrebbero non sapere cosa significhi il messaggio.

Quindi, aiuteremo Cesare un po 'usando una forma avanzata del suo codice: il Caesar Shift a spostamento automatico !

Sfida

Il tuo compito è scrivere un programma o una funzione che, data una stringa da codificare, emetta la stringa crittografata corrispondente all'input. L'avanzato Caesar Shift funziona così:

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

Gli spazi e altri simboli speciali, come la punteggiatura, vengono saltati in questo processo. È garantito che al programma verrà assegnata una stringa contenente solo caratteri ASCII stampabili. L'output della tua funzione / programma deve essere solo in maiuscolo.

Questo è , quindi si applicano scappatoie standard e può vincere la risposta più breve in byte!


2
No E -3?
Leaky Nun,

3
Che cosa succede se la differenza di lettera porta la lettera fuori dall'alfabeto? Ad ZENesempio. Zspostato di 1 è ... A? (come nota a margine, la risposta 05AB1E si trasforma Zin A)
Mr. Xcoder il

6
Casi di prova per favore. Inoltre, quali personaggi vengono saltati esattamente? E cosa significa per loro essere saltati? Vengono rimossi del tutto o devono rimanere nell'output?
Luis Mendo,

1
@Giuseppe vede le risposte votate per i casi di test, sono state validate dall'OP come corrette, presumo, o avrebbero un voto negativo.
Magic Octopus Urn,

2
Intendevi parole come RELIEFe RELIEScifrare entrambe allo stesso risultato SRSFAG?
Anders Kaseorg,

Risposte:


5

05AB1E , 28 27 24 byte

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

Provalo online!

Spiegazione

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

Entrambi abbiamo get IBSLR, EGUFV!per Hello, World!, è corretto? OP ha appena sbagliato quell'esempio?
Magic Octopus Urn,

1
@MagicOctopusUrn: il suo esempio all'inizio sta solo mostrando che cos'è uno spostamento. Si sposta di 1 lettera, quindi è piuttosto fuorviante.
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))

Provalo online!

btiene traccia del codice ASCII dell'ultima lettera o è inizialmente zero; la formula c+c-(b or~-x)indica che una lettera con codice ASCII cviene spostata c-bse if bè diverso da zero e c-(c-1) == +1if bè zero (per la prima lettera).

bnon diventerà mai più zero, poiché la stringa è garantita da caratteri ASCII stampabili .

Infine, 64<c<91controlla se cè una lettera ASCII maiuscola e (…-65)%26+65avvolge tutto A-Znell'intervallo.

ovs ha salvato un byte. Grazie!





1

MATL , 27 byte

tXkt1Y2mXH)tlwdh+64-lY2w)H(

Provalo online!

Penso che questo sia il più breve che posso ottenere, ma ci sono molte varietà diverse poiché c'è un sacco di riutilizzo delle "variabili" (ci sono 3 t(duplicazione) e 2 w(scambio), gli appunti Hvengono usati e anche allora c'è ancora un duplicato 1Y2...). Purtroppo, non sono riuscito a salvare byte con gli Mappunti automatici .

Oltre la metà del programma è dedicata a renderlo maiuscolo e ignorato i caratteri non alfabetici: solo la cifra non supera i 13 byte ( provalo online! )


1

Perl, 90 89

Sebbene le lingue non codegolf siano raramente competitive, possiamo andare al di sotto di 100;)

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

Ho deciso di deselezionare questo:

@a = split//,<>; Prende input da STDIN, memorizza l'elenco dei caratteri (con newline!) In @a.

say uc(++$a[0])output maiuscola prima lettera spostata di 1. Si scopre che è possibile incrementare una lettera in perl se si utilizza un prefisso ++. Questo è un mutatore ofc.

2*ord($a[$_+1])-ord($a[$_])+!$_Ci viene chiesto di prendere il carattere in xe di aggiungere la differenza + (x- (x-1)). Bene, questo è 2x - (x-1). Tuttavia: ho cambiato la prima lettera! Quindi devo correggere quell'errore, quindi +!$_, che correggerà per averne sottratto uno alla posizione 0 (l'unico caso! $ _ Non è indefinito). Dobbiamo quindi uc chrottenere una lettera maiuscola dal valore ASCII calcolato.

map{ ... } $#a-2- $#aè la posizione per accedere all'ultimo elemento dell'array. Dal momento che ne sto aggiungendo uno che desidero $#a-1, ma poiché la newline dall'input deve essere ignorata, questo è $#a-2.

Questo è concatenato con la prima lettera e abbiamo finito :)


Questo sembra avere dei problemi con gli offset che avvolgono l'alfabeto e con i caratteri non alfabetici. Provalo 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

Provalo online!


Questo non salta totalmente le non lettere; semplicemente non li converte. Penso che Hello, World!dovrebbe tradursi IBSLR, EGUFV!, no IBSLR, XGUFV!.
Tito,

Hai ragione. Risolto il problema con altri 4 byte per preservare la lettera precedente.
Xcali,

1

PHP, 106 98 byte

piuttosto brutto quello ... se base_convertnon fosse così lungo (o ctype_alpha) ...
ma l'ho ottenuto sotto i 100. soddisfatto.

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

Esegui come pipe -nRo provalo online .


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.