Determinar se strings são anagramas


85

Desafio

Dadas duas seqüências, resolva se ambas têm exatamente os mesmos caracteres.

Exemplo

Entrada

palavra, errado

Isso retorna trueporque eles são os mesmos, mas apenas embaralhados.

Entrada

palavra wwro

Isso retorna false.

Entrada

barco, toba

Isso retorna true

Regras

Aqui estão as regras!

  • Suponha que a entrada tenha pelo menos 1 caractere e não mais que 8 caracteres.
  • Sem caracteres especiais, apenas a-z
  • Todas as entradas podem ser consideradas minúsculas

Casos de teste

boat, boat = true
toab, boat = true
oabt, toab = true
a, aa = false
zzz, zzzzzzzz = false
zyyyzzzz, yyzzzzzy = true
sleepy, pyels = false
p,p = true

10
9 respostas em 13 visualizações ... uau!
Tom Gullen

@ Tom, porque todo mundo queria provar que o seu comentário sobre como usar um número inteiro de 64-bit estava apontando na direção errada: P
Peter Taylor

5
Pedido de título: Cod Elf, Go!

5
"Falcon Rage, enlouqueça!"
Geobits

7
Minha sugestão de nome: "eles são anagramas" → "gerenciar as matrizes"
Esolanging Fruit

Respostas:


39

Python, 32 bytes

f=lambda a,b,S=sorted:S(a)==S(b)

3
@Debanjan, este é apenas o mesmo que def f(a,b):return sorted(a)==sorted(b)O trade off é que você começa a substituir def + voltar com lambda em troca de não usar quaisquer declarações
gnibbler

1
@Danjanjan, acho que só economiza um personagem. Eu usei uma variação aqui, mas ele funciona o mesmo comprimento que o seu porque eu trocar uma nova linha para uma vírgula
gnibbler

4
@ Tomas, bobagem. A pergunta não especifica o programa completo, portanto , uma função ou um programa completo são aceitáveis.
Gnibbler

2
@ Tomas, a maioria das respostas aqui não passa nos seus critérios. Por que não dar um voto positivo a todos aqueles que o fazem?
Gnibbler

4
@ Tomas, não é abuso de regras. Algumas perguntas são deliberadamente abertas como esta. Compare com uma pergunta bem especificada como esta . Se você não gostar destas respostas, queixe-se da pergunta
gnibbler):

27

Golfscript, 3 caracteres?

$$=

uso:

'boat'$'baot'$=
1

'toab'$'boat'$=
1

'oabt'$'toab'$=
1

'a'$'aa'$=
0

'zzz'$'zzzzzzzz'$=
0

'zyyyzzzz'$'yyzzzzzy'$=
1

'sleepy'$'pyels'$=
0

'p'$'p'$=
1

23
Esta é uma interpretação interessante de como fornecer a entrada :)
gnibbler

