Equivalência de César

24

Duas cadeias são "equivalentes a César" se a distância (contando) entre os caracteres correspondentes for a mesma. Sim, eu inventei esse termo. Aqui está um exemplo:

"Abc" e "Cde" são equivalentes porque

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

A capitalização não faz diferença.

"Olá" e "Mundo" não são equivalentes a César porque

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" e "Yzab" são equivalentes a César porque

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

Você deve escrever um programa completo que use duas strings de STDIN e imprima um valor verdadeiro, se eles forem equivalentes a César, e um valor falso, se não forem.

Entrada válida

  • Como a capitalização não importa, é aceitável que o seu programa exija que a entrada seja minúscula, maiúscula ou qualquer combinação desejada, desde que isso seja especificado em sua resposta.

  • A entrada não terá espaços ou pontuação.

  • As entradas terão o mesmo comprimento.

DJMcMayhem
fonte
8
Teria sido bom permitir a entrada como argumentos de linha de comando. Eu ia escrever uma solução em C, mas a leitura do stdin requer um código bastante longo, principalmente se você não tiver um comprimento máximo antes do tempo.
Reto Koradi
@RetoKoradi Por que não? Provavelmente não vai ganhar de qualquer maneira, já que C não é exatamente conhecido por ser conciso.
DJMcMayhem
Certo, duvido que C tenha a chance de uma vitória absoluta. Na melhor das hipóteses, eu comparo a soluções que usam "real";) linguagens de programação. Mas mesmo lá, outros idiomas tendem a ser mais compactos, principalmente se envolver processamento de cadeias.
Reto Koradi
4
Toda vez que vejo isso na lista de perguntas, ele tem exatamente o mesmo número de votos positivos que as respostas.
Alex A.
11
@AlexA. Eu não estava prestando atenção à proporção de votos para responder até que você apontou. Agora é tudo que eu aviso.
DJMcMayhem

Respostas:

10

Pitão, 9 bytes

}wm=.rzGG

As duas seqüências são esperadas em minúsculas, nova linha separada.

Demonstração.

Como funciona:

.ré a função de translação rotativa de Pyth. Ele mapeia cada elemento no primeiro argumento, desde sua primeira ocorrência no segundo argumento até a próxima entrada no segundo argumento. Nesse caso, o segundo argumento é Go alfabeto em minúsculas, portanto, isso é equivalente a um deslocamento de César de 1.

Colocar um =na frente da função a coloca no lugar. Assim, =.rzGatribui o deslocamento de César de zum a z. Observe que zé inicializado na primeira linha de entrada no Pyth.

Essa expressão é usada dentro de um mapa. m=.rzGGaplica essa transformação a z26 vezes, uma vez para cada elemento de G, e salva os resultados em uma lista. Isso fornece a lista de todos os turnos possíveis de César z.

Por fim, }wverifica se a próxima linha de entrada está nessa lista.

isaacg
fonte
14

CJam, 17 12 11 bytes

1 byte salvo por Dennis.

ll.m26f%)-!

Teste aqui.

Espera que a primeira string seja minúscula e a segunda maiúscula. Imprime 1para seqüências equivalentes a César e 0outras.

Explicação

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.

A razão pela qual exigimos a primeira string em minúscula e a segunda em maiúscula é garantir que a diferença seja sempre positiva. Caso contrário, tomar o módulo pode retornar algo negativo e não seria necessariamente único, mesmo para seqüências equivalentes a César.

Martin Ender
fonte
11
Se você precisar que a primeira palavra seja minúscula e a segunda em maiúscula, poderá usar 26f%para salvar um byte.
Dennis
Você pode usar a convenção de shell ( stackoverflow.com/questions/2933843/… ) para aproximá-la da resposta Pyth.
VicAche
11
@VicAche A convenção aceita é interpretar verdade e falsidade da maneira que seu idioma a interpretar. Além disso, se eu removesse o !eu não teria 0 ou 1, mas uma matriz vazia ou não vazia.
Martin Ender
9

Python2, 68 67 70 69 Bytes

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

Python3, 67 66 bytes

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

