Caesars Shifts verschieben

13

Beschreibung

Ein Caesar Shift ist eine sehr einfache monoalphabetische Chiffre, bei der jeder Buchstabe durch den Buchstaben nach dem Buchstaben im Alphabet ersetzt wird. Beispiel:

Hello world! -> IFMMP XPSME!

( IBSLR, EGUFV!Ist die Ausgabe für die eigentliche Herausforderung, dies war ein Beispiel für die Verschiebung um 1.)

Wie Sie sehen können, bleiben Abstand und Interpunktion unbemerkt. Um jedoch zu verhindern, dass die Nachricht erraten wird, werden alle Buchstaben in Großbuchstaben geschrieben. Durch Zurückschieben der Buchstaben wurde die Nachricht entschlüsselt, bequem, aber auch von anderen Personen, die nicht wissen sollen, was die Nachricht bedeutet, wirklich leicht zu entschlüsseln.

Wir werden Caesar also ein wenig helfen, indem wir eine fortgeschrittene Form seiner Chiffre verwenden: den selbstverschiebenden Caesar Shift !

Herausforderung

Ihre Aufgabe ist es, ein Programm oder eine Funktion zu schreiben, die bei einer zu verschlüsselnden Zeichenfolge die der Eingabe entsprechende verschlüsselte Zeichenfolge ausgibt. Der fortgeschrittene Caesar Shift funktioniert so:

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

Leerzeichen und andere spezielle Symbole, z. B. Satzzeichen, werden dabei übersprungen. Es ist garantiert, dass Ihr Programm eine Zeichenfolge erhält, die nur druckbare ASCII-Zeichen enthält. Die Ausgabe Ihrer Funktion / Ihres Programms darf nur in Großbuchstaben erfolgen.

Dies ist , daher gelten Standardlücken, und es kann die kürzeste Antwort in Bytes gewinnen!

racer290
quelle
2
Nicht E -3?
Undichte Nonne
3
Was ist, wenn der Buchstabenunterschied den Buchstaben aus dem Alphabet entfernt? Wie ZENzum Beispiel. Zum 1 verschoben ist ... A? (Als Randnotiz verwandelt sich die 05AB1E-Antwort Zin A)
Mr. Xcoder
6
Testfälle bitte. Auch welche Zeichen werden genau übersprungen? Und was bedeutet es für sie, übersprungen zu werden? Werden sie komplett entfernt oder müssen sie in der Ausgabe bleiben?
Luis Mendo
1
@ Giuseppe sehen die upvoted Antworten für Testfälle, sie wurden von OP als korrekt validiert, ich nehme an, oder sie hätten downvotes.
Magic Octopus Urn
2
Meinten Sie für Wörter wie RELIEFund, RELIESum beide zum gleichen Ergebnis zu verschlüsseln SRSFAG?
Anders Kaseorg

Antworten:

5

05AB1E , 28 27 24 Bytes

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

Probieren Sie es online!

Erläuterung

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
Emigna
quelle
Wir bekommen beide IBSLR, EGUFV!dafür Hello, World!, ist das richtig? Hat OP dieses Beispiel nur durcheinander gebracht?
Magic Octopus Urn
1
@MagicOctopusUrn: Sein Beispiel am Anfang zeigt nur, was eine Verschiebung ist. Es verschiebt sich nur um einen Buchstaben, so dass es ziemlich irreführend ist.
Emigna
4

Python 3 , 100 Bytes

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

Probieren Sie es online!

bVerfolgt den ASCII-Code des letzten Buchstabens oder ist anfangs Null. Die Formel c+c-(b or~-x)bedeutet, dass ein Buchstabe mit ASCII-Code cum den c-bWert bungleich Null und den c-(c-1) == +1Wert bNull (für den allerersten Buchstaben) verschoben wird .

bwird nie wieder Null, da die Zeichenfolge garantiert aus druckbaren ASCII-Zeichen besteht.

Zum Schluss wird 64<c<91geprüft, ob ces sich um einen ASCII-Großbuchstaben handelt, und (…-65)%26+65alles wird wieder in den A-ZBereich eingeschlossen.

