# Determine whether strings are anagrams

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

• 9 answers in 13 views... wow! Commented Mar 8, 2011 at 16:44
• Title request: Cod Elf, Go!
– user54200
Commented Jul 9, 2016 at 12:48
• "Falcon Rage, go mad!" Commented Oct 6, 2016 at 17:25
• My name suggestion: "are they anagrams" → "manage the arrays" Commented Oct 31, 2017 at 4:32
• Suggested test case: aaab, bbba = false Commented Aug 3, 2022 at 23:56

# JavaScript, 41

Comparison function (41):

a=b=>''+[...b].sort()
b=(c,d)=>a(c)==a(d)

alert(b('abc', 'cba')) // true


Comparator function (21):

a=b=>''+[...b].sort()

alert(a('abc') == a('bca')); //true


Comparator function (48):

function a(b){return String(b.split('').sort())}

alert(a('abc')==a('bca')); //true


Comparison function (78):

function a(b,c){return String(b.split('').sort())==String(c.split('').sort())}

alert(a('abc','bca')); //true


Assumes String has split and Array has sort.

• 38 bytes: c=>d=>(a=b=>''+[...b].sort())(c)==a(d) Commented Mar 19, 2019 at 6:17

# Brain-Flak, 170 bytes

{({}[(()()()()()){}]<>)<>}<>([]){{}(<>())<>{({}[(((((()()()()()){}){}){})){}])({({})({}[()])()}{}{}())({<({}[()])><>({})<>}{}<><{}>)<>}{}([])}<>({}[{}])((){[()](<{}>)}{})


Try it online!

Takes input on two lines.

This program makes a Gödel encoding of letter frequencies in each string. This means I need to map each letter to a unique prime number. For that, I use the polynomial n^2 + n + 41, which is known to give prime results for 0 <= n <= 40. I subtract 90 from the ascii code for each letter before passing it to the polynomial, to get a number in the proper range. When the primes are multiplied together, the results should be equal only when the strings are permutations of each other.

# Husk, 2 bytes

€P


Try it online!

Returns index of the permutation found, or 0.

import Data.List
s%t=s\\t==t\\s


Try it online!

The \\ operator from Data.List is multiset difference. If s and t and anagrams, then s\\t is empty, as is t\\s. However, if any character appears in s more times than in t, then s\\t will contain it whereas t\\s won't, making them unequal, and vice versa is the character appears in t more than s.

36 bytes

(.q).(==).q


Try it online!

A shot at an import-less solution. Each string is converted to a base-9 representation of its character counts, and these are checked for equality. The i'th digit base 9 is the number of appearances of the character with fromEnum ASCII value i. This takes advantage of the spec guaranteeing each string is no longer than 9 characters, so there's no rollover in base 9.

39 bytes

s%t=and[q s==q t|q<-filter.(==)<$>s++t]  Try it online! A more general solution following the principles of avoiding sorting. Checks that each character in s++t appears as many times in s as it does in t. # Regex (PCRE), 65 bytes ^((?=(.))(?!(.*?\2(?=.* (\4?+.*?\2)))*+.*\2)(?=.* (\5?+.)).)* \5$


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

Takes the input strings delmited by newline.

This asserts that both:

• For each character in the first string, the second string contains that character at least as many times as it occurs in the first string
• The second string is equal in length to the first
^              # Assert that we're starting at the beginning of the first word.
(
(?=(.))    # Match and capture a character in \2, without consuming it.
# Assert that the second has at least as many occurrences of \2 as there
# are subsequent occurrences of it in the first word (including the one we
# just captured above).
(?! # Negative lookahead - assert the following can't match, and also
# conveniently erase whatever capture groups it creates when finished.
(
.*?\2     # Match up to the next occurrence of \2 in the first word
# (which will be the first one when this loop starts)
(?=
(             # \4 = the following:
\4?+      # previous value of \4, if any
.*?\2     # Match up to the first subsequent occurrence of
# \2 in the second word (which will be the first
# occurrence when this loop starts)
)
)
)*+           # Loop the above possessively, locking in each iteration
# atomically as it matches.
.*\2          # Assert \2 occurs again in the first word.
)
# Append one more character from the second word onto \5, building up \5
# to have the same number of characters of the second word as characters
# we have finished processing in the first word.
(?=
(             # \5 = the following:
\5?+      # Previous value of \5, if any
)
)
.          # Skip over the \2 just processed in the first word.
)*             # Iterate the above as many times as possible.
¶              # Assert we've reached a newline, meaning we've processed the
# entire first word, and advance to the second word.
\5$# Assert that the second word is of equal length to the first.  It only takes +1 byte (66 bytes) to add support for zero-length words: ^((?=(.))(?!(.*?\2(?=.* (\4?+.*?\2)))*+.*\2)(?=.* (\5?+.)).)* \5?$


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