É um pouco difícil de ser jogado, então apenas explique as peças:

  • zip(*raw_input().split())pega a entrada, divide-a em uma lista de duas palavras, assumindo que as palavras sejam separadas por espaços em branco. Depois disso, cada palavra é passada como parâmetro da zipfunção, pelo uso do *operador. A zipfunção criará uma lista de pares de letras, para letras na mesma posição.
  • (ord(y)-ord(x))%26for x,y in ... Isso apenas transforma a lista de 2 letras em uma expressão geradora das distâncias entre essas letras.
  • {...} reduz essa expressão a um conjunto, basicamente descartando duplicatas
  • len(...)<2 verifica se existe apenas um item no conjunto (ou 0 para cadeias vazias), o que significa essencialmente que todas as letras tinham a mesma distância.
  • print gera esse valor

Obrigado ao xnor por me lembrar que set(...)pode ser substituído {...}e o espaço anterior fornão é necessário. Também graças ao Josay para <=1a <2otimização.

KillianDS
fonte
Bem parecido com a minha solução postada aproximadamente no mesmo minuto. Você foi mais esperto do que eu em fazer a entrada, mas pode reduzir <=1para '<2'.
precisa saber é o seguinte
11
Você pode fazer uma compreensão do conjunto diretamente, em {...}vez de set((...)). Seu código precisa realmente imprimir o resultado.
xnor 21/05
@KillianDS As regras padrão requerem impressão em STDOUT ou retorno (não avaliação REPL), e aqui a impressão especificada pelo OP. Caso contrário, a maneira mais curta genérica é usar lambdapara economizar na gravação printou return.
Xnor 22/05
11
A propósito, você não faz o espaço antes for; o lexer Python se divide corretamente 26for.
Xnor 22/05
5

APL (15)

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

Ele precisa que as letras estejam em maiúsculas e imprima uma 1ou mais ou 0menos:

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

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

Explicação:

  • ↑⍞⍞: leia duas linhas do teclado e organize os caracteres em uma matriz N × 2.
  • ⎕A⍳: para cada caractere, encontre em qual posição ele ocorre ⎕A(o alfabeto maiúsculo).
  • -⌿: para cada coluna, subtraia o segundo valor do primeiro valor
  • 26|: pegue o mod-26 de cada um desses números.
  • Se as cadeias são equivalentes a César, todos os números nesta lista agora são iguais, então:
  • ≢∪: encontre o número de valores exclusivos na lista
  • 1=: compare isso com 1.
marinus
fonte
Nunca vou
votar
@AlexA .: Estou usando o Dyalog APL 14. Se você tem um Raspberry Pi, é grátis; para estudantes também é gratuito; caso contrário, você poderá baixar uma versão não registrada, que é nagware, mas funcionalmente idêntica à versão real. O TryAPL é baseado nisso, a propósito.
Marinus 21/05
Eu ficaria interessado em ouvir seus pensamentos sobre Dyalog vs. GNU APL, ngn / apl e APLX, embora os comentários não sejam realmente o lugar para essa discussão. ;)
Alex A.
3

J, 19 bytes

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

Letras na mesma posição devem ter o mesmo caso.

Depois de converter as duas cadeias de entrada em sua representação de ponto de código &(3&u:), comparamos 1com o comprimento #do nó ~.do módulo 26 26|da diferença -das duas matrizes. O problema será 1se todas as distâncias de César forem iguais.

Uso:

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

Experimente online aqui.

randomra
fonte
3

Julia, 91 87 83 bytes

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

Ungolfed + explicação:

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

Isso tira vantagem do fato de que seqüências de caracteres em Julia podem ser tratadas como matrizes de caracteres e que operações aritméticas podem ser executadas em valores de caracteres. As cadeias de entrada podem ter qualquer combinação de letras maiúsculas, desde que a capitalização em cada posição corresponda entre as seqüências.

Alex A.
fonte
3

C99, 92 bytes com bug   101 92 bytes

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

Bem direto; assume que as palavras vêm como primeiro e segundo argumentos, respectivamente. Compilado com -std=c99.

rr-
fonte
Isso fornece o resultado errado para a segunda entrada de amostra.
Reto Koradi 24/05
Você está certo, eu senti falta disso. Fixo.
RR
3

Javascript ( ES7 Draft ), 87 bytes

Requer entradas para ser o mesmo caso.

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

nderscore
fonte
2

CJam, 13 bytes