ovs hat ein Byte gespeichert. Vielen Dank!

Lynn
quelle
100 Bytes
Ovs
1

ES6 (Javascript), 138 Bytes:

s=>((s,a,f)=>((r=i=>s[i]&&(a[i]=String.fromCharCode((2*s[f](i)-(s[f](i-1)||71)-38)%26+64),r(i+1)))(0),a))(s.toUpperCase(),[],"charCodeAt")

http://jsbin.com/manurenasa/edit?console

Jonas Wilms
quelle
überspringt man anscheinend keine Buchstaben?
Titus
1

MATL , 27 Bytes

tXkt1Y2mXH)tlwdh+64-lY2w)H(

Probieren Sie es online!

Ich denke, dies ist die kürzeste, die ich bekommen kann, aber es gibt viele verschiedene Sorten, da 'Variablen' häufig wiederverwendet werden (es gibt 3 t(Duplizieren) und 2 w(Tauschen) Operationen, die Zwischenablage Hwird verwendet, und Auch dann gibt es noch ein Duplikat 1Y2...). Leider konnte ich mit der automatischen MZwischenablage keine Bytes speichern .

Über die Hälfte des Programms ist darauf ausgerichtet, Großbuchstaben zu schreiben und nicht-alphabetische Zeichen zu ignorieren - nur die Chiffre darf nicht länger als 13 Bytes sein ( Online ausprobieren! )

Sanchises
quelle
1

Perl, 90 89

Obwohl Nicht-Codegolf-Sprachen selten wettbewerbsfähig sind, können wir unter 100 gehen;)

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

Ich habe mich dazu entschlossen, dies zu entgolfen:

@a = split//,<>; Übernimmt die Eingabe von STDIN und speichert die Zeichenliste (mit Zeilenumbruch!) In @a.

say uc(++$a[0])Geben Sie den ersten Buchstaben in Großbuchstaben mit einer Verschiebung von 1 aus. Es hat sich herausgestellt, dass Sie einen Buchstaben in Perl erhöhen können, wenn Sie ein Präfix ++ verwenden. Dies ist ein Mutator von c.

2*ord($a[$_+1])-ord($a[$_])+!$_Wir werden gebeten, das Zeichen bei x zu nehmen und die Differenz + (x- (x-1)) zu addieren. Nun, das ist 2x - (x-1). Allerdings: Ich habe den Anfangsbuchstaben geändert! Also muss ich diesen Fehler korrigieren +!$_, der korrigiert wird, wenn an Position 0 zu viele subtrahiert wurden (nur Fall! $ _ Ist nicht undef). Wir erhalten dann uc chreinen Großbuchstaben aus dem berechneten ASCII-Wert.

map{ ... } $#a-2- $#aist die Position, an der auf das letzte Array-Element zugegriffen werden kann. Da ich einen hinzufüge, möchte ich $#a-1, aber weil der Zeilenumbruch von der Eingabe ignoriert werden muss, ist dies $#a-2.

Dies wird mit dem ersten Buchstaben verkettet, und wir sind fertig :)

Byteschieber
quelle
Dies scheint einige Probleme mit Offsets zu haben, die sich um das Alphabet und um nicht-alphabetische Zeichen drehen. Probieren Sie es online!
Xcali
1

Perl 5 -F , 73 77 74 Bytes

/\w/&&($_=chr 65+(2*($n=ord uc)-65-($!||-1+ord uc))%26)&($!=$n)for@F;say@F

Probieren Sie es online!

Xcali
quelle
Nicht-Buchstaben werden nicht vollständig übersprungen. es konvertiert sie einfach nicht. Ich denke Hello, World!sollte dazu führen IBSLR, EGUFV!, nicht IBSLR, XGUFV!.
Titus
Du hast recht. Problem mit 4 weiteren Bytes behoben, um den vorherigen Buchstaben beizubehalten.
Xcali
1

PHP, 106 98 Bytes

ziemlich böse das ... wenn nur base_convertnicht so lange (oder ctype_alpha) ...
aber ich habe es unter 100. zufrieden.

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

Laufen Sie als Pipe mit -nRoder versuchen Sie es online .

Titus
quelle