# Regex (.NET), 70 bytes

^(((.))(?=((?<2>\2)|.)*)(?=.*
(?(\2)(?<-2>.)|.)*$(?(2)^)))* (?<-3>.)*$


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

This asserts that both:

• For each character in the first string, the second string contains that character at least as many times as it occurs in the first string
• The second string is not longer than the first

Although it is not required, this works even with zero-length words (for free; there is no golf sacrifice in doing so).

^              # Assert that we're starting at the beginning of the first word.
(
((.))      # Consume a character and capture it in both \2 and \3.

# Assert that the second word has at least as many occurrences of \2 as
# there are subsequent occurrences of it in the first word (including the
# occurrence we just consumed). This only needs to be asserted for the first
# occurrence of each character in the first word (because on each subsequent
# occurrence, the count of subsequent occurrences will be one fewer than
# before) but for golf reasons, it's harmless to do it for every occurrence.

# Step 1: Push every additional occurrence of \2 onto the \2 stack.
(
(?<2>\2)  # Pop a capture off \2 and match it.
|        # or
.         # Match a single character.
)*            # Iterate the above as many times as possible.
)

# Step 2: Assert that the second word has at least as many occurrences
# of \2 as were counted above.
(?=
(?(\2)        # For each character in the second word, if it
# matches \2, match the following:
(?<-2>.)  # Pop that capture off the \2 stack, and consume the
# character.
|             # Else, match the following:
.         # Consume the character.
)*$# Iterate the above until reaching end of string. (?(2)^) ) )* # Iterate the above as many times as possible. ¶ # Assert we've reached a newline; advance to the second word. (?<-3>.)*$     # Assert that this word is not longer than the first word, by
# popping every capture from the \3 stack and matching one
# character of the second word (it doesn't have to match \3)
# for each.


# Regex (Perl / PCRE), 71 bytes

^((?=(.))(?4)(?=.*
(\3?+.)).)*
\3$((?!(.*?\2(?=.* (\6?+.*?\2)))*+.*\2))  Try it online! - Perl Try it online! - PCRE2 Perl doesn't erase capture groups upon exiting from a negative lookahead. For compatibility with it, this version uses a subroutine call (?4) instead of a negative lookahead to erase the necessary capture group. The subroutine is then executed again, harmlessly, after the regex finishes and reaches the end of the string (for golf reasons, it is not hidden in a (?(DEFINE)...) block or similar construct). # Regex (PCRE / .NET), 74 bytes ^((?=(.))(?!(?>(.*?\2(?=.* ((?>\4?).*?\2)))*).*\2)(?=.* ((?>\5?).)).)* \5$


Try it online! - PCRE2
Try it online! - .NET

This is the PCRE version ported to be compatible with .NET, replacing possessive quantifiers with atomic groups.

# Regex (PCRE / Ruby), 87 bytes

^((?=(.))(?!(.*?\2(?=.*
(\5?+.*?\2))(?=.*
(\4)))*+.*\2)(?=.*
(\7?+.))(?=.*
(\6)).)*
\6?$ Try it online! - PCRE Try it online! - Ruby This is a port of the 65 byte PCRE version, using back-and-forth copying of \4\5 and \6\7 to avoid use of nested backreferences, which aren't supported by Ruby. For a reason I have yet to determine, this doesn't work on Pythonregex, even its latest version. # Regex (Perl / PCRE / Ruby / .NET), 147 bytes ^((?=(.))(?!(?>(.*?\2(?=((?!.*\2)|.))(?=.* ((?!.*$\4)(?>\6?).*?\2|(?=.*$\4)(?=(?>\6?).*?\2)))(?=.* (\5)))*).*\2)(?=.* ((?>\8?).))(?=.* (\7)).)* \7$


Try it online! - Perl
Try it online! - PCRE2
Try it online! - Ruby
Try it online! - .NET

This is a rather interesting challenge for writing a regex polyglot.

Supporting both Perl and Ruby/.NET is rather difficult. The problem is finding a way to erase the capture group that is created inside a negative lookahead in the PCRE version. Erasing capture groups in situations like this can be a challenge, and to support this combination of regex engines, we can't use negative lookahead (Perl doesn't erase it), a subroutine call (because Ruby's syntax is incompatible with Perl, and .NET doesn't have them), a branch reset group (neither Ruby nor .NET support them), or capture group aliasing or explicit erasure (only .NET has those).