4
Explicação, por favor :(
st0le

10
@ st0le, a sério? Eu não sei golfscript, mas é obviamente $ (tipo), $ (tipo), = (comparar)
Peter Taylor

11
Isso não é trapaça? Quero dizer, não é entrada variável. Tem que ser codificado. Em qualquer caso, eu adicionaria 4 à contagem de caracteres para os caracteres de quote ( ').
21811 Thomas Eding

6
Isso não é válido pelas nossas regras atuais. Você pode, no entanto, alterá-lo para a função de 4 bytes do @ JanDvorak, que aceita entrada por um formato de entrada válido .
Maçaneta

20

J, 8

-:&(/:~)

Literalmente, combine ( -:) em ( &) classifique ( /:~)

Uso da amostra:

   'boat' -:&(/:~) 'boat'
1
   'toab' -:&(/:~) 'boat'
1
   'oabt' -:&(/:~) 'toab'
1
   'a' -:&(/:~) 'aa'
0
   'zzz' -:&(/:~) 'zzzzzzzz'
0
   'zyyyzzzz' -:&(/:~) 'yyzzzzzy'
1
   'sleepy' -:&(/:~) 'pyels'
0
   'p' -:&(/:~) 'p'
1

Onde os números inteiros de 64 bits entram em jogo?


Não é possível escrever funções / sub-rotinas em J?

2
@ Tim Nordenfur: eles são chamados de "verbos" e levam um argumento à direita como em v arg(mônadas) ou dois de ambos os lados como em arg1 v arg2(díades). A que enviei é obviamente uma díade. Não me preocupei em nomeá-lo, pois não foi solicitado e é mais curto dessa maneira. Se você realmente quiser dar um nome a ele, faça assim: is_anagram_of =: -:&(/:~)e use como 'a' is_anagram_of 'aa'.
JB

Parecia um pouco barato substituir os argumentos no código, mas agora vejo que é essencialmente uma díade. Deixa pra lá.

29
J sempre parece os restos de uma explosão de fábrica de emoticons.
9115 st0le

19

Javascript, 192 157 152 152 147 125 bytes

Ok, algumas dessas línguas são muito mais flexíveis do que eu pensava! Enfim, essa é a maneira mais longa, eu acho, mas pelo menos uma técnica diferente.

Comprimido

Obrigado a Peter e David por espremer mais caracteres!

for(a=[j=p=2];j<123;)a[j]?p%a[++j]<1&&p++&&(j=0):(a[j]=p,j=0);function b(c,i){return c[i=i||0]?a[c.charCodeAt(i)]*b(c,++i):1}

Então faça:

alert(b("hello")==b("elloh"));

Código expandido

O comprimido teve muitas mudanças, mas esta é a teoria básica:

// Define dictionary of primes
a = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101];

// Returns the unique ID of the word (order irrelevant)
function b(c) {
    r = 1;
    for (i = 0; i < c.length; i++)
        r *= a[c[i].charCodeAt(0) - 97];
    return r
}

alert(b("hello") == b("hlleo"));

Ótima idéia usando números primos.

@ Tim obrigado! Agora chegamos a 157.
Tom Gullen

2
Você pode raspar alguns caracteres da inicialização do dicionário usando a peneira. a=[2];for(p=3,j=0;j<26;)if(a[j]){if(p%a[j++]==0){p++;j=0}}else{a[j]=p;j=0}
Peter Taylor

1
@ Tom, depende de quão bem otimizado as rotinas de classificação são, uma vez que você tem entradas limitadas a 8 caracteres: P
Peter Taylor

1
125 caracteres . Recursão e ternários FTW:for(a=[j=p=2];j<123;)a[j]?p%a[++j]<1&&p++&&(j=0):(a[j]=p,j=0);function b(c,i){return c[i=i||0]?a[c.charCodeAt(i)]*b(c,++i):1}
David Murdoch

15

Golfscript, 8 bytes

Isso define uma função chamada A

{$\$=}:A

Casos de teste

;
'boat' 'boat' A
'toab' 'boat' A
'oabt' 'toab' A
'a' 'aa' A
'zzz' 'zzzzzzzz' A
'zyyyzzzz' 'yyzzzzzy' A
'sleepy' 'pyels' A
'p' 'p' A

11

Haskell, 31 bytes

função - 31

import List
f=(.sort).(==).sort

programa - 81 58 55

import List
g=sort`fmap`getLine
main=(`fmap`g).(==)=<<g

Uso:

$ runghc anagram.hs
boat
boat
True
$ runghc anagram.hs
toab
boat
True
$ runghc anagram.hs
a
aa
False

Parabéns ao lambdabot e sua refatoração sem pontos .


O código Haskell que apenas executa o que é desejado sob runghc, mas não quando compilado, ainda pode ser chamado de "programa"?
JB

3
@JB: O código Perl que apenas o que é procurado perlainda pode ser chamado de "programa"? :-)
Joey Adams

JB: As linguagens funcionais de hoje distorcem o significado de um programa, tornando-o uma abstração de ordem superior. Em vez de apenas uma lista de instruções a serem executadas, o programa haskell pode ser visto apenas como uma coleção de funções, mesmo que não sejam chamadas.
Callum Rogers

@ Callum Rogers: meu argumento é: o código dele se comporta de maneira diferente, seja executado sob runghc ou compilado, em uma área sensível a problemas. A "função" está correta. O "programa" não resolve o problema com nada além de runghc, e runghc não é a única maneira legítima de executar programas Haskell. Nesse contexto, isso torna o snippet um "script runghc", não um "programa Haskell". - não que eu considere a questão importante, como eu disse, a função está boa de qualquer maneira e é mais curta.
JB

2
x#y=sort x==sort yé 1 caractere menor
Rotsor 6/08/11

10

C #, 129 caracteres

