シーザーシフト


22

シーザーシフトは、おそらく私たちがよく知っているものです。

(宿題としてもしているかもしれません。もしそうなら、これらの答えをコピーしないでください。先生はほとんど間違いなくここの答えのようなものを望んでいません。)

そうでない場合に備えて、シーザーシフトは非常に単純な暗号形式です。暗号化される文字列と整数を取ります。次に、文字列内のすべてのアルファベット文字について、次の変換を実行します。

  1. アルファベットでのキャラクターの位置を調べます(0ベース)。
  2. 最初に受け取った整数をその数に追加します。
  3. 数が25より大きい間、26を引きます。
  4. アルファベットの位置を確認します。

残りのキャラクターはそのままにしておきます。

大文字のない英語とは何ですか?

例:

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

仮定

  • 印刷可能なASCII文字を受け取る場合があります
  • 入力数は負の値にすることができ、常に-128より大きく128未満になります(-128<x<128
  • 大文字と非大文字を可逆的にエンコードできる必要があります。
  • 関数やスニペットだけでなく、完全なプログラムを作成する必要があります
  • STDINまたは最も近い代替から入力を取得します
  • 入力の形式を選択できます。これを回答に明記してください
  • シフトする必要がある文字はASCIIコードポイント0x41 - 0x5Aおよび0x61-0x7A-大文字と小文字

    • 大文字は大文字のままにしてください
    • 小文字は小文字のままにしてください
    • この範囲外の文字はそのままにしておく必要があります
  • このチャレンジに注意してください、文字列を暗号化するだけで、自動的に解決する必要はありません(ただし、与える-xと暗号が逆になります)


これはカタログであるため、この課題の後に作成された言語は競合できます。提出物をテストできるように、通訳が必要であることに注意してください。以前に実装されていない言語用にこのインタープリターを自分で作成することは許可されています(さらに推奨されています)。それ以外は、すべての標準ルールに従う必要があります。ほとんどの言語での提出物は、適切な既存のエンコーディング(通常はUTF-8)でバイト単位で記録されます。

カタログ

この投稿の下部にあるスタックスニペットは、a)言語ごとの最短ソリューションのリストとして、b)全体的なリーダーボードとして、回答からカタログを生成します。

回答が表示されるようにするには、次のマークダウンテンプレートを使用して、見出しから回答を開始してください。

## Language Name, N bytes

N提出物のサイズはどこですか。スコアを改善する場合、古いスコアを打つことで見出しに残すことができます。例えば:

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

ヘッダーに複数の数字を含める場合(たとえば、スコアが2つのファイルの合計であるか、インタープリターフラグペナルティーを個別にリストする場合)、実際のスコアがヘッダーの最後の数字であることを確認します。

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

言語名をリンクにして、スニペットに表示することもできます。

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


8
「宿題としてそれをしているかもしれません。もしそうなら、これらの答えをコピーしないでください。先生はほとんど間違いなく答えのようなものを望んでいません。」私は...あなたは教師に厄介な文字やショートカットの90バイトのその場しのぎを渡したらどうなるのだろうか
ASCIIThenANSI

回答:


9

Pyth、13バイト

uXGH.<HQrBG1z

テストスイート

基本的に、シーザーシフトする2つの文字列、小文字と大文字のアルファベットから始めます。これらの両方を含むリストは、によって生成されrBG1、大文字で分岐します。次に、入力文字列から始めて、最初に小文字を変換し、次に大文字を適切なシフトで変換して、このリストを縮小します。


非常に素晴らしい、私は分岐が存在することを忘れ続けています...:P
FryAmTheEggman


5

Bash + bsd-gamesパッケージ、21

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

ビルトインFTW!ほとんどMathematicaのように感じます。ただし、Pythの回答はまだ短くなっています。

STDINから読み取った入力文字列とコマンドラインからの整数。例えば:

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

または、組み込みが気に入らない場合:

Bash + coreutils、63

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

coreutilsバージョンは-127および/または127では動作しないように思えますか?
ニール

@ニールはい。良いキャッチ。一定。
デジタル外傷

5

JavaScriptの(ES6)、122の 118 114 111バイト