{r(fm26f%}2*=

Requer que o primeiro caractere de cada palavra esteja em maiúscula, outros em minúscula.

Experimente aqui . ( Firefox aqui .)

Pena que as variantes APL não suportam aritmética de caracteres ...

Explicação

{
    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.
jimmy23013
fonte
2

Perl, 80

Editar : uma falha na otimização caiu no código do golfe. Agora, ele combina com a versão não destruída. (A contagem de bytes estava correta, no entanto.)

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

Execute com Perl versão 5.10 ( perl -M5.10.0ou perl -E …) para say(). Versão ligeiramente expandida:

@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

O código gera 1(verdade em Perl) se as seqüências de caracteres forem equivalentes a César, e a sequência vazia (falsy em Perl), se não forem. Se essa interpretação for muito flexível, preciso adicionar 2 bytes para say$p+0, que imprime 1ou 0.

O caso do caractere deve corresponder entre as entradas.

xebtl
fonte
Com base nos comentários da pergunta acima, você também pode receber entradas como argumentos da linha de comando. Você poderia usar -ia tomar na segunda corda, que seria armazená-lo na variável $^I. Além disso, usar em -Evez de -eexecutar na linha de comando o levará saygratuitamente, para que você possa usá-lo sem adicionar bytes. Tente executar o seguinte: perl -iteststring -E'say$^I'você pode reduzi-lo com o -itruque.
Hmatt1 21/05
Obrigado @chilemagic, o -itruque é legal (e eu não sabia!). Nesse caso, não acho que ajude porque $^Ié mais longo que <>.
Xebtl # 21/15
@chilemagic Oh, e de acordo com essa discussão , eu não contei os bytes de -M5.10.0qualquer maneira. (Mas eu mencionei o -Einterruptor na edição)
xebtl
2

Matlab, 49 48 bytes

Essa foi realmente rápida. Infelizmente, obter uma string de stdin é bastante caro.

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

Observe que, como a maioria, senão todas as respostas, diferencia maiúsculas de minúsculas.

Edição: raspou um byte, definindo uma função anônima!

Oebele
fonte
2

Prolog, 56 bytes

b([],[],_).
b([A|C],[B|D],N):-N is mod(A-B,26),b(C,D,N).

Nem todas as combinações de casos são suportadas.

uso

b(`abcd`,`yzab`,_).

Experimente online aqui

Persitz
fonte
2

C, 97 bytes

#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");}
Reto Koradi
fonte
11
Yay! Você restaurou o saldo!
DJMcMayhem
Você pode salvar 4 caracteres se reutilizar de declarar ao tipo fora dos parâmetros como este: d,r;main(int c,char**a){r;main(d,a)char**a;{
rr-
1

Scala, 57 bytes

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

Pouco mais que os outros, e essencialmente equivalente, mas está em um estilo de linguagem diferente!

Eu também tenho esta versão (56 bytes):

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

Mas eu não sei se x $ 1 de trabalho é coincidência ou por design ...

Outras
fonte
11
Isso é realmente estranho, como x$1funciona sem xnunca ser definido?
Dan Getz #
@ DanGetz Tenho certeza de que é um acaso de compilador. Posso fazer uma pergunta sobre o estouro de pilha: D
Outros
1

Python 2, 80 bytes

Pega 2 seqüências de caracteres semelhantes de stdin separadas por um espaço:

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

Testado nos seguintes casos de teste:

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)
SylvainD
fonte
1

Python 2 - 241 237 188 147 Bytes

Recebe a entrada como uma sequência minúscula entre aspas, com espaço separado. Tem que haver uma maneira melhor ..

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 bytes ímpares)

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)
Kade
fonte
Tenho certeza de que você pode aumentar o tamanho de todas as variáveis ​​1 e economizar um monte de bytes. Você também precisa adicionar 4 à sua pontuação, pois espera 4 "s extras em sua entrada.
@Reticidade Não posso acreditar que não reduzi as variáveis ​​... movimento amador. Adicionei 2 à contagem de bytes, porque não expliquei corretamente; entrada funciona como "abc cde".
Kade
1

R, 83 84

Praticamente o mesmo que as outras soluções. Converta as seqüências de caracteres em um vetor de números inteiros. Modifique a diferença dos vetores em 26. Faça um único sobre a lista, pois verifique se o comprimento é 1. Ele espera que o caso seja o mesmo nos caracteres correspondentes em cada sequência.

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

Espera que as duas cadeias sejam inseridas

> 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
>
MickyT
fonte
Você pode salvar um byte usando em <2vez de ==1.
21315 Alex A.
Você pode salvar 3 bytes apenas 10
@AlexA. Graças Alex eu perdi esse ... e agora eu sinto falta que um :)
MickyT
@ Liticidade: Como?
Alex A.
Infelizmente, ele retornaria 1 ou mais que um.
MickyT
1

