凯撒等效


24

如果相应字符之间的距离(向上计数)相同,则两个字符串为“凯撒等效项”。是的,我补了这个学期。这是一个例子:

“ 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”等同于凯撒,因为

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

您必须编写一个完整的程序,该程序使用来自STDIN的两个字符串,如果它们等效于凯撒,则输出一个真实值,如果不相同,则输出一个虚假值。

有效输入

  • 由于大小写无关紧要,因此只要您的程序中要求输入全部为小写字母,全部为大写字母或所需的任意组合,就可以接受。

  • 输入将没有空格或标点符号。

  • 输入将具有相同的长度。


8
允许将输入作为命令行参数会很好。我打算编写一个C解决方案,但是从stdin读取需要相当长的代码,尤其是如果您没有最大长度的话。
Reto Koradi 2015年

@RetoKoradi为什么不呢?无论如何,它可能不会赢,因为C并不以简洁而著称。
DJMcMayhem

是的,我怀疑C会不会有绝对胜利的机会。充其量,我将其与使用“真实”;)编程语言的解决方案进行比较。但是即使在那儿,其他语言也趋向于更紧凑,特别是在涉及字符串处理的情况下。
Reto Koradi 2015年

4
每次我在问题列表中看到它时,它的投票数和答案数一样多。
Alex A.

1
@AlexA。除非您指出,否则我不会关注投票赞成率。现在,我注意到了。
DJMcMayhem

Answers:


10

Pyth,9个字节

}wm=.rzGG

这两个字符串应以小写字母,换行符分隔。

示范。

怎么运行的:

.r是Pyth的旋转翻译功能。它将第一个自变量中的每个元素从第二个自变量中的第一次出现映射到第二个自变量中的下一个条目。在这种情况下,第二个参数是G小写字母,所以这相当于凯撒偏移量为1。

=在函数前面放置一个使其就位。因此,=.rzG将凯撒(Caesar)偏移量指定为z1 z。请注意,它z已初始化为Pyth中的第一行输入。

该表达式在地图内部使用。m=.rzGG将此转换应用z26次,对的每个元素一次G,并将结果保存在列表中。这给出了所有可能的Caesar移位的列表z

最后,}w检查输入的下一行是否在该列表中。


14

CJam,17 12 11字节

Dennis保存了1个字节。

ll.m26f%)-!

在这里测试。

期望第一个字符串为小写,第二个为大写。打印1与凯撒等效的字符串,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.

我们要求第一个字符串小写,第二个字符串大写的原因是为了确保差异始终为正。否则,取模可能会返回负数,即使对于凯撒等效字符串也不一定是唯一的。


1
如果您要求第一个单词为小写字母,第二个单词为大写字母,则可以26f%保存一个字节。
丹尼斯

您可以使用shell约定(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())接受输入,将其拆分为两个单词的列表,并假设单词之间用空格隔开。之后,zip使用*运算符将每个单词作为函数的参数传递。该zip函数将为相同位置的字母创建字母对列表。
  • (ord(y)-ord(x))%26for x,y in ... 这只是将2个字母的列表转换为这些字母之间的距离的生成器表达式。
  • {...} 将这个表达式简化为一组,本质上排除重复项
  • len(...)<2 检查集合中是否只剩下一项(对于空字符串,则为0),这实际上意味着所有字母的距离都相同。
  • print 输出该值

感谢xnor提醒我set(...)可以替换为,{...}并且for不需要空格。同时还要感谢Josay的<=1to <2优化。


与我在同一分钟内发布的解决方案非常相似。您比我更聪明地进行输入,但是您可以减少<=1到“ <2”。
SylvainD

1
您可以直接设置理解,{...}而不是set((...))。您的代码需要实际打印结果。
xnor 2015年

@KillianDS 默认规则要求打印到STDOUT或返回(不是REPL评估),这里是OP指定的打印。否则,一般最短的方法是使用lambda节省编写时间printreturn
xnor

1
顺便说一句,您没有前面的空间for;Python词法分析器正确拆分26for
xnor

5

APL(15)

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

它需要将字母大写,并打印10,如下所示:

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

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

说明:

  • ↑⍞⍞:从键盘读取两行,并将字符排列在N×2矩阵中。
  • ⎕A⍳:对于每个字符,找到它出现在的位置⎕A(大写字母)。
  • -⌿:对于每一列,从第一个值中减去第二个值
  • 26|:对每个数字取mod-26。
  • 如果字符串与凯撒等效,则此列表中的所有数字现在都相等,因此:
  • ≢∪:在列表中找到唯一值的数量
  • 1=:与1

我永远不会
反对

@AlexA .:我使用的是Dyalog APL14。如果您有Raspberry Pi,则它是免费的;对于学生来说,它也是免费的;否则,您可以下载未注册的版本,该版本是nagware,但在功能上与真实版本相同。顺便 说一下,dyalog.com TryAPL基于此。
marinus

我很想听听您对Dyalog与GNU APL,ngn / apl和APLX的看法,尽管评论实际上并不是进行此类讨论的地方。;)
Alex A.

3

J,19个字节

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

同一位置的字母应具有相同的大小写。

在将两个输入字符串转换为它们的代码点表示形式之后,&(3&u:)我们将比较两个数组之差的模26 的小节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)

取消+说明:

# 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,92 个字节,错误   101 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);}

