5
\$\begingroup\$

This is an easy one.

Anagrams are words which have the same characters but in different order. All you have to do is to figure out if two strings are anagram or not.

Rules:

  • Take two strings as a function argument, command-line argument or from standard input.
  • Write a function or program which returns truthy value if strings are anagram, falsy value otherwise
  • Anagrams may have different number of spaces () characters in them.
  • Anagrams are case insensitive matches.
  • Anagrams can only have printable ASCII characters for this code-golf.

For example(taken from the Wikipedia page itself): Doctor Who is an anagram of Torchwood . Note missing space and lack of capital D and W in Torchwood

This is code-golf so minimum bytes code win!

Happy golfing.

\$\endgroup\$
11
  • \$\begingroup\$ Done - Edited to clarify \$\endgroup\$
    – Optimizer
    Sep 12, 2014 at 7:40
  • \$\begingroup\$ If that is considered as standard input (STDIN) then yes. \$\endgroup\$
    – Optimizer
    Sep 12, 2014 at 7:54
  • \$\begingroup\$ printable ascii or alphanumeric? what about ,:;...? \$\endgroup\$
    – edc65
    Sep 12, 2014 at 8:49
  • \$\begingroup\$ @MartinBüttner No objection against ARGV from my side. Feel free to edit the question to point it out in clear words as I might not be able to make it clear. \$\endgroup\$
    – Optimizer
    Sep 12, 2014 at 9:43
  • \$\begingroup\$ @edc65 Well, these are just words, not sentences, so ideally those characters should not appear. But if they do, they are to be considered. Same for numbers \$\endgroup\$
    – Optimizer
    Sep 12, 2014 at 9:44

12 Answers 12

4
\$\begingroup\$

Java, 146 131 144 134 131 128

Not a very exciting answer. Returns true for anagrams, false for others. Actually works now. Cheapass abuse of generics in class declaration.

boolean b(T a,T b){return c(a).equals(c(b));}T c(T a){char[]c=a.toLowerCase().toCharArray();sort(c);return(T)valueOf(c).trim();}

Ungolfed:

boolean b(T a,T b) {
    return c(a).equals(c(b));
}

T c(T a) {
    char[] c = a.toLowerCase().toCharArray();
    sort(c);
    return (T) valueOf(c).trim();
}
\$\endgroup\$
4
  • 1
    \$\begingroup\$ mmm... cat and faq? \$\endgroup\$
    – edc65
    Sep 12, 2014 at 9:52
  • \$\begingroup\$ Two different strings can have the same ASCII sum. Take, for e.g., the strings "bb"(98 + 98) and "ac"(97 + 99). \$\endgroup\$
    – c.P.u1
    Sep 12, 2014 at 10:10
  • \$\begingroup\$ Is valueOf a static import? \$\endgroup\$
    – nanofarad
    Sep 12, 2014 at 10:32
  • \$\begingroup\$ yeah, same with sort \$\endgroup\$
    – carnifex
    Sep 12, 2014 at 10:34
3
\$\begingroup\$

CJam, 15 11 bytes

Just thought I'd practice CJam a bit more. This is basically the same as my Ruby answer (or most answers):

ea{S-el$}/=

Quick explanation

ea          "Push command line arguments";
ea{     }/  "For each element in that array";
ea{S-   }/  "Push a space character onto the stack and remove spaces from string";
ea{S-el }/  "Convert string to lower case";
ea{S-el$}/  "Sort the characters in the string";
ea{S-el$}/= "Check for equality";

Prints 1 for anagrams and 0 otherwise.

\$\endgroup\$
1
  • \$\begingroup\$ 1. Brackets can be unmatched in CJam, so you don't need the [ in [ll]. ea would be even shorter; it pushes all command-line arguments as an array. Doesn't work with the online interpreter though... 2. S is initialized to " ", so you can use it instead of ' . 3. You can replace %~ with /. \$\endgroup\$
    – Dennis
    Sep 14, 2014 at 5:12
3
\$\begingroup\$

Rebol   44   40

(Rebol 2)

Define a function m which takes two values a and b. Sort each string, trim the whitespace and use = to check if the strings are the same.

m: func[a b][(trim sort a)= trim sort b]

m: func[a b][equal? trim sort a trim sort b]

Example

>> m: func[a b][(trim sort a)= trim sort b] 
>> m "Doctor Who" "Torchwood"             
== true

It is useful handy that sort is case insensitive by default. Note: This function does have side effects if you use this code elsewhere as sort modifies a and b directly.

