シーザー等価


24

対応する文字間の距離(カウントアップ)が同じ場合、2つの文字列は「Caesarに相当」です。はい、私はこの用語を作りました。以下に例を示します。

「Abc」と「Cde」は同等であるため、

distance from a-c == 2
distance from b-d == 2
distance from c-e == 2

大文字小文字を区別しても違いはありません。

「Hello」と「World」はCaesarで同等ではありません

distance from h-w == 15
distance from e-o == 10
distance from l-r == 6
distance from l-l == 0
distance from o-d == 15

「Abcd」と「Yzab」はCaesarと同等です

distance from a-y = 24
distance from b-z = 24
distance from c-a = 24 (it wraps around)
distance from d-b = 24

STDINから2つの文字列を取得し、Caesarと同等の場合は真実の値を出力し、そうでない場合は偽の値を出力する完全なプログラムを作成する必要があります。

有効な入力

  • 大文字と小文字は区別されないため、回答で指定されている限り、プログラムがすべて小文字、すべて大文字、または任意の組み合わせの入力を必要とする場合は許容できます。

  • 入力にはスペースや句読点は含まれません。

  • 入力は同じ長さになります。


8
コマンドライン引数として入力できるようになったら良かったでしょう。Cソリューションを作成するつもりでしたが、stdinからの読み取りには、かなり長いコードが必要です。特に、事前に最大長がない場合は特にそうです。
レトコラディ

@RetoKoradiどうして?Cは簡潔であることで正確に知られていないため、とにかく勝つことはないでしょう。
DJMcMayhem

確かに、Cが絶対的な勝利のチャンスがあるとは思わない。せいぜい、「本物の」プログラミング言語を使用するソリューションと比較します。しかし、それでも、他の言語は、特に文字列処理を伴う場合は、よりコンパクトになる傾向があります。
レトコラディ

4
質問リストでこれを見るたびに、答えと同じくらい多くの賛成票があります。
アレックスA.

1
@AlexA。あなたがそれを指摘するまで、私は賛成票率に何の注意も払っていませんでした。今、私が気づいたすべてです。
DJMcMayhem

回答:


10

Pyth、9バイト

}wm=.rzGG

2つの文字列は、改行で区切られた小文字である必要があります。

デモンストレーション。

使い方:

.rPythのロータリー翻訳機能です。最初の引数の各要素を、2番目の引数の最初の出現から2番目の引数の次のエントリにマップします。この場合、2番目の引数はG小文字のアルファベットであるため、これは1のシーザーシフトに相当します。

=関数の前にを置くと、その場所に配置されます。したがって、=.rzGのCaesarシフトをz1に割り当てzます。zは、Pythの入力の最初の行に初期化されることに注意してください。

この式はマップ内で使用されます。m=.rzGGz、の各要素に対して1回ずつ、この変換を26回適用しG、結果をリストに保存します。これにより、可能なすべてのシーザーシフトのリストが得られzます。

最後に、}w入力の次の行がそのリストにあるかどうかを確認します。


14

CJam、17 12 11バイト

デニスが保存した1バイト。

ll.m26f%)-!

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

最初の文字列が小文字で、2番目の文字列が大文字であると想定します。1Caesarに相当する文字列などを印刷し0ます。

説明

ll           e# Read two lines of input.
  .m         e# Take the differences of corresponding characters.
    26f%     e# Take the differences modulo 26.
        )-   e# Remove all copies of the last difference from the array. This will 
             e# yield an empty array if and only if all differences are the same.
          !  e# Logical NOT, which yields 1 for an empty array and 0 otherwise.

小文字の最初の文字列と大文字の2番目の文字列が必要な理由は、差が常に正であることを確認するためです。それ以外の場合、モジュロを取ると負の値が返される可能性があり、Caesarに相当する文字列であっても必ずしも一意ではありません。


1
最初の単語を小文字にし、2番目の単語を大文字にする必要がある場合26f%、1バイトを節約するために使用できます。
デニス

シェルの規則(stackoverflow.com/questions/2933843/…)を使用して、Pythの回答に近づけることができます。
VicAche

1
@VicAche 受け入れられている慣習は、あなたの言語がそれを解釈するどんな方法でも真実と偽を解釈することです。また、削除した場合、!0または1ではなく、空または空でない配列になります。
マーティンエンダー

9

Python2、68 67 70 69のバイト

print len({(ord(y)-ord(x))%26for x,y in zip(*raw_input().split())})<2

python3、67の 66バイト

print(len({(ord(y)-ord(x))%26for x,y in zip(*input().split())})<2)