So we must signal to the place where the capture is normally made, to erase it when it needs to be erased. The method I settled upon here is rather convoluted, but it works. (It would be shorter with a lookaround conditional, but we can't one, as Ruby doesn't have them, and .NET's syntax for them is different.) This post is already pretty long, so here's a link to the commented version.

JavaScript (67)

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

• Wanted to post the same solution before I even saw yours Commented Jan 30, 2015 at 7:38

VBScript

172 characters

wscript.echo "boat, boat         = " & s("boat, boat")
wscript.echo "toab, boat         = " & s("toab, boat")
wscript.echo "oabt, toab         = " & s("oabt, toab")
wscript.echo "a, aa              = " & s("a, aa")
wscript.echo "zzz, zzzzzzzz      = " & s("zzz, zzzzzzzz")
wscript.echo "zyyyzzzz, yyzzzzzy = " & s("zyyyzzzz, yyzzzzzy")
wscript.echo "sleepy, pyels      = " & s("sleepy, pyels")
wscript.echo "p,p                = " & s("p,p")

function s(a):b=split(replace(a," ",""),","):c=0:for x=1 to len(b(0)):if instr(b(1),mid(b(0),x,1)) then c=c+1
next:if len(b(1))-c=0 then s=true else s=false
end function


I was kinda suprised I could get it under 200.

• 131 characters if I pass the values seperatly. function s(a,b):c=0:for x=1 to len(a):if instr(b,mid(a,x,1)) then c=c+1 next:if len(b)-c=0 then s=true else s=false end function
– user775
Commented Mar 9, 2011 at 14:40

Ruby (40)

a.unpack('c*').sort==b.unpack('c*').sort

• I've formatted your code for you. The tool bar above the edit box has the most commonly used functions, and the sidebar has a link to more detailed info. Commented Mar 9, 2011 at 6:47

Another Ruby (46)

(a.size==b.size)&&(a<<b.count(a,b)==a<<b.size)


C function (147 chars), using brute-force

int c(char*x,char*y){int i=0,l=0;for(;y[l]&&x[l];l++);if(y[l]||x[l])return 0;
while(*x&&i!=l){for(i=0;i<l&&y[i]!=*x;i++);y[i]=0,x++;}return(i!=l);}


## Ruby (39)

Accepts the input as given in the question. Run with ruby -n.

$cat t.rb$_=~/, /;p $'.chars.sort==$.chars.sort

$echo -n "word, wrdo" | ruby -n t.rb true  • Finally a nice solution that works! Commented Feb 3, 2014 at 0:09 • (Two years later...) You can omit the first three characters ($_=). In -n mode ~/x/ is equivalent to /x/ =~ $_. You can also omit the space between p and $. Commented Aug 18, 2016 at 5:29

# Ruby 1.9 - 32

x=->{gets.chars.sort}
p x[]==x[]

• Cool! x=->{gets.sum} passes the test cases but is kind of a cheat. Commented Mar 17, 2011 at 16:18
• BTW, why 1.9.1 and not 1.9.2? It works in 1.9.2. Commented Mar 17, 2011 at 16:19
• That's just the version of Ruby 1.9 I have. Commented Mar 17, 2011 at 20:40

## R, 77

f=function(x,y)identical(sort(strsplit(x,"")[[1]]),sort(strsplit(y,"")[[1]]))


Sample output:

f("boat","boat")
[1] TRUE
f("toab","boat")
[1] TRUE
f("oabt","toab")
[1] TRUE
f("a","aa")
[1] FALSE
f("zzz","zzzzzzzz")
[1] FALSE
f("zyyyzzzz","yyzzzzzy")
[1] TRUE
f("sleepy","pyels")
[1] FALSE
f("p","p")
[1] TRUE

• Why not simply f=function(x,y) identical(sort(strsplit(x,"")[[1]]),sort(strsplit(y,"")[[1]]))? Commented Oct 19, 2013 at 8:28
• You're completely right! Stupid me! I replaced the code with your solution. Commented Oct 21, 2013 at 9:14

## Matlab: 10 characters without using sort

a*a'==b*b'


Not counting imports, Haskell can do it in 10 chars:

import Data.List
import Data.Function
on(==)sort


Called like this:

λ> on(==)sort "balaclava" "aabllcav"
False

λ> on(==)sort "balaclava" "aabllcava"
True


## Julia - 36

f=s->==(map(sort,map(collect,s))...)


Used as f(["foo", "bar"])

Using a list for calling it kind of feels like cheating though.

43 characters

f=(a,b)->sort(collect(a))==sort(collect(b))


Used as f("foo", "bar")

Both solutions just sort the words and compare the result

Woohoo, my first real CodeGolf submission ^_^

Mathcad, 38 chars including non-character keys

s(a):sort(str2vec(a))


© stands for the Ctrl key.

s(a):=sort(str2vec(a))
f(a,b):=s(a)=s(b)


Converts the strings to vectors (one-dimensional arrays) of symbols' ASCII values, sorts them, then compares the vectors. Input is supplied to function f. Returns 1 on success and 0 on failure.

Example: f("toab","boat") returns 1

# PHP, 44 Bytes

<?=($c=count_chars)($argv[1])==$c($argv[2]);


## Perl, 41 bytes

40 bytes code + 1 for -p.

Since this uses a slightly different trick to the other Perl answers I thought I'd share it. Input is separated by newlines.

@{$.}=sort/./g}{$_="@1"eq"@2"?true:false


Uses the magic variable $. which tracks the line number to store the words, as character lists, in @1 and @2 which are then compared. ### Usage perl -pe '@{$.}=sort/./g}{$_="@1"eq"@2"?true:false' <<< 'wrdo word' true perl -pe '@{$.}=sort/./g}{$_="@1"eq"@2"?true:false' <<< 'word wwro' false perl -pe '@{$.}=sort/./g}{\$_="@1"eq"@2"?true:false' <<< 'boat
toba'
true


# Python, 151, 89 bytes

Handles arbitrarily many inputs from stdin. Comma separated, one pair per line.

import sys
f=sorted
for l in sys.stdin:a,b=l.split(',');print f(a.strip())==f(b.strip())

• Mwahaha, first time I see a Python solution longer than C# :) Commented Mar 8, 2011 at 16:05
• Won't this return True for aab, bba? Commented Mar 8, 2011 at 20:28
• @gnibbler; Yes, it will, I wasn't thinking this morning. Fixed Commented Mar 9, 2011 at 1:52

# Brachylog, 2 bytes

pᵈ


Try it online!

The p predicate is essentially a declaration that the variables on either side of it are permutations of each other. The ᵈ meta-predicate modifies the predicate to which it is attached to interpret the input variable as a list of two items, which are effectively placed on either side of the predicate (with the output variable being unified with the second element of the input). So, given a pair of strings as input, the predicate pᵈ will succeed if they are anagrams, and fail if they are not.

If anyone's suspicious of the header on TIO, it just goes through the list of test cases and prints a list of "true"/"false" values based on whether the predicate succeeded or failed for each case. The predicate can be run as a standalone program that prints "true." if it succeeds for the single test case it is given and "false." if it fails.

• Caveat (?): takes a list of two strings, doesn't do anything to parse a one-string input, some people seem to have been worried about that on their answers but those were also different times so I'm not sure what to think Also, technically, the one-byte p would count, but I'd have a hard time justifying that as an answer (plus it's nice to finally have a good use for the declare metapredicate). Commented Mar 1, 2019 at 3:18