namespace System.Linq{class X{static void Main(string[]a){Console.Write(a[0].OrderBy(_=>_).SequenceEqual(a[1].OrderBy(_=>_)));}}}

Legível:

namespace System.Linq
{
    class X
    {
        static void Main(string[] a)
        {
            Console.Write(a[0].OrderBy(_ => _)
                  .SequenceEqual(a[1].OrderBy(_ => _)));
        }
    }
}

Eu acho que você poderia jogar golfe com alguns bytes em using System.Linq;vez de colocar o namespace?
Stackstuck 26/03

10

Ruby, 34 bytes

Usando o esquema de E / S da solução Peter Taylors Perl:

p gets.chars.sort==gets.chars.sort

Lança um erro:-e:1:in '<main>': undefined method 'chars' for nil:NilClass (NoMethodError)
Tomas

9

Programa C, 118

t[52],i;main(c){for(;i<52;)(c=getchar())<11?i+=26:t[i+c-97]++;
for(i=27;--i&&t[i-1]==t[i+25];);puts(i?"false":"true");}

1
Já pensou em se candidatar à IOCCC ?
Mateen Ulhaq

9
@muntoo: você viu alguma coisa no IOCCC? Isso é muito legível para isso.
R. Martinho Fernandes

@ Martinho Sim, os códigos-fonte da IOCCC são muito bonitos. Sinfonias. Mas ele deveria pelo menos tentar compor um pequeno pedaço. :)
Mateen Ulhaq

@muntoo: eu nem sabia que eles ainda estavam ativos.
Joey Adams

1
Só vi esse ... Muito bom. Mas pode ser mais curto: t[256],i;main(c){for(;c+3;)(i=getchar())>10?t[i]+=c:(c-=2);for(i=257;--i&&!t[i-1];);puts(i?"false":"true");}- são 108 caracteres. Muito importante, seu ctruque de inicialização ainda é empregado.
31512 ugoren

7

Perl, 58 bytes

(programa completo, diferente da outra resposta Perl, que é apenas uma função)

