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.


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.


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.


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.


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.

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.


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.


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.


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


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.

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.


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!


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


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

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


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)

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)

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
>

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.


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

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;.

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

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.


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.