非常简单;假设单词分别作为第一和第二自变量。与编译-std=c99


这为第二个样本输入给出了错误的结果。
Reto Koradi

您说的没错,我想念它。固定。
rr-

3

Javascript(ES7 Draft),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.0perl -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如果字符串等效于凯撒,则代码输出(在Perl中为真),如果不是,则输出为空字符串(在Perl中为假)。如果这个解释太松散,我需要为添加2个字节say$p+0,打印10

输入之间的字符大小写必须匹配。


基于对以上问题的评论,您也可以将输入作为命令行参数。您可以使用-i第二个字符串,将其存储在变量中$^I。另外,在命令行运行时使用-E代替代替-e将使您say免费,因此您可以在不添加任何字节的情况下使用它。尝试运行此方法:perl -iteststring -E'say$^I'您可以通过-i技巧来缩短它。
hmatt1 2015年

谢谢@chilemagic,-i技巧很整洁(我不知道!)。在这种情况下,我认为它没有帮助,因为$^I它长于<>
xebtl 2015年

@chilemagic哦,按照此讨论-M5.10.0无论如何我没有计算字节数。(但我-E在编辑中提到了切换)
xebtl 2015年

2

Matlab,49 48字节

这是一个非常快的过程。可悲的是,从stdin获取字符串非常昂贵。

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

请注意,与大多数(如果不是全部)答案一样,它区分大小写。

编辑:通过定义一个匿名函数减少了一个字节!



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

如果重用da在这样的外部参数中声明的类型,则可以保存4个字符:d,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我相当确定这是一个编译器uke幸。我可能会问有关堆栈溢出的问题:D
其他

1

Python 2,80个字节

从标准输入中取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

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

非高尔夫(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 s。

@Reticality我不敢相信我没有缩短变量..业余移动。我没有正确解释,所以在字节数上加了2。输入的工作方式类似于“ abc cde”。
卡德2015年

1

R,83 84

与其他解决方案完全相同。将字符串转换为整数向量。将向量的差值修改26。在列表上进行唯一检查,检查长度是否为1。它期望每个字符串中相应字符的大小写相同。

length(unique(((S=strtoi)((R=charToRaw)((I=readline)()),16L)-S(R(I()),16L))%%26))<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
Alex A.

您可以通过仅输出10

@AlexA。谢谢亚历克斯,我错过了一个……而现在我错过了一个:)
MickyT 2015年

@Reticality:如何?
Alex A.

@Reticality不幸的是它将返回1或大于1。
MickyT

1

Matlab /八度,53 52

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

输入应全部使用相同的大小写。

可悲的是,Matlab在用户输入方面不是很好。作为匿名句柄,这可能只有35个字节:

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

Matlab将字符串的字符视为数字的向量。进行减法可以获取它们的差值,unique并将该向量转换为仅包含唯一值的向量。如果只有一个数字,则这些单词等同于caeser,并且isscalar返回1,否则将返回0。


哦! 另一个Matlab条目!回答自己后才看答案。
Oebele 2015年

刚刚发现,您可以通过定义x = @()input('','s')节省一个字节;
Oebele 2015年

@Oebele谢谢!我想我将开始在Matlab中尝试更多的高尔夫问题,我发现它实际上很有趣。
FryAmTheEggman 2015年

是的,是的。对于许多问题,其基于矩阵的内容可能非常简洁。Octave具有更多免费语法,有时还可以节省更多字节,例如内联变量定义。
Oebele 2015年

1

bash,71 48

使用“标准” Unix程序caesar(6)

新版本(在@DigitalTrauma的帮助下):

read a b;seq -f"caesar %g <<<$a" 26|bash|grep $b
  • 输入必须在同一行上,并用空格分隔
  • 输入之间的字符大小写必须匹配。
  • 打印1为true或不打印为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根据$?标准Shell语义,结果在内置变量中,其中0 == FALSE和1 == TRUE。
Digital Trauma 2015年

@DigitalTrauma那是一些不错的主意!我特别喜欢这个seq -f | bash位。$?根据我对挑战的阅读,结果无效,但是就像我的代码一样,您的输出不输出任何错误,而输出任何结果为true(在两个空输入字符串的临界情况下除外)。无论如何,将所有这些都用在我的答案中似乎是一种欺骗,也许您应该提交自己的。
xebtl

不用担心-我为您提供高尔夫球技巧。如果我想使用它们,我已经会这样做了:)。至于真假,我倾向于将其解释为您指定语言中的真假-尝试[ 0 == 0 ] ; echo $?[ 0 == 1 ] ; echo $?
Digital Trauma 2015年

1

> <>(鱼),50字节

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

期望处于相同位置的字母具有相同的大小写。

说明

  • i:3b*(?v通过88+0.提供循环跳转将第一个单词读入堆栈
  • ~ri-&~从堆栈中移除分隔空间,反转堆栈r(第一个字母将在顶部),读取第二个单词的第一个字母i,计算与第一个单词的第一个字母的偏移量,-并将其存储在寄存器中&
  • l?!^i-&:&-2d*%0)?v从堆栈顶部的第一个单词的对应字母中减去第二个单词的每个下一个字母,然后减去&:&-存储在寄存器中的偏移量,并检查结果是否为0 mod 26 2d*%。如果不是,则打印0并终止0n;c1.提供循环跳转。
  • 如果到达第二个单词的末尾,程序将打印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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.