# Curry, 49 bytes

Tested in PAKCS

e#x=e:x
e#(x:y)=x:e#y
p(x:y)=x#p y
p[]=[]
(=:=).p


Try it online!

Try it on Smap!

This returns True if inputs are anagrams and nothing otherwise.

## Explanation

This is a really fun Curry solution. First we define a function p which gives a non-deterministic permutation of the input.

Then our submission is just (=:=).p. Written more normally this is:

f x y = p x =:= y


Meaning it tries to bind y to a permutation of x. If they are anagrams this succeeds and gives True, if they are not there is no binding and we get nothing.

• 31 bytes. Commented Apr 11, 2022 at 9:01

# Pyth 10 7

qFSMczd


Takes input as two space-separated words.

Try it here.

Essentially, it splits the elements into an array, sorts each element, and checks if the elements are unique.

My first attempt at Code Golf. Any advice appreciated :o)

• I got this to 8 bytes: !.{SMczd. If you accept input in the form ['wrod','word'], you can get it to 6 bytes: !.{SMQ. Commented Aug 3, 2015 at 21:15
• Also, you can replace !.{ with qF, giving you 7 bytes with the current input method and 5 with the other one I mentioned. Commented Aug 3, 2015 at 21:17
• Thank you both! I made a note mentioning how the answer is valid for the problem, and changed my code accordingly. Commented Aug 4, 2015 at 14:15

# Vyxal, 2 bytes

Þ⊍


Try it Online!

Takes two strings pushed separately onto the stack as input. Returns inverted output (falsey if the strings are anagrams of each other, truthy if they are not).

Þ⊍  # Multiset Symmetric Difference - yields a list of the characters in A that
# aren't in B and the characters in B that aren't in A. Will be empty iff A
# is an anagram of B.


# Vyxal, 3 bytes

Þ⊍¬


Try it Online!

Takes two strings pushed separately onto the stack as input. Returns 1 if the strings are anagrams of each other and 0 otherwise.

Þ⊍  # Multiset Symmetric Difference - yields a list of the characters in A that
# aren't in B and the characters in B that aren't in A. Will be empty iff A
# is an anagram of B.
¬   # Logical Not - When used on a list (as is the case here) returns 1 for an
# empty list and 0 for a non-empty list (even a list containing one 0 in it)


# Vyxal, 3 bytes

vs≈


Try it Online!

Takes a list of two strings as input. Returns 1 if the strings are anagrams of each other and 0 otherwise.

vs  # Vectorized sort (sort the characters in each individual item)
≈   # All Equal


# Knight, 92 68 bytes

Saved 21 bytes (and indirectly 3 more) thanks to Bubbler

O?C=sB;=wP;=j~9;W=j+1j;=i 8Wi=wI>=bGw i 1=aGw=i-i 1 1wSw i 2+b a wCs


Try it online!

### Explanation

Sorts both strings using a bubble-sort algorithm and checks if they are equal. The sorting algorithm takes advantage of the "input will be ... no longer than 8 chars" rule.

Ungolfed:

;= sort_input BLOCK
;= word PROMPT
;= j ~9
;WHILE = j (+ 1 j)
;= i 8
:WHILE i
:= word
;= char2 GET word i 1
;= char1 GET word (= i (- i 1)) 1
:IF > char2 char1
:word
:SUB word i 2 (+ char2 char1)
:word
:OUTPUT ? (CALL sort_input) (CALL sort_input)

• 71B: O?C=sB;=wP;=j~9;W=j+1j;=i~1W>9=i+1i=wI<=xGw+1i 1=yGw i 1wSw i 2+x y wCs Changes: move ;=wP into the block body; use return value of C to avoid =v w; move increments into the loop condition; store 1-char substrings in variables; swap two branches of I to save a space. Commented Aug 2, 2022 at 23:37
• @Bubbler Thanks! I started thinking of blocks as subroutines because they don't take arguments--forgot that they do have return values. I found another golf by running the i loop in the opposite direction and updating i in the loop body instead of the header. Commented Aug 4, 2022 at 4:06

# Knight, 59 52 bytes

O?C=bB;=aP;=x*"0"128;Wa;=xSxAa 1+1GxAa 1=aGa 1La xCb


Try it online!

For both inputs, it creates a 128-character string of 0s, then iterates through the input and increases the value in the index associated with the ASCII code of the given character. Finally, it compares these strings.

This only works because the input strings are less than 8 characters, meaning there can be at most 8 of a single character (less than the 9 that can be stored in a single index by this encoding).

Expanded code:

;=b BLOCK
;=a PROMPT
;=x *"0" 128
WHILE a
;= x (SET x (ASCII a) 1 (+1 (GET x (ASCII a) 1))
= a (GET a 1 (LENGTH a))
;CALL b
;=y x
;CALL b
OUTPUT (? x y)


-7 bytes from @Bubbler

• 52 bytes O?C=bB;=aP;=x*"0"128;Wa;=xSxAa 1+1GxAa 1=aGa 1La xCb using the same refactor as DLosc's solution. Commented Aug 4, 2022 at 6:28

# Knight, 51 bytes

O?C=cB;=iP;=x*'0'256;Wi;=xSx=aAiT+1Gx aT=iSiF1""xCc


Try it online!

This challenge was made a lot easier because inputs were length 8 maximum. That way, we could have a string of length 256, where each index is the amount of times that byte appeared in a word. Then, we can just compare them.

Ungolfed and reorganized slightly, with copious comments:

# Create a new block (ie a niladic function) named char_counts.
; = char_counts BLOCK
# Set i to the input from stdin.
; = input PROMPT

# Set x to a string of 256 0s. The number at each
# index keeps track of how many times that ascii code
# has been seen.
; = counts * '0' 256

# while input isn't empty
; WHILE input
# Set the variable ascii_code to the ascii codepoint
# of the first character. If ASCII is given a string
# that's more than one character long, it uses the first.
; = ascii_code ASCII input

# Set the variable new_count to one more than the
# previous value at ascii_code within counts. This
# will coerce the GET result to an integer, which is
; = new_count + 1 (GET counts ascii_code 1)

# Update counts by replacing the character at ascii_code
# (or, more precisely, the range ascii_code..ascii_code+1)
# with the new, updated count.
: = counts SET counts ascii_code 1 new_count

# The last value of a BLOCK is its return value. Here,
# we return the occurances of each byte.
: counts

# Finally, print out whether calling char_counts twice
# in a row yields the same count of characters.
: OUTPUT ? (CALL char_counts) (CALL char_counts)

• You put the language as C (gcc).... but the code is written in Knight. Commented Aug 14, 2022 at 23:26
• Oh true, thanks for catching that Commented Aug 15, 2022 at 17:00
• Just a note: this link doesn't work: github.com/knight-lang/knight/knight.kn (it's linked on the language page: github.com/knight-lang/knight-lang). Commented Aug 15, 2022 at 20:05

# Thunno 2, 3 bytes

€Ṡạ


Attempt This Online!

#### Explanation

€Ṡạ  # Implicit input
€    # Apply to both strings:
Ṡ   #  Sort the string
ạ  # Are they both equal?
# Implicit output


Yet another Python answer :). (43 characters including whitespace)

This also includes reading in input and displaying output.

i,s=raw_input,sorted
print s(i())==s(i())


Matlab (24)

Given two strings a and b.

isequal(sort(a),sort(b))
`