Matlab / Octave, 53 52

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

A entrada deve ser do mesmo caso.

Infelizmente, o Matlab não é muito bom com a entrada do usuário. Como um identificador anônimo, isso pode ter apenas 35 bytes:

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

O Matlab trata os caracteres de uma string como um vetor de números. Fazer subtração nos faz a diferença e uniqueconverte esse vetor em um vetor que contém apenas valores únicos. Se houver apenas um número, as palavras serão equivalentes a maiúsculas e o retorno isscalar 1, caso contrário, retornará 0.

FryAmTheEggman
fonte
Oh! Outra entrada do Matlab! Olhei para as respostas apenas depois de me responder.
Oebele 22/05
acabei de descobrir que você pode salvar um byte definindo x = @ () input ('', 's');
Oebele
@Oebele Thanks! Acho que vou começar a tentar mais problemas de golfe no Matlab, achei bastante divertido.
FryAmTheEggman
Sim, é. Para muitos problemas, pode ser muito conciso com o material baseado em matriz. O Octave possui um pouco mais de sintaxe livre, que às vezes também pode economizar mais alguns bytes, como definição de variável embutida.
Oebele
1

festança, 71 48

Usando o programa Unix "padrão" caesar(6).

Nova versão (com muita ajuda do @DigitalTrauma):

read a b;seq -f"caesar %g <<<$a" 26|bash|grep $b
  • As entradas devem estar na mesma linha, separadas por espaços
  • O caso do caractere deve corresponder entre as entradas.
  • Imprime 1para verdadeiro ou nada para falso.

Se a entrada via argumentos da linha de comando for permitida, ela poderá ser reduzida para 39 bytes :

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

Versão antiga para o registro:

 read a b;for i in `seq 26`;do [ `echo $a|caesar $i` = $b ]&&echo 1;done
xebtl
fonte
48 bytes, pela minha contagem: read a b;seq -f"caesar %g <<<$a" 26|bash|grep $bO resultado está na $?variável interna, onde 0 == FALSE e 1 == TRUE, conforme a semântica padrão do shell.
Digital Trauma
@DigitalTrauma Essas são algumas idéias bacanas! Eu gosto especialmente do seq -f | bashpouco. O resultado $?não é válido pela minha leitura do desafio, mas, assim como meu código, o seu não gera nada para falso e algo para verdadeiro (exceto no caso limítrofe de duas seqüências de entrada vazias). Enfim, seria uma trapaça usar tudo isso na minha resposta, talvez você deva enviar a sua própria.
Xebtl # 22/15
Não se preocupe, estou oferecendo dicas de golfe para você usar. Se eu quisesse usá-los, já o teria feito :). Quanto à coisa da verdade / falsey, eu tendem a interpretar como verdadeiras e falsas em seu idioma específico - try [ 0 == 0 ] ; echo $?and[ 0 == 1 ] ; echo $?
Digital Trauma
1

> <> (Peixe) , 50 bytes

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

Espera que as letras na mesma posição tenham o mesmo caso.

Explicação

  • i:3b*(?vlê a primeira palavra na pilha 88+0.fornecendo o salto em loop
  • ~ri-&remove ~o espaço de separação da pilha, inverte a pilha r(a primeira letra estará no topo), lê a primeira letra da segunda palavra i, calcula o deslocamento da primeira letra da primeira palavra -e a armazena no registro &.
  • l?!^i-&:&-2d*%0)?vlê cada letra seguinte da segunda palavra, subtraindo-a da letra correspondente da primeira palavra, que está no topo da pilha, substratos o deslocamento &:&-armazenado no registro e verifica se o resultado é 0 mod 26 2d*%. Caso contrário, imprime 0 e termina 0n;. c1.fornece o salto em loop.
  • Se chegar ao final da segunda palavra, o programa imprime 1 e termina 1n;.
randomra
fonte
0

KDB (Q), 35 bytes

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

Explicação

                         "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

Teste

q){0=sum(1_-':)mod[;26](-)."i"$(x;y)}["abcd";"yzab"]
1b
WooiKent Lee
fonte
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();}}

expandido:

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

Eu poderia economizar 14 bytes se me livrasse da conversão de tudo para maiúsculas, mas acho que é mais completo deixá-lo.

Jack Munição
fonte
0

Geléia , 5 bytes

Oạ/ċ2

Experimente online!

Emite um número inteiro positivo para equivalente, 0 caso contrário

Como funciona

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
caird coinheringaahing
fonte