シーザーズシフト


13

説明

シーザーシフトは非常に単純な単一アルファベット暗号で、アルファベットの各文字がその後の文字に置き換えられます。例:

Hello world! -> IFMMP XPSME!

IBSLR, EGUFV!実際のチャレンジの出力です。これは1シフトした例です。)

ご覧のとおり、間隔と句読点は調整されていません。ただし、メッセージの推測を防ぐため、すべての文字は大文字です。文字を戻すことで、メッセージは解読され、便利になりましたが、メッセージの意味を知らないはずの人が解読するのも簡単です。

そこで、高度な形式の暗号を使用して、Caesarを少し支援します:Self-shifting Caesar Shift

チャレンジ

あなたの仕事は、暗号化する文字列が与えられると、入力に対応する暗号化された文字列を出力するプログラムまたは関数を書くことです。高度なシーザーシフトは次のように機能します。

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

このプロセスでは、スペースや句読点などのその他の特殊記号はスキップされます。プログラムには、印刷可能なASCII文字のみを含む文字列が与えられることが保証されています。関数/プログラムの出力は大文字でなければなりません。

これはであるため、標準の抜け穴が適用され、バイト単位の最短回答が勝つことがあります


2
じゃないE -3
リーキー修道女

3
文字の違いがアルファベットから文字を引き出す場合はどうなりますか?のようZENに、例えば。Z1シフト...はA?(サイドノートとして、05AB1E回答ターンZA
ミスターXcoder

6
テストケースをお願いします。また、どの文字が正確にスキップされますか?そして、それらがスキップされるとはどういう意味ですか?それらは完全に削除されますか、または出力に残る必要がありますか?
ルイスメンドー

1
@Giuseppeは、テストケースに対する投票された回答を確認し、OPによって正しいものとして検証された、私は推測する、または彼らはダウン票を持っているでしょう。
魔法のタコUr

2
のような単語RELIEFRELIES、同じ結果を暗号化するという意味SRSFAGですか?
アンダースカセオルグ

回答:


5

05AB1E28 27 24バイト

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

オンラインでお試しください!

説明

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

私たちは両方のために取得IBSLR, EGUFV!しますHello, World!、それは正しいですか?OPはその例を台無しにしましたか?
魔法のタコUr

1
@MagicOctopusUrn:最初の彼の例は、シフトとは何かを示しています。それは1文字だけシフトするため、かなり誤解を招きます。
エミグナ

4

Python 3、100バイト

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

オンラインでお試しください!

b最後の文字のASCIIコードを追跡するか、最初はゼロです。式は、c+c-(b or~-x)ASCIIコードで文字を意味するcだけシフトされますc-b場合はb非ゼロであり、そしてc-(c-1) == +1場合b(非常に最初の文字の場合)ゼロです。

b文字列は印刷可能な ASCII文字で構成されることが保証されているため、再びゼロになることはありません。

最後に、大文字のASCII文字64<c<91かどうかを確認し、すべてを範囲にラップします。c(…-65)%26+65A-Z

ovsはバイトを保存しました。ありがとう!





1

MATL、27バイト

tXkt1Y2mXH)tlwdh+64-lY2w)H(

オンラインでお試しください!

これは私が得ることができる最短だと思いますが、「変数」(3 t(複製)、2 w(スワップ)操作があり、クリップボードHが使用されているため、多くの異なる種類があります。それでも、まだ重複してい1Y2ます...)。悲しいことに、自動Mクリップボードでバイトを保存できませんでした。

プログラムの半分以上は大文字にし、アルファベット以外の文字を無視することに専念しています-暗号は13バイト以下です(オンラインで試してみてください!


1

Perl、90 89

非codegolf言語はめったに競合しませんが、100を下回ることもできます;)

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

私はこれをアンゴルフすることにしました:

@a = split//,<>; STDINから入力を取得し、@ aに文字リスト(改行付き!)を格納します。

say uc(++$a[0])大文字の最初の文字を1ずつシフトして出力します。プレフィックス++を使用すると、perlで文字をインクリメントできることがわかります。これはミューテーターofcです。

2*ord($a[$_+1])-ord($a[$_])+!$_xで文字を取得し、差+(x-(x-1))を追加するように求められます。まあそれは2倍です-(x-1)。ただし、最初の文字を変更しました!だから私はそのエラーを修正しなければならないので、+!$_、、位置0で1つを減算しすぎた場合に修正します(!$ _がundefでない場合のみ)。次にuc chr、計算されたASCII値から大文字を取得します。

map{ ... } $#a-2 - $#aは、最後の配列要素にアクセスする位置です。私が欲しいものを追加している$#a-1ので、入力からの改行は無視する必要があるため、これは$#a-2です。

これは最初の文字と連結され、完了です:)


これには、アルファベットを囲むオフセットとアルファベット以外の文字の処理に問題があるようです。 オンラインでお試しください!
Xcali

1

Perl 5の -F73の 77 74バイト

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

オンラインでお試しください!


これは、文字以外を完全にスキップするわけではありません。それらは変換されません。私が考えるHello, World!になる必要がありIBSLR, EGUFV!ません、IBSLR, XGUFV!
タイタス

あなたが正しい。前の文字を保持するために、さらに4バイトで修正しました。
Xcali

1

PHP、106 98バイト

それはかなり厄介です... base_convertそれほど長くなかった場合(またはctype_alpha)...
しかし、私はそれを100未満にした。満足。

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

でパイプとして実行する-nR、オンラインで試してください


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.