アンゴルフするのは少し難しいので、ピースを説明するだけです。

  • zip(*raw_input().split())入力を受け取り、単語が空白で区切られていると仮定して、2つの単語のリストに分割します。その後zip*演算子を使用して、各単語が関数のパラメーターとして渡されます。このzip関数は、同じ位置にある文字に対して、文字ペアのリストを作成します。
  • (ord(y)-ord(x))%26for x,y in ... これは、2つの文字のリストを、それらの文字間の距離のジェネレーター式に変換するだけです。
  • {...} この式をセットに縮小し、本質的に重複をスローします
  • len(...)<2 セットにアイテムが1つしか残っていないかどうかをチェックします(空の文字列の場合は0)。これは、すべての文字の距離が本質的に同じであることを意味します。
  • print その値を出力します

xnorのおかげで、私set(...)を置き換えることができ{...}、前のスペースforは不要です。またためJosayのおかげ<=1<2最適化。


大体同じ分で投稿された私のソリューションとかなり似ています。あなたは私より賢く入力を行ってきましたが、<=1「<2」に減らすことができます。
-SylvainD

1
として{...}ではなく、直接セット内包を行うことができますset((...))。コードは実際に結果を出力する必要があります。
xnor

@KillianDS デフォルトのルールでは、STDOUTへの印刷またはリターン(REPL評価ではない)が必要です。ここではOPが印刷を指定します。それ以外の場合、一般的な最短の方法はlambda、書き込みprintまたはでの保存に使用することreturnです。
xnor

1
ちなみに、前のスペースはありませんfor。Python lexerは正しく分割されます26for
xnor

5

APL(15)

1=≢∪26|-⌿⎕A⍳↑⍞⍞

文字を大文字にする必要があり、次のように1またはのいずれかを出力します0

      1=≢∪26|-⌿⎕A⍳↑⍞⍞
ABCD
YZAB
1

      1=≢∪26|-⌿⎕A⍳↑⍞⍞
HELLO
WORLD
0

説明:

  • ↑⍞⍞:キーボードから2行を読み取り、N×2マトリックスに文字を配置します。
  • ⎕A⍳:各文字について、それが出現する位置⎕A(大文字のアルファベット)を見つけます。
  • -⌿:各列について、最初の値から2番目の値を引きます
  • 26|:これらの各番号のmod-26を取得します。
  • 文字列がCaesarに相当する場合、このリストのすべての数字は等しいため、次のようになります。
  • ≢∪:リスト内の一意の値の数を見つける
  • 1=:それと比較してください1

私は決してAPLに
賛成票を投じる

@AlexA .: Dyalog APL 14を使用しています。RaspberryPiをお持ちの場合は無料です。学生にとっては無料です。それ以外の場合は、未登録のバージョンをダウンロードできます。これはナグウェアですが、それ以外は実際のバージョンと機能的に同じです。ちなみに、dyalog.com TryAPLはこれに基づいています。
マリヌス

Dyalog対GNU APL、ngn / apl、APLXについてのあなたの考えを聞いてみたいと思いますが、コメントは実際にはそのような議論の場ではありません。;)
アレックスA.

3

J、19バイト

