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
Tom Gullen
fonte
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)
mordedor
fonte
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
VOCÊ
fonte
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?

JB
fonte
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"));
Tom Gullen
fonte
Ó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
mordedor
fonte
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 .

Joey Adams
fonte
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(_ => _)));
        }
    }
}
Timwi
fonte
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
steenslag
fonte
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");}
Joey Adams
fonte
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"}
Timwi
fonte
é 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
Obrigado!
Timwi
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
Mikera
fonte
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()+""}

fonte
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;
}
Matthew Read
fonte
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]);
ts01
fonte
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
Blair Mitchelmore
fonte
3
esta é a resposta ID 1337. parabéns
TheDoctor
4

Clojure REPL 41 chars

(= (sort (read-line)) (sort (read-line)))
Lula
fonte
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 ...

Greg Schueler
fonte
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/}
Tomas
fonte
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
Tobia
fonte
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.
Geno Racklin Asher
fonte
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)

Peter Taylor
fonte
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.

jrtapsell
fonte
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" ...

Wooble
fonte
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)
Quixotesco
fonte
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
Martin
fonte
4

R , 54 bytes

function(x,y,`~`=sort,`+`=utf8ToInt)identical(~+x,~+y)

Experimente online!

J.Doe
fonte
Estou muito intrigado com o uso de utf8ToInt, não apenas nesta resposta, mas em muitas outras que já vi.
Sumner18
1
Você já viu dicas para jogar golfe no R ? utf8ToInte seu reverso tende a reduzir a divisão das cordas do que as funções convencionais.
J.Doe
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.

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

Elias Mårtenson
fonte
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.

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

zzzzBov
fonte
38 bytes:c=>d=>(a=b=>''+[...b].sort())(c)==a(d)
Shieru Asakoto 19/03