Shifting Caesars Shifts

13

La description

Un changement de César est un chiffre monoalphabétique très simple où chaque lettre est remplacée par celle qui la suit dans l'alphabet. Exemple:

Hello world! -> IFMMP XPSME!

( IBSLR, EGUFV!est la sortie pour le défi réel, c'était un exemple de décalage de 1.)

Comme vous pouvez le voir, l'espacement et la ponctuation restent sans accord. Cependant, pour éviter de deviner le message, toutes les lettres sont en majuscules. En reculant les lettres, le message a été déchiffré, pratique, mais aussi très facile à déchiffrer par d'autres personnes censées ne pas savoir ce que signifie le message.

Nous allons donc aider un peu César en utilisant une forme avancée de son chiffre: le changement César auto-changeant !

Défi

Votre tâche consiste à écrire un programme ou une fonction qui, étant donné une chaîne à chiffrer, génère la chaîne chiffrée correspondant à l'entrée. Le Caesar Shift avancé fonctionne comme ceci:

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

Les espaces et autres symboles spéciaux, tels que la ponctuation, sont ignorés dans ce processus. Il est garanti que votre programme recevra une chaîne contenant uniquement des caractères ASCII imprimables. La sortie de votre fonction / programme doit être uniquement en majuscules.

Il s'agit de , donc les échappatoires standard s'appliquent, et la réponse la plus courte en octets peut gagner!

racer290
la source
2
Non E -3?
Leaky Nun
3
Et si la différence de lettre fait sortir la lettre de l'alphabet? Comme ZEN, par exemple. Zdécalé de 1 est ... A? (en guise de remarque, la réponse 05AB1E se transforme Zen A)
M. Xcoder
6
Cas de test s'il vous plaît. De plus, quels caractères sont ignorés exactement? Et qu'est-ce que cela signifie pour eux d'être ignorés? Sont-ils supprimés complètement ou doivent-ils rester dans la sortie?
Luis Mendo
1
@Giuseppe voit les réponses des votes positifs pour les cas de test, ils ont été validés par OP comme corrects, je suppose, ou ils auraient des votes négatifs.
Magic Octopus Urn
2
Vouliez-vous dire pour les mots comme RELIEFet RELIESpour les deux chiffrer au même résultat SRSFAG?
Anders Kaseorg

Réponses:

5

05AB1E , 28 27 24 octets

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

Essayez-le en ligne!

Explication

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
la source
Nous avons tous deux get IBSLR, EGUFV!pour Hello, World!, est - ce exact? OP a-t-il simplement gâché cet exemple?
Magic Octopus Urn
1
@MagicOctopusUrn: Son exemple au début montre simplement ce qu'est un changement. Il décale simplement d'une lettre, donc c'est assez trompeur.
Emigna
4

Python 3 , 100 octets

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

Essayez-le en ligne!

bgarde la trace du code ASCII de la dernière lettre, ou est initialement zéro; la formule c+c-(b or~-x)signifie qu'une lettre avec un code ASCII cest décalée de c-bsi best différent de zéro et c-(c-1) == +1si best nul (pour la toute première lettre).

bne redeviendra plus jamais nul, car la chaîne est composée de caractères ASCII imprimables .

Enfin, 64<c<91vérifie s'il cs'agit d'une lettre ASCII majuscule et (…-65)%26+65remet tout dans la A-Zplage.

ovs a enregistré un octet. Merci!

Lynn
la source
1

ES6 (Javascript), 138 octets:

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
la source
ne saute pas les non-lettres, semble-t-il?
Titus
1

MATL , 27 octets

tXkt1Y2mXH)tlwdh+64-lY2w)H(

Essayez-le en ligne!

Je pense que c'est la plus courte possible, mais il existe de nombreuses variétés différentes car il y a beaucoup de réutilisation de `` variables '' (il y a 3 opérations t(duplication) et 2 w(permutation), le presse H- papiers est utilisé, et même alors il y a encore un doublon 1Y2...). Malheureusement, je n'ai pas pu enregistrer d'octets avec le Mpresse-papiers automatique .

Plus de la moitié du programme est dédié à le rendre en majuscules et à ignorer les caractères non alphabétiques - juste le chiffre ne dépasse pas 13 octets ( Essayez-le en ligne! )

Sanchises
la source
1

Perl, 90 89

Bien que les langues autres que le codegolf soient rarement compétitives, nous pouvons descendre en dessous de 100;)

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

J'ai décidé de dé-golfer ceci:

@a = split//,<>; Prend l'entrée de STDIN, stocke la liste des caractères (avec la nouvelle ligne!) Dans @a.

say uc(++$a[0])sortie première lettre majuscule décalée de 1. Il s'avère que vous pouvez incrémenter une lettre en perl si vous utilisez un préfixe ++. C'est un mutateur ofc.

2*ord($a[$_+1])-ord($a[$_])+!$_On nous demande de prendre le caractère en x et d'ajouter la différence + (x- (x-1)). Eh bien, c'est 2x - (x-1). Cependant: j'ai changé la première lettre! Je dois donc corriger cette erreur, ce +!$_qui corrigera le fait d'avoir soustrait un trop à la position 0 (seul cas! $ _ N'est pas indéfini). Nous devons ensuite uc chrobtenir une lettre majuscule à partir de la valeur ASCII calculée.

map{ ... } $#a-2- $#aest la position pour accéder au dernier élément du tableau. Puisque j'en ajoute un, je veux $#a-1, mais parce que la nouvelle ligne d'entrée doit être ignorée, c'est le cas $#a-2.

Ceci est concaténé avec la première lettre, et nous avons terminé :)

bytepusher
la source
Cela semble avoir des problèmes avec les décalages qui entourent l'alphabet et avec les caractères non alphabétiques. Essayez-le en ligne!
Xcali
1

Perl 5 -F , 73 77 74 octets

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

Essayez-le en ligne!

Xcali
la source
Cela ne saute pas totalement les non-lettres; il ne les convertit tout simplement pas. Je pense que cela Hello, World!devrait aboutir IBSLR, EGUFV!, non IBSLR, XGUFV!.
Titus
Tu as raison. Correction de 4 octets supplémentaires pour conserver la lettre précédente.
Xcali
1

PHP, 106 98 octets

assez méchant celui-là ... si ce base_convertn'était pas si long (ou ctype_alpha) ...
mais je l'ai eu sous 100. satisfait.

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

Exécuter en tant que pipe avec -nRou l' essayer en ligne .

Titus
la source