1=[:#@~.26|-&(3&u:)

同じ位置にある文字の大文字と小文字は同じにする必要があります。

両方の入力文字列をコードポイント表現に変換した後、2つの配列の差のモジュロ26のナブの長さと&(3&u:)比較1します。すべてのシーザー距離が同じであれば、こぶができます。#~.26|-1

使用法:

   'abcd' (1=[:#@~.26|-&(3&u:)) 'yzab'
1

こちらからオンラインでお試しください。


3

ジュリア、91 87 83バイト

a=readline()
b=readline()
show(length(Set([mod(a[i]-b[i],26)for i=1:length(a)]))<2)

Ungolfed +説明:

# Read two strings from STDIN
a = readline()
b = readline()

# Get the absolute difference mod 26 of the character values in the strings
x = [mod(a[i] - b[i], 26) for i = 1:length(a)]

# Construct a set consisting of the elements of x. If the set has only a
# single element, the strings are Caesar equivalent. This will print a
# boolean value to STDOUT.
show(length(Set(x)) < 2)

これは、Juliaの文字列を文字配列として扱うことができ、文字値に対して算術演算を実行できるという事実を利用しています。入力文字列には、各位置の大文字小文字が文字列間で一致する限り、任意の大文字小文字を混在させることができます。


3

C99、バグ   101 92バイト付き 92バイト

  r,i;main(z,a)char**a;{for(;z=a[2][++i];)r|=(a[1][i]-z+*a[2]-*a[1]+52)%26;putchar(49-!!r);}

とても簡単です。単語がそれぞれ最初と2番目の引数として来ると仮定します。でコンパイル-std=c99


これは、2番目のサンプル入力に対して間違った結果を与えます。
レトコラディ

あなたは正しい、私はそれを逃した。一定。
rr-

3

Javascript(ES7ドラフト)、87バイト

入力が同じ大文字である必要があります。

(p=prompt)(![z=(a[c='charCodeAt'](i)-b[c](i)+26)%26 for(i in b=p(a=p()))].some(x=>x^z))


2

CJam、13バイト

{r(fm26f%}2*=

各単語の最初の文字は大文字で、その他は小文字である必要があります。

ここで試してみてください。(Firefoxはこちら。)

残念なことに、APLバリアントは文字演算をサポートしていません...

説明

{
    r       e# Read a word.
    (f-     e# Return each character value minus the first character.
    26f%    e# Mod 26.
}2*         e# Repeat 2 times.
=           e# Check if they are equal.

2

Perl、80

編集:失敗した最適化がゴルフのコードに滑り込んだ。これで、非ゴルフバージョンと一致します。(ただし、バイト数は正確でした。)

@a=unpack"W*",<>;for(<>=~/./g){$n=ord()-shift@a;$p=!$c++||$p&&$n==$o;$o=$n}say$p

Perlバージョン5.10(perl -M5.10.0またはperl -E …)で実行しますsay()。わずかに拡張されたバージョン:

@a=unpack"W*",<>;             # read first string, split and convert to numbers

for(<>=~/./g){                # reads the second string and splits it
   $n=ord()-shift@a;          # convert next character of second string and compare
   $p= !$c++ || $p && $n==$o; # compare differences (special case for first char)
   $o=$n
}

say $p

1文字列がCaesarに相当する場合、コードは出力(Perlでは真)、そうでない場合は空の文字列(Perlでは偽)を出力します。これがあまりにも緩い解釈である場合、に2バイトを追加する必要がsay$p+0あります。1または0

入力間で大文字と小文字を区別する必要があります。


上記の質問に対するコメントに基づいて、コマンドライン引数として入力を受け取ることもできます。を使用-iして2番目の文字列を取得すると、変数に格納されます$^I。また、コマンドラインで実行するときの-E代わりにを使用すると-esay無料で使用できるため、バイトを追加せずに使用できます。これを実行してみてください:トリックでperl -iteststring -E'say$^I'これを短くできるかもしれません-i
hmatt1

@chilemagicに感謝します。-iトリックはきちんとしています(そして、私はそれを知りませんでした!)。この場合、私$^Iはそれよりも長いので、それが役立つとは思わない<>
xebtl

@chilemagicああ、この議論では、-M5.10.0とにかくバイト数を数えませんでした。(ただし-E、編集でスイッチについて言及しました)
-xebtl

2

Matlab、49 48バイト

これは本当に速いものでした。悲しいことに、stdinから文字列を取得するのは非常に高価です。

x=@()input('','s');sum(diff(mod(x()-x(),26)))==0

すべてではないにしてもほとんどの回答と同様に、大文字と小文字が区別されることに注意してください。

編集:匿名関数を定義することにより、1バイト削りました!



2

C、97バイト

#define D (*a[2]++-*a[1]+++26)%26
d,r;main(int c,char**a){for(d=D;*a[1];r|=d-D);puts(r?"N":"Y");}

1
わーい!バランスが回復しました!
DJMcMayhem

次のように、パラメーターの外部の型を再利用dして宣言すると、4文字を保存できますad,r;main(int c,char**a){r;main(d,a)char**a;{
rr-

1

Scala、57バイト

(readLine zip readLine map(x=>x._1-x._2%26)toSet).size==1

他のものより少し長く、本質的に同等ですが、言語のさまざまなスタイルです!

私もこのバージョン(56バイト)を持っています:

(readLine zip readLine map(_._1-x$1._2%26)toSet).size==1

しかし、x $ 1の動作が偶然なのか、それとも設計によるのかはわかりません...


1
それは本当に奇妙です、どのように定義されるx$1ことなく動作しxますか?
ダン・ゲッツ

@DanGetz私はそれがコンパイラーだとかなり確信しています。私はそれについてスタックオーバーフローに関する質問をするかもしれません:D
その他

1

Python 2、80バイト

スペースで区切られたstdinから同様のケースの2つの文字列を取得します。

s,t=raw_input().split();print len(set((ord(c)-ord(d))%26 for c,d in zip(s,t)))<2

次のテストケースでテスト済み:

tests = [
    ("abc", "abc", True),
    ("abcd", "abc", False),
    ("abc", "cde", True),
    ("Abc", "Cde", True),
    ("abc", "deg", False),
    ("Hello", "World", False),
    ("Abcd", "Yzab", True),
    ("", "", True)
]

for s, t, v in tests:
    if len(s) == len(t): # I didn't read that at first
        assert v == (len(set((ord(c) - ord(d)) % 26 for c, d in zip(s, t))) < 2)

1

Pythonの2 - 241 237 188 147のバイト

スペースで区切られた引用符で囲まれた小文字の文字列として入力を受け取ります。より良い方法が必要です。

s=[[ord(x)for x in y]for y in input().split()];v=[];v=[v+[(s[1][i]-s[0][i])%26]for i in xrange(0,len(s[0]))];v=sum(v,[]);print sum(v)//v[0]==len(v)

Ungolfed(260奇数バイト)

strs = [[ord(x) for x in y] for y in raw_input().split()]
vals = []
for i in xrange(0, len(strs[0])):
if strs[0][i]<strs[1][i]:
    vals += [strs[1][i]-strs[0][i]]
else:
    vals += [26-(strs[0][i]-strs[1][i])]
return sum(vals)//vals[0] == len(vals)

すべての変数を1文字長にし、大量のバイトを節約できると確信しています。また"、入力に4 秒追加されると予想されるため、スコアに4を追加する必要があります。

@Reticality変数を短くしなかったとは信じられません。アマチュアの動き。適切に説明しなかったため、バイトカウントに2を追加しました。入力は「abc cde」のように機能します。
ケイド

1

R、83 84

他のソリューションとほぼ同じです。文字列を整数のベクトルに変換します。ベクトルの差を26でModします。長さが1であることを確認して、リスト全体で一意にします。各文字列の対応する文字で大文字と小文字が同じであると予想されます。

length(unique(((S=strtoi)((R=charToRaw)((I=readline)()),16L)-S(R(I()),16L))%%26))<2

2つの文字列が入力されるのを待ちます

> length(unique(((S=strtoi)((R=charToRaw)((I=readline)()),16L)-S(R(I()),16L))%%26))<2
abcdefghijklmnopqrstuvwxyz
opqrstuvwxyzabcdefghijklmn
[1] TRUE
> length(unique(((S=strtoi)((R=charToRaw)((I=readline)()),16L)-S(R(I()),16L))%%26))<2
Hello
World
[1] FALSE
> length(unique(((S=strtoi)((R=charToRaw)((I=readline)()),16L)-S(R(I()),16L))%%26))<2
Bob
Nan
[1] TRUE
>

<2ではなくを使用してバイトを保存できます==1
アレックスA.

あなただけの出力で3つのバイトを救うことができる10

@AlexA。アレックス、私はそれを逃しました...そして今、私はそれを逃しています:)
MickyT

@Reticality:どうやって?
アレックスA.

@Reticality残念ながら、1または1を超える値が返されます。
MickyT

1

Matlab / Octave、53 52

x=@()input('','s');isscalar(unique(mod(x()-x(),26)))

入力はすべて同じ場合である必要があります。

悲しいことに、Matlabはユーザー入力にあまり適していません。匿名ハンドルとして、これはわずか35バイトです。

@(a,b)isscalar(unique(mod(a-b,26)))

Matlabは文字列の文字を数字のベクトルとして扱います。減算を行うと、その差が得uniqueられ、そのベクトルが一意の値のみを含むベクトルに変換されます。数字が1つしかない場合、単語はcaeserと同等であり、isscalarは1を返します。それ以外の場合、0を返します。


ああ!別のMatlabエントリー!自分自身に答えた後にだけ答えを見ました。
Oebele

x = @()input( ''、 's');を定義することで1バイトを節約できることがわかりました。
Oebele

@Oebeleありがとう!Matlabでゴルフの問題をもっと試してみようと思っています。実際、かなり楽しいことがわかりました。
FryAmTheEggman

うん、そうです。多くの問題については、マトリックスベースのものと非常に簡潔にすることができます。Octaveにはもう少し自由な構文があり、インライン変数の定義など、さらに数バイトも節約できる場合があります。
-Oebele

1

bash、71 48

「標準」のUnixプログラムを使用する caesar(6)ます。

新しいバージョン(@DigitalTraumaからの多くの助けを借りて):

read a b;seq -f"caesar %g <<<$a" 26|bash|grep $b
  • 入力はスペースで区切って同じ行にある必要があります
  • 入力間で大文字と小文字を区別する必要があります。
  • 1trueの場合は印刷し、falseの場合は印刷しません。

コマンドライン引数による入力が許可されている場合、39バイトに短縮できます

 seq -f"caesar %g <<<$1" 26|bash|grep $2

レコードの古いバージョン:

 read a b;for i in `seq 26`;do [ `echo $a|caesar $i` = $b ]&&echo 1;done

私のカウントでは48バイト:read a b;seq -f"caesar %g <<<$a" 26|bash|grep $b結果は$?組み込み変数にあります。標準シェルのセマンティクスによると、0 == FALSEおよび1 == TRUEです。
デジタル外傷

@DigitalTraumaこれらは気の利いたアイデアです!私は特にseq -f | bashビットが好きです。$?私のチャレンジを読むと結果は有効ではありませんが、私のコードと同じように、あなたのものはfalseに対して何も出力せず、trueに対して何かを出力します(2つの空の入力文字列の境界線の場合を除く)。とにかく、私の答えでこれをすべて使用するのはごまかしのように感じるでしょう。たぶん、あなたはあなた自身を提出するべきです。
xebtl

心配しないでください-私はあなたが使用するためのゴルフのヒントを提供しています。それらを使用したい場合、私はすでにそうしていたでしょう:)。truthy / falseyの事に関しては、私はあなたの指定した言語であるか、真と偽であるためにそれを解釈する傾向がある-試み[ 0 == 0 ] ; echo $?[ 0 == 1 ] ; echo $?
デジタルトラウマ

1

> <>(魚)、50バイト

i:3b*(?v88+0.;n1<
0)?vc1.>~ri-&l?!^i-&:&-2d*%
;n0<

同じ位置にある文字は、大文字と小文字が同じであることを期待します。

説明

  • i:3b*(?v88+0.ループジャンプを提供しながら、スタックに最初の単語を読み込みます
  • ~ri-&~スタックから分離スペースを削除し、スタックを反転しr(最初の文字が上になります)、2番目の単語の最初の文字を読み取りi、最初の単語の最初の文字からのオフセットを計算-し、registerに格納します&
  • l?!^i-&:&-2d*%0)?vスタックの一番上にある最初の単語の対応する文字からそれを減算する2番目の単語の次のすべての文字を読み取り&:&-、レジスタに格納されたオフセットを減算し、結果が0 mod 26かどうかをチェックします2d*%。そうでない場合は0を出力して終了します0n;c1.ループジャンプを提供します。
  • 2番目の単語の終わりに達すると、プログラムは1を出力して終了します1n;

0

KDB(Q)、35バイト

{0=sum(1_-':)mod[;26](-)."i"$(x;y)}

説明

                         "i"$(x;y)      / convert to ascii decimal
                     (-).               / get differences
             mod[;26]                   / mod 26
      (1_-':)                           / difference between the differences
 0=sum                                  / sum should be 0 if equivalent
{                                 }     / lambda

テスト

q){0=sum(1_-':)mod[;26](-)."i"$(x;y)}["abcd";"yzab"]
1b

0

Java 281

import java.util.*;enum C{E;Scanner s=new Scanner(System.in);public static void main(String[]z){char[]u=E.n(),v=E.n();int i=0,d=(u[0]-v[0]+26)%26;boolean e=true;for(;++i<u.length;)e&=d==(u[i]-v[i]+26)%26;System.out.print(e);}char[]n(){return s.next().toUpperCase().toCharArray();}}

展開された:

import java.util.*;
enum Caesar{
    Equivalence;
    Scanner input=new Scanner(System.in);
    public static void main(String[]z){
        char[]firstString=Equivalence.nextInput(),secondString=Equivalence.nextInput();
        int index=0,difference=(firstString[0]-secondString[0]+26)%26;
        boolean isEqual=true;
        for(;++index<firstString.length;)
            isEqual&=difference==(firstString[index]-secondString[index]+26)%26;
        System.out.print(isEqual);
    }
    char[]nextInput(){
        return input.next().toUpperCase().toCharArray();
    }
}

すべてを大文字に変換するのをやめれば14バイト節約できますが、そのままにしておいた方が完全だと思います。


0

ゼリー、5バイト

Oạ/ċ2

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

同等の場合は正の整数を出力し、それ以外の場合は0を出力します

使い方

Oạ/ċ2 - Main link. Argument A (a list of strings)  e.g. ["abc", "cde"]

O     - Ordinal. Cast to code point                     [[97, 98, 99], [99, 100, 101]]
  /   - Reduce the list by...
 ạ    -   absolute difference                           [2, 2, 2]
   ċ2 - Count the number of 2s in the list              3
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.