($c,$d)=map{[sort split//]}<>;print"@$c"eq"@$d"?true:false

49 em função

sub f{($c,$d)=map{[sort split//]}<>;"@$c"eq"@$d"}

é claro que você pode salvar 4 caracteres no programa removendo "true e false, pois sem usar estritos / avisos, uma palavra de barra é uma string.
Joel Berger


Eu prefiro isso como ($c,$d)=map{[sort split//]}@ARGV;exit("@$c"ne"@$d")(51 caracteres) para que ele possa receber argumentos da linha de comando e usar os códigos de saída da linha de comando. Seriam 48 caracteres retidos <>com uma entrada de várias linhas.
Adam Katz

6

Clojure - 23 caracteres

Como uma função anônima:

#(apply = (map sort %))

Exemplo de caso de teste:

(#(apply = (map sort %)) ["boat" "boat"])
=> true

Legal, eu gosto disso.
Quíron

1
Boa resposta. Eu, particularmente, como as cordas de teste que você escolheu ;-)
coredump

6

Javascript

Com base na solução de @ zzzzBov.

Comparação, 65 caracteres (40 sem função)

function f(a,b){return a.split('').sort()==b.split('').sort()+""}

Comparador, 43 caracteres

function f(a){return a.split('').sort()+""}

Inteligente usando o +""para coagir a string.
Casey Chu

6

C ++ (104 caracteres não-ws)


Com base na classificação da contagem. Nota: assume cadeias do mesmo comprimento, o que parece estar implícito (embora não declarado) pela pergunta.

int u[123], i;

int a(char **c) {
    for(; c[0][i]; ) {
        u[c[0][i]]++;
        u[c[1][i++]]--;
    }

    i=123;
    while(i && !u[--i]);
    return !i;
}

Em C, se você declarar uma variável no escopo global, ela será inicializada como zero. Eu acho que isso também é verdade para C ++.
Joey Adams

As variáveis ​​locais, por outro lado, não são inicializadas para zero automaticamente.
Joey Adams

OK, retirei minha ressalva desde que encontrei maneiras de passar sem ela.
Matthew Leia

1
Bzzzt. Você passa nos casos de teste, mas "helle" e "hollo" são aparentemente os mesmos. Solução fácil: altere um dos ++ para um -. Então apenas se (u [i ++]) retornar 0;
Dave Gamble

1
Eu não testei isso, mas as últimas três linhas podem ser escritas comoi=123;while(i&&u[--i]);return!i;
st0le

4

PHP (linha de comando, 87 caracteres)

function d($s){
    return array_count_values(str_split($s));
}

echo d($argv[1]) == d($argv[2]);

4

Javascript

Uma versão (muito) ligeiramente mais curta da solução do @ zzzzBov, que usa, em .join()vez do boxe String:

function a(b,c){return b.split('').sort().join()==c.split('').sort().join()}
alert(a('abc','bca')); //true

Similarmente:

function a(b){return b.split('').sort().join()}
alert(a('abc')==a('bca')); //true

3
esta é a resposta ID 1337. parabéns
TheDoctor

4

Clojure REPL 41 chars

(= (sort (read-line)) (sort (read-line)))

Bem-vindo à rede Stack Exchange. Ajuda de formatação aqui .
dmckee

4

Java

(Aparentemente, o idioma favorito de todos!)

173 caracteres:

import java.util.*;class g{public static void main(String[]p){String[]a=p[0].split(""),b=p[1].split("");Arrays.sort(a);Arrays.sort(b);System.out.print(Arrays.equals(a,b));}}

(Não imprime caracteres de nova linha para salvar 2 caracteres de println)

Compile e execute:

javac g.java
java -cp . g abcdef fedcba
true

Amor para ver um mais curto ...


Eu sei que tem sido mais de 6,5 anos (lol), mas você pode golfe-lo por 10 bytes, adicionando java.util.Arrays x=null;e usar x.em vez de Arrays.: class g{public static void main(String[]p){java.util.Arrays x=null;String[]a=p[0].split(""),b=p[1].split("");x.sort(a);x.sort(b);System.out.print(x.equals(a,b));}}( 163 bytes ) E, convertendo-a Java 8, class g{public static void mainpoderia ser interface g{static void mainassim, mas eu acho que Java 8 wasn ainda está por aí em 2011, portanto, manter classtambém é bom. ; p
Kevin Cruijssen

4

sed, 45 caracteres

É até possível no meu favorito - sed! Apenas uma expressão regular para resolver o anagrama ! Continue removendo as letras correspondentes:

:
s/(.)(.*,.*)\1/\2/
t
/\w/{i\false
d}
i\true

(a ser invocado com -nE)

Perl, 48

1while s/(.)(.*,.*)\1/\2/;$_=/\w/?"false":"true"

Para ser invocado com -p.

Função Perl, 39

sub f{$,while s/(.)(.*,.*)\1/\2/;!/\w/}

4

APL, 2 caracteres

≡⍦

Essa é a função Multiset Match do Nars2000 , uma das implementações de APL de ponta. Quando aplicado a strings, calcula exatamente a função necessária:

      'elvis' ≡⍦ 'lives'
1
      'alec guinness' ≡⍦ 'genuine class'
1

Apenas curioso, quantos bytes é esse? 4? 6?
Maltysen 30/01

Depende da codificação. 6 bytes em UTF-8, 4 bytes em UCS-2, 2 bytes, se algum dos caracteres APL herdados de byte único tiver o símbolo, o que duvido.
precisa saber é

4

05AB1E , 6 4 bytes (não concorrente)

{I{Q

Experimente online!

Isso levou um tempo devido a dificuldades de entrada. Golfe devido ao pop.

Explicação:

{I{Q    Original code

{       Takes first input e.g. word and sorts -> 'dorw'
 I      Takes second input e.g. 'wrdo'
  {     Sorts second input -> 'dorw'
   Q    Compare if sorted 1 = sorted 2, then print result. 'dorw' = 'dorw', so prints 1.

1
Como 05AB1E é mais recente que esse desafio, esta resposta não é concorrente.
Loovjo 06/10

Desculpe - não percebi.
Geno Racklin Asher

4

Perl, 77 75 caracteres

A E / S do problema não está bem especificada; isso lê duas linhas de stdin e gera true ou false para stdout.

sub p{join'',sort split'',$a}$a=<>;$x=p;$a=<>;print$x eq p()?"true":"false"

(Obrigado a Tim por 77 -> 75)


Algo está errado. $a=;? Além disso, você pode pular as parênteses de sorte o espaço a seguir print.

@ Tim, o gênio que desenvolveu essa plataforma para compartilhar código pela rede decidiu que, em blocos de código, as pessoas deveriam escapar menos de caracteres. Mas ei, não é grande coisa: não é como se alguém os usasse no código, certo? Continua me pegando.
Peter Taylor

2
Ok, eu removi o voto negativo. Você pode querer usar a formatação do código no futuro, ou seja, recuar o código com quatro espaços.

1
Ok, existem três maneiras de formatar o código (um em linha e dois blocos), e os dois são inconvenientes de maneiras diferentes. Suspiro.
Peter Taylor

4

Perl, 62 bytes

Essa função aceita as seqüências de caracteres como argumentos e retorna verdadeiro ou falso.

sub f{my@a;for$.(1,-1){$a[ord]+=$.for split//,pop}!grep{$_}@a}

Armazena os valores ASCII em uma matriz e verifica se está nivelado. Incrementos para a primeira palavra e decrementos para a segunda palavra.


4

Python 3, 107 97 76 64

s=sorted;a,b=input().split(', ')
print(str(s(a)==s(b)).lower())

Obviamente, isso pode ser abreviado se não considerarmos literalmente as palavras do OP e em minúsculas "true" e "false" ...


Você pode cortar alguns caracteres se anexar ;s=sortedà primeira linha e substituir as duas instâncias de sortedpor sna segunda linha. Deve salvar ... 3 caracteres?
precisa

1
De fato. O Python 3 também economiza um pouco de espaço e provavelmente é razoável usá-lo agora, cinco anos após a publicação desta resposta. Além disso, o .strip () era redundante, dadas as entradas especificadas.
Wooble

Sim, desculpe-me. Eu não percebi a idade dessa pergunta quando comentei, apenas que estava na primeira página. ^^;
Alex Van Liew

4

Python, 32 bytes

p=sorted
f=lambda a,b:p(a)==p(b)

Não faz nada em python. Tem certeza de que é um programa completo que recebe a entrada e produz a saída conforme solicitado?
Tomas

1
@Tomas É uma função
TuxCrafting 08/10

4

Bash, 88 caracteres

diff <(grep -o .<<<$1|sort) <(grep -o .<<<$2|sort)>/dev/null && echo true || echo false


3

Scala em REPL (32)

readLine.sorted==readLine.sorted

Função Scala (43)

def f(a:String,b:String)=a.sorted==b.sorted

Programa Scala (61)

object A extends App{println(args(0).sorted==args(1).sorted)}

Eles utilizam um recurso interessante do Scala, no qual uma String também pode ser tratada como uma sequência de caracteres ( Seq), com todas as operações Seqdisponíveis.


3

APL - 13 caracteres

{(⍺[⍋⍺])≡⍵[⍋⍵]}

Ligue assim:

      'boat' {(⍺[⍋⍺])≡⍵[⍋⍵]} 'baot'
1
      'baot' {(⍺[⍋⍺])≡⍵[⍋⍵]} 'boat'
1
      (,'a') {(⍺[⍋⍺])≡⍵[⍋⍵]} 'aa'
0

No último exemplo, 'a'representa um único caractere e o prefixo ,o converterá em uma sequência.


3

Java (134 bytes)

int[][]c=new int[2][26];
for(int i=0;i<2;i++)for(byte a:args[i].getBytes())c[i][a-97]++;
System.out.print(Arrays.equals(c[0],c[1]));`

Isso faz com que uma matriz conte o número de vezes que cada letra aparece e compara as matrizes para verificar se são iguais.


1
Bem-vindo ao PPCG! Bom primeiro post! Existem 2 espaços que você pode remover (c[0], c[1])e for (int i=0;.
Rɪᴋᴇʀ

3

JavaScript, 41

Função de comparação (41) :

a=b=>''+[...b].sort()
b=(c,d)=>a(c)==a(d)
alert(b('abc', 'cba')) // true

Função comparadora (21) :

a=b=>''+[...b].sort()
alert(a('abc') == a('bca')); //true

Função comparadora (48):

function a(b){return String(b.split('').sort())}
alert(a('abc')==a('bca')); //true

Função de comparação (78):

function a(b,c){return String(b.split('').sort())==String(c.split('').sort())}
alert(a('abc','bca')); //true

Assume que Stringtem splite Arraytem sort.


38 bytes:c=>d=>(a=b=>''+[...b].sort())(c)==a(d)
Shieru Asakoto 19/03
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.