alert((p=prompt)().replace(/[a-z]/gi,c=>String.fromCharCode((x=c.charCodeAt(),a=x&96,x-a+n+129)%26-~a),n=+p()))

@Neilのおかげで4バイト節約

説明

最初のプロンプトは入力文字列を受け取ります。2番目は、各文字をシフトする数字です。

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
非常に素晴らしい!ただし、すべての入力で機能するわけではありません。試してください"abcdefg", -26。これは、式をに変更することで修正できます(x-a+n+130)%26
ETHproductions

@ETHproductionsキャッチしてくれてありがとう!
user81655

「あなたは完全なプログラムだけでなく、機能やスニペットを作成しなければなりません」
LegionMammal978

@ LegionMammal978ありがとう、気づかなかった。
user81655

DOESのa=x&96,(x-a+n+129)%26+a+1ヘルプ?
ニール

3

CJam、34 22 21 20バイト

1バイトを節約してくれたFryAmTheEggmanに感謝します。

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

ここでテストしてください。

入力は、最初の行でシフトされ、2番目の行でシフトされる文字列です。

説明

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 '[,_el^はデニスからのヒントです。私はあなたが何を意味するのか分かりませんfが、それはかなり普通の使い方のように見えますか?
マーティンエンダー

十分なCJamの答えを読んでいないだけだと思います。
FryAmTheEggman

@FryAmTheEggman、実際には、まったく必要ありません@。:)
マーティンエンダー

2

Java、249バイト

これは私が手に入れることができる限り短いものです。stdinからの読み取りは、大量のバイトを消費します。コマンドライン引数を使用したソリューションは著しく短くなりましたが、このタスクでは入力に標準入力を指定しました。

入力形式は、最初に文字列で、その後に新しい行のシフト番号が続きます。

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

コマンドライン引数を使用すると、このソリューションは188バイトのみです。入力は、最初の引数としての文字列と2番目の引数としてのシフトです。

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バイト

コード

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

食べない

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
}

このプログラムは、STDINからユーザー入力を受け取り、最初に整数シフター、次に文字列を文字ごとに受け取ります。


1

Perl、81バイト

-pフラグの場合は+1 )

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

まだゴルフに取り組んでいます...

テスト:

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バイト

まだゴルフができるかどうかわかりません。

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

それはかなり読みにくいので、ここに未改変版があります:

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)

入力に関して:2つの引数が必要です。最初の引数は文字列で、2番目の引数は整数(シフト量)でなければなりません。例(ファイルの名前はcsr.py):

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

注:2番目の例では、エスケープ文字""が必要です


1

Python 2、118 116バイト

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)

if/elseインスタンス(codegolf.stackexchange.com/a/62/36885)の代わりにリストを使用することもできます。たとえばprint''.join([[c,chr((ord(c)-97+n)%26+97)]['~'<c<'{'],chr((ord(c)-65+n)%26+65)]['@'<c<'[']for c in s)、少し短く、同じように動作するはずです。(以前のようにチルダをバック
ティックに

1

Mathematica、117バイト

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

文字列を取得し、その後に改行、シフト要素が続きます。まだゴルフできるかもしれない...


1

Perl 6、73 + 1 = 74バイト

$ perl6 -pe 's:g:i/<[a..z]>/{chr ((my$o=ord ~$/)-(my$a=$o+&96+1)+BEGIN get%26)%26+$a}/' # 73+1

入力の最初の行は、文字を上にシフトする文字数です。

使用法:

$ 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バイト

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

使用法:

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

0

k4、80バイト

プログラムはシフト番号をコマンドライン引数として受け入れ、標準入力からテキストを読み取ります。

技術的な制約により、負のシフトはハイフンマイナスではなくアンダースコアでエンコードする必要があります。(このエンコードを解釈するためのパーサーがなければ、ソリューションは64バイトになります。)

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

実行された例は次のとおりです。

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

そして、エンコードとデコードの両方を検証する愚かな小さなテストハーネスがあります。(これはzsh; for bashまたはkshforループのインデックスを((i=0;i<5;i++))。に変更します。1ベースの配列、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
% 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.