(sort should work in Rebol 3 but doesn't as there is a known bug)

\$\endgroup\$
6
  • 1
    \$\begingroup\$ Yes ... :( <backs slowly away from keyboard and slaps forehead> \$\endgroup\$
    – johnk
    Sep 12, 2014 at 11:58
  • \$\begingroup\$ That should work. Just a few chars longer \$\endgroup\$
    – johnk
    Sep 12, 2014 at 12:05
  • \$\begingroup\$ Wait, I don't understand. Just because sort sorts case insensitively, how does that make equal? work on strings of different cases? \$\endgroup\$ Sep 12, 2014 at 12:06
  • \$\begingroup\$ Oh equal? itself is case insensitive, too. That's... handy. \$\endgroup\$ Sep 12, 2014 at 12:08
  • \$\begingroup\$ and same? "ABC" "abc" is false :) Also has the shorthand "ABC" == "abc" - double equal signs means really equal! \$\endgroup\$
    – johnk
    Sep 12, 2014 at 12:11
3
\$\begingroup\$

Ruby, 65 60 58 57 51 48 46 bytes

s,t=$*.map{|u|u.upcase.scan(/\S/).sort};p s==t

Edit: Switched to STDIN to save a few bytes.

Edit: Switched to ARGV to save three more bytes.

Quite long for such a simple problem, hmmmm.

  • For each string:
    • Turn to upper case (to make it case in-sensitive).
    • Split into non-whitespace characters.
    • Sort (by character code).
  • Then check that the results are equal.
\$\endgroup\$
1
  • \$\begingroup\$ Wow everything i would like to have in C# - nice one +1 \$\endgroup\$ Sep 12, 2014 at 8:27
2
\$\begingroup\$

JavaScript (ES6) 68 99

Generate a key for each word and compare them. If only JS had some shorter ucase method...

A=(a,b,k=s=>[...s.toUpperCase()].sort().join('').trim())=>k(a)==k(b)
\$\endgroup\$
3
  • \$\begingroup\$ You always bring in unique techniques to the table :) \$\endgroup\$
    – Optimizer
    Sep 12, 2014 at 10:04
  • \$\begingroup\$ @Optimizer you're kind, but nothing new here, this is really a standard way to handle anagrams \$\endgroup\$
    – edc65
    Sep 12, 2014 at 10:07
  • \$\begingroup\$ No, I was talking about the declare a second method in the third argument and use it to save space trick. \$\endgroup\$
    – Optimizer
    Sep 12, 2014 at 10:09
2
\$\begingroup\$

Python 3 -- 73 67 bytes


Code:

f=lambda:sorted(i for i in input().upper()if" "!=i);print(f()==f())

As usual, nice looking, but not very short. Typical python...

\$\endgroup\$
2
  • \$\begingroup\$ Does a#b count as an word? Fixed. \$\endgroup\$
    – matsjoyce
    Sep 12, 2014 at 10:26
  • \$\begingroup\$ The challenge asks for printable ASCII, so all characters except spaces should be treated as "letters" for the purposes of the challenge. \$\endgroup\$ Sep 12, 2014 at 10:26
2
\$\begingroup\$

Cobra - 130

do(a='',b='')
    print (f=Func<of String,String>(do(s='')=s.toLower.toCharArray.toList.sorted.join('').trim)).invoke(a)==f.invoke(b)
\$\endgroup\$
1
  • 2
    \$\begingroup\$ Sorted first, then tolower: couldn't this create problems? \$\endgroup\$
    – edc65
    Sep 12, 2014 at 10:37
1
\$\begingroup\$

JavaScript (ES6) 82

Returns true if the two strings are anagrams, otherwise returns false or throws an exception

e=(a,b)=>(a.replace(/\S/g,c=>b=b.replace(b.match(RegExp(c,'i'))[0],'')),!b.trim())
\$\endgroup\$
2
  • \$\begingroup\$ "or throws an exception" violates the rules, though. That's not a falsy value as required. \$\endgroup\$
    – Ingo Bürk
    Sep 12, 2014 at 19:58
  • \$\begingroup\$ Throwing makes this an invalid entry :( \$\endgroup\$
    – Optimizer
    Sep 12, 2014 at 21:41
1
\$\begingroup\$

Perl - 84

Always need Perl in these...

sub c{map{s/\s//}@a=@_;(join'',sort split//,lc$a[0])eq join'',sort split//,lc$a[1]}

Wanted to be able to modify @_ directly but perl wont allow that

\$\endgroup\$
2
  • \$\begingroup\$ How should this be called? It doesn't seem to return a result. \$\endgroup\$ Sep 13, 2014 at 16:34
  • \$\begingroup\$ It returns a 1 or a 0 ---> print c('Doctor Who','Torchwood') ? 'Yes' : 'No'; \$\endgroup\$
    – mcreenan
    Sep 16, 2014 at 23:37
1
\$\begingroup\$

Bash+coreutils, 62 bytes

s()(tr -d '     '<<<"${@^^}"|fold -1|sort)
cmp <(s $1) <(s $2)

Takes arguments from the command line. Return code 0 for TRUE and 1 for FALSE. Also something like /dev/fd/63 /dev/fd/62 differ: byte 1, line 1 is output in the FALSE case.

Output:

$ ./anagram.sh "Doctor Who" Torchwood; echo $?
0
$ ./anagram.sh "Doctor Watson" Torchwood; echo $?
/dev/fd/63 /dev/fd/62 differ: byte 1, line 1
1
$ 
\$\endgroup\$
1
\$\begingroup\$

Clojure : 84 chars

Golfed:

(defn g[s](sort(remove #(= \  %)(seq(.toLowerCase s)))))
(defn f[a b](=(g a)(g b)))

Ungolfed:

(defn g[s] (sort (remove #(= \  %) (seq (.toLowerCase s)))))
(defn f[a b] (= (g a) (g b)) )

Driver program with execution:

(def a "Doctor   Who")
(def b "Torch woo d")
(println (f a b))

bash$ java -jar clojure-1.6.0.jar anagram.clj 
true
\$\endgroup\$
0
\$\begingroup\$

Groovy : 96 77 chars

Golfed:

g={it.findAll{it!=" "}.collect{it.toLowerCase()}.sort()}
f={a,b->g(a)==g(b)}

Ungolfed:

g = { it.findAll{ it!=" " }.collect{ it.toLowerCase() }.sort() }
f = { a,b -> g(a)==g(b) }

Example main program and execution:

a="Doctor Who x x"
b="Tor chwoo dxx"
println f(a,b)

$ groovy Anagram.groovy
$ true
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.