97
\$\begingroup\$

Challenge

Given two strings, work out if they both have exactly the same characters in them.

Example

Input

word, wrdo

This returns true because they are the same but just scrambled.

Input

word, wwro

This returns false.

Input

boat, toba

This returns true

Rules

Here are the rules!

  • Assume input will be at least 1 char long, and no longer than 8 chars.
  • No special characters, only az
  • All inputs can be assumed to be lowercase

Test Cases

boat, boat = true toab, boat = true oabt, toab = true a, aa = false zzz, zzzzzzzz = false zyyyzzzz, yyzzzzzy = true sleepy, pyels = false p,p = true 
\$\endgroup\$
7
  • 11
    \$\begingroup\$ 9 answers in 13 views... wow! \$\endgroup\$ Commented Mar 8, 2011 at 16:44
  • 5
    \$\begingroup\$ Title request: Cod Elf, Go! \$\endgroup\$ Commented Jul 9, 2016 at 12:48
  • 7
    \$\begingroup\$ "Falcon Rage, go mad!" \$\endgroup\$ Commented Oct 6, 2016 at 17:25
  • 16
    \$\begingroup\$ My name suggestion: "are they anagrams" → "manage the arrays" \$\endgroup\$ Commented Oct 31, 2017 at 4:32
  • 2
    \$\begingroup\$ Suggested test case: aaab, bbba = false \$\endgroup\$ Commented Aug 3, 2022 at 23:56

171 Answers 171

1
\$\begingroup\$

Jelly, 3 bytes (probably non-competing)

Ṣ€E 

Try it online!

Similar to X88B88's solution, but this takes a list of strings instead of two arguments, like ["String1", "String2"].

Explanation:

Ṣ€ Sort each input E Check equality 
\$\endgroup\$
0
1
\$\begingroup\$

Wolfram Language 26 bytes ( Mathematica )

ContainsAll@@Characters@#& 

Usage:

%@{"BOAT","TOAB"} 

Output:

True

\$\endgroup\$
1
\$\begingroup\$

J, 8 bytes

-:&(/:~) 

Match -: after sorting /:~ both args &.

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Axiom, 45 bytes

f(a:String,b:String):Boolean==sort(a)=sort(b) 
\$\endgroup\$
1
\$\begingroup\$

Perl 5, 27 + 3 (-lF) = 30 bytes

@{$.}=sort@F}{say"@1"eq"@2" 

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ The -l option is not needed. It would still count as +3 though since you must count the space too (since you cannot bundle the -F with -E. You can however do the final match using @1~~@2 saving 4 bytes (or 3 if you add an extra X option letter to supress the warning). Very neat solution by the way. Have a +1 \$\endgroup\$ Commented Feb 4, 2018 at 11:43
1
\$\begingroup\$

Pyth, 4 bytes

_ISM 

Try it Online

Explanation

_ISM SMQ Sort both (implicit) inputs. _I Check if the result is invariant under reversing. 
\$\endgroup\$
1
\$\begingroup\$

Lua, 140 chars

t={io.read():match"(%w+), (%w+)"}T=table for k=1,2 do w={t[k]:byte(1,-1)}T.sort(w)t[k]=T.concat{string.char(unpack(w))}end print(t[1]==t[2]) 

... like driving a screw with a light weight hammer, at least for code-golfing

\$\endgroup\$
1
\$\begingroup\$

Python 2, 79 bytes

I thought I would add a different Python approach:

import sys for l in sys.stdin: not reduce(cmp,map(sorted,l.strip().split(','))) 

Or as a function:

def f(*v): return not reduce(cmp,map(sorted,v)) 
\$\endgroup\$
1
\$\begingroup\$

Scala, 84 characters

object A{def main(a: Array[String]){println(a(0).sortWith(_<_)==a(1).sortWith(_<_))}} 

This one's slightly longer, but doesn't use sorting (92 characters):

object A{def main(a:Array[String]){print((a(0)diff a(1)).isEmpty&&(a(1)diff a(0)).isEmpty)}} 
\$\endgroup\$
3
  • 1
    \$\begingroup\$ You can use sorted instead of sortWith. I posted another reply with sorted as well as REPL and function versions. \$\endgroup\$ Commented Mar 9, 2011 at 6:15
  • \$\begingroup\$ @ebruchez Thanks, I'm just learning Scala at the moment and these make good exercises. :-) \$\endgroup\$ Commented Mar 9, 2011 at 10:19
  • \$\begingroup\$ Still learning myself ;) \$\endgroup\$ Commented Mar 9, 2011 at 16:17
1
\$\begingroup\$

Common Lisp, 50 bytes

(lambda(a b)(string=(sort a'char<)(sort b'char<))) 

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Japt, 10 9 5 4 bytes

á øV 

Try it

á øV :Implicit input of strings U & V á :Permutations of U øV :Contains V? 
\$\endgroup\$
2
  • \$\begingroup\$ As of v2.0a0, ¬n eV¬n works with 7 bytes. \$\endgroup\$ Commented May 21, 2018 at 7:42
  • \$\begingroup\$ øVá \$\endgroup\$ Commented Feb 1, 2019 at 2:22
1
\$\begingroup\$

SmileBASIC, 49 bytes

INPUT A$,B$WHILE""<A$B$[INSTR(B$,POP(A$))]=" WEND 

Throws an error when the strings aren't anagrams.

\$\endgroup\$
1
\$\begingroup\$

Symja, 26 bytes

f(x_,y_):=Sort(x)==Sort(y) 

Try It Online!

Try With Changeable Tests

Assumes strings are given as a list of characters.

\$\endgroup\$
1
\$\begingroup\$

PHP7.4 (45 chars)

The function $f will return the answer using count_chars :

$f=fn($a,$b)=>($x='count_chars')($a)==$x($b); 

Try it Online - in PHP4 the XOR cipher passes all tests using 48 chars :

function f($a,$b){return$a==chop($a.$b^$b^$b);}; 

C gcc (69 chars)

The function f compute the product of both string and implicitly return the comparison :

i;j;f(char*a,char*b){i=j=1;for(;*a;i*=*a++);for(;*b;j*=*b++);a=i==j;} 

Try it Online

C version isn't shaved up to 65 chars by XOR cipher due to some ae == bf misses :

i;f(char*a,char*b){i=1;for(;*a;i^=*a++);for(;*b;i^=*b++);a=i==1;} 
\$\endgroup\$
3
  • \$\begingroup\$ You can put the $f= into the header, as as long as the function does not reference itself, you can drop the function name from the char count. like this \$\endgroup\$ Commented Apr 7, 2022 at 23:18
  • \$\begingroup\$ also you can remove the quotes around count_chars. it will spout all sorts of stuff to stderr, but who cares \$\endgroup\$ Commented Apr 7, 2022 at 23:20
  • \$\begingroup\$ 68 bytes \$\endgroup\$ Commented Apr 10, 2022 at 18:36
1
\$\begingroup\$

Julia, 26 bytes

!a=sort([a...]) a\b=!a==!b 

Try it online!

\$\endgroup\$
1
\$\begingroup\$

C - 115 Bytes

a[127],b[127],i,o=1;f(char*s,char*z){for(;*s;a[*s++]++);for(;*z;b[*z++]++);for(;i++<128&&o;o=a[i]==b[i]);return o;} 

Ungolfed

a[127], b[127], i, o = 1; f(char* s, char* z) { for(; *s; a[*s++]++); for(; *z; b[*z++]++); for(; i++ < 128 && o; o = a[i] == b[i]); return o; } 

Alternative way (By @ceilingcat)

*a,*b,i,o;f(char*s,char*z){for(a=calloc(i=128,8);*s;a[*s++]++);for(b=a+i;*z;b[*z++]++);for(;i--&&(o=a[i]==b[i]););return o;} 

Explanation

A function that receives two ASCII character strings with arbitrary length and checks if one is an anagram of the other.

To accomplish this, both entire strings are iterated over and the number of matches for each character is stored in a list for each string; later it is checked if both lists have the same number of matches, if so, then the strings are anagrams and true (1) is returned, otherwise false (0) is returned.

\$\endgroup\$
2
  • \$\begingroup\$ Fixed some bugs 124 bytes \$\endgroup\$ Commented Apr 11, 2022 at 7:59
  • \$\begingroup\$ @ceilingcat thanks for your comments. \$\endgroup\$ Commented Apr 11, 2022 at 13:09
1
\$\begingroup\$

TI-Basic, 83 bytes

Prompt Str1,Str2 "seq(inString(Str1+Str2,sub(Ans,I,1)),I,1,length(Ans→u Str1 u→A SortA(ʟA Str2 u→B SortA(ʟB 0 If dim(ʟA)=dim(ʟB min(ʟA=ʟB Ans 

Output is stored in Ans and displayed. Outputs 1 if the inputs are anagrams, otherwise 0.

\$\endgroup\$
1
\$\begingroup\$

Alice, 11 bytes

/@Mn/ \MOX\ 

Try it online!

Prints Jabberwocky if the two words are anagrams

Flattened

MM Reads the two arguments X Compute their symmetric difference n Empty string becomes Jabberwocky, anything else becomes empty string O Print it out @ Bye 
\$\endgroup\$
1
\$\begingroup\$

R, 47 bytes

\(x,y)all(table(strsplit(paste0(x,y),""))%%2==0) 
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Fails for aab + bcc: try it. \$\endgroup\$ Commented Nov 18, 2022 at 23:20
1
\$\begingroup\$

BQN, 3 bytes

≡○∧ 

Anonymous tacit function that takes two strings; returns 1 if they are anagrams, 0 otherwise. Try it at BQN online!

Explanation

≡ Are the strings identical ○ when both of them ∧ are sorted? 
\$\endgroup\$
1
\$\begingroup\$

Nekomata + -e, 2 bytes

↕= 

Attempt This Online!

↕ Check if any permutation of the first string = is equal to the second string 
\$\endgroup\$
1
\$\begingroup\$

Labyrinth, 23 bytes

1 ,:# * 0 1;/----+}=-!@ 

Try it online!

Takes two words separated by a newline. For each word, computes the product of c * 10 + 1 for each char c, and compares the two values. Prints 0 for true and a nonzero integer for false.

Such product is unique for lowercase words up to permutation, since the counts of 25 out of 26 letters can be recovered from the exponents of 25 unique prime factors:

971 is prime 981 = 109 * 3 * 3 991 is prime 1001 = 7 * 11 * 13 (no unique prime factor) 1011 = 337 * 3 1021 is prime 1031 is prime 1041 = 347 * 3 1051 is prime 1061 is prime 1071 = 17 * 7 * 3 * 3 1081 = 47 * 23 1091 is prime 1101 = 367 * 3 1111 = 101 * 11 1121 = 59 * 19 1131 = 29 * 13 * 3 1141 = 163 * 7 1151 is prime 1161 = 43 * 3 * 3 * 3 1171 is prime 1181 is prime 1191 = 397 * 3 1201 is prime 1211 = 173 * 7 1221 = 37 * 11 * 3 

Therefore this approach works for arbitrary length inputs.

Since a lowercase letter has value of 97 or higher, the newline has value 10, and -1 is pushed on EOF, a three-way branch is possible via dividing the input value by any number between 11 and 97 inclusive.

By a little bit of planetary alignment, letting the IP reflect on newline (instead of creating a 4-way junction) magically sets up the stack for the second word. This part works because the words are guaranteed to be nonempty.

1 push 1 on empty stack ,:# loop: compute the value of word1 until newline * 0 ,: getchar, dup [word1 c c] 1;/ #0/ divide by 30 [word1 c c/30] if positive: ;1* drop, multiply 10c+1 [word1'] if zero: reflect 1 [word1 10 0] ,:# 0#: push some garbage [word1 10 0 3 3] 0 , getchar (1st char of word2) 1 times 10 plus 1 [word1 10 0 3 3 word2] enter the loop again to compute the value of word2 same flow as first loop, except that # gives 8 and IP turns left on EOF [word1 10 0 3 3 word2 -1 -1] ----+}=-!@ clean up the stack and compare word1 and word2 ----+ [word1 10 word2] }= [word1 word2 | 10] -!@ print the difference and halt 
\$\endgroup\$
1
\$\begingroup\$

JavaScript (Node.js), 37 38 bytes

-1 byte thanks to emanresu A

Here is a more up-to-date JS answer.

a=>b=>(g=x=>[...x].sort()+0)(a)==g(b) 

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can save a byte with +0 since the exact string doesn't matter as long as it's consistent \$\endgroup\$ Commented Aug 6, 2024 at 21:13
  • \$\begingroup\$ @emanresuA Oh you're right! Thanks for the tip, i updated my answer \$\endgroup\$ Commented Aug 7, 2024 at 7:59
1
\$\begingroup\$

TinyAPL, 3 bytes

≡⍥⊵ 

Try it: TinyAPL repl

Explanation: Match over sort

\$\endgroup\$
1
\$\begingroup\$

Regex (.NET), 74 73 bytes

^(.)* ((.)(?<=(?=\3(?<-4>.*?(?<1>\4))*)(?<-1>\1.*(?=(.)?))* .*))*$(?(1)^) 

Try it online! - test cases
Try it on regex101 - try it on your own

This uses a completely different algorithm than my other answer which includes a 70 66 byte .NET version. Like it, this takes the input strings delimited by newline, and works even with zero-length words.

Simply put, it pushes each letter of the first word onto a stack, then goes through each letter of the second word, removing a matching letter from the stack. Iff that completes successfully, and the stack ends up empty, then the two words are anagrams of each other.

What complicates this is that it's a stack, not a random-access array, so to find a matching letter in it, the letters above it need to be moved to a temporary stack, then moved back after the matching letter has been removed.

When interpreting the explanation below, remember that lookbehinds in .NET are evaluated from right to left – so read those from bottom to top, one quantified token at a time. When entering a lookahead inside a lookbehind, go back to reading from top to bottom.

^ # Go to beginning of first word (.)* # Push each letter of first word onto \1 stack ¶ # Go to beginning of second word ( # Begin main loop (.) # \3 = next letter from second word (?<= # Lookbehind (?= # Lookahead \3 # Assert that the last letter popped from the \1 # stack matches \3 (which may make the (?<-1>...) # loop backtrack), and skip it # Transfer \4 stack back onto \1 stack in original order (?<-4> # Pop a letter from the \4 stack as many times as # can be done, each time doing the following: .*? # Skip letters that have already been removed from # the stack in this pass or previous passes (?<1>\4) # Push the letter from \4 back onto the \1 stack )* ) (?<-1> # Pop a letter from the \1 stack as many times as # can be done, each time doing the following: \1 # Match and consume the letter from the \1 stack .* # Skip letters that have already been removed from # the stack in previous passes (?=(.)?) # Push the last letter removed from the \1 stack # onto the \4 stack )* ¶.* # Skip back to the end of the first word ) )* # End main loop $ # Assert end of second word has been reached (?(1)^) # Assert \1 stack has been emptied 
\$\endgroup\$
1
\$\begingroup\$

J-uby, 17 14 bytes

(A|:sort)**:== 

Attempt This Online! (Uses the working ** operator from an older version of J-uby.)

\$\endgroup\$
1
\$\begingroup\$

Vyxal 3 -l, 2 (literate) bytes

permutations contains 

Vyxal It Online!

Performs literally what it says

\$\endgroup\$
0
\$\begingroup\$

C# 118 chars

using System.Linq;namespace A{class P{static void Main(string[] a){System.Console.Write(!a[0].Except(a[1]).Any());}}} 

Readable:

using System.Linq; namespace A { class P { static void Main(string[] a) { System.Console.Write(!a[0].Except(a[1]).Any()); } } } 
\$\endgroup\$
1
  • \$\begingroup\$ You can remove an extra character: string[]a You also don't need a namespace. \$\endgroup\$ Commented Dec 7, 2011 at 13:54
0
\$\begingroup\$

C#

bool IsJumbledPair(string a, string b) { if(a.Length!=b.Length) return false; foreach(char c in a.ToCharArray()) { int i = b.IndexOf(c); if(i<0) return false; b = b.Remove(i,1) } return (b.Length==0); } 

Readable, and does not require sorting.

Another method:

bool IsJumbledPair(string a, string b) { string c; while { if(a.Length!=b.Length) return false; if(a.Length==0) return true; c = a.Chars(0).ToString(); b = b.Replace(c, ""); a = a.Replace(c, ""); } } 

The above version works better when the strings contain a number of duplicated characters, as each distinct character is only compared once using the relatively fast Replace() method.

VB.NET

Same as the first C# example, slightly simpler using Replace() method, but doesn't short-cut like the C# version:

Function IsJumbledPair(a As String, b As String) As Boolean If a.Length <> b.Length Then Return false For Each(c As Char In a.ToCharArray()) b = Replace(b, c.ToString(), "", 1, 1) Next Return (b.Length=0) } 
\$\endgroup\$
3
  • \$\begingroup\$ It is likely that the downvotes are because you have made no effort to golf (see the tag?) your solutions, or because you have mixed several distinct solutions in one answer. \$\endgroup\$ Commented Mar 9, 2011 at 22:50
  • 1
    \$\begingroup\$ Meh. If I play real golf, it's for socializing or beer, not score-keeping. Guess I should have actually been playing to win... :) \$\endgroup\$ Commented Mar 11, 2011 at 6:17
  • \$\begingroup\$ People generally respond well to solutions in wordy languages (I play in Fortran 77 from time to time), as long as you make an effort to write aggressively compacted <wordy language>, and especially if your languages supports a interesting trick (i.e. fortran has computed branches). \$\endgroup\$ Commented Mar 11, 2011 at 16:10
0
\$\begingroup\$

F# (59 chars)

let f a b=(Seq.sort>>Seq.toArray)a=(Seq.sort>>Seq.toArray)b 

Very annyoying that sequences can' be directly compared.

\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.