[Week Two] Programming Contest - Anagram Checker

Welcome to week two of the weekly programming contests! As always, you can find the rules and information on the contests Posted Here

This weeks challenge: is to write a method that checks whether or not two words are anagrams. It should take in exactly two String parameters, and return true if they are anagrams, and false if they are not. Remember to also make the method public and static. For this challenge, Imports Are Allowed!

If you do not know what an anagram is, Google defines it as “a word, phrase, or name formed by rearranging the letters of another, such as cinema, formed from iceman”

For the purposes of this challenge an anagram will be only a single word (no spaces) and one that must be formed by the use of ALL the letters of another word

Examples:

anagram(“cinema”, “iceman”) -> true
anagram(“mary”, “army”) -> true
anagram(“kill”, “bill”) -> false
anagram(“hated”, “death”) -> true
anagram(“pneumonoultramicroscopicsilicovolcanoconiosis”, “Hi”) -> false

Challenge Closes: Sunday 11/15/15

As always, Good Luck!

272 characters :

public static boolean anagram(String s1,String s2){char[]l=s1.toCharArray();if(l.length!=s2.length())
return false;for(char c:s2.toCharArray())
if(!c(l,c))
return false;return true;}
public static boolean c(char[]l,char c){for(char n:l)
if(n==c)
return true;return false;}

Readable version : 351 characters :

public static boolean anagram(String s1, String s2) {
	char[] l = s1.toCharArray();
	if (l.length != s2.length())
		return false;
	for (char c : s2.toCharArray())
		if (!c(l, c))
			return false;
	return true;
}

public static boolean c(char[] l, char c) {
	for (char n : l)
		if (n == c)
			return true;
	return false;
}

Do we have to use Java? Because in D:

bool anagram(string s1, string s2) {
    return s1.dup.sort == s2.dup.sort;
}

That’s all you need. :slight_smile:

Yes, and that’s exactly why :stuck_out_tongue:

149 characters

public static boolean b(String...s){char[] a=s[0].toCharArray();char[] b=s[1].toCharArray();Arrays.sort(a);Arrays.sort(b);return Arrays.equals(a,b);}

Readable version

public static boolean b(String...s){
   char[] a = s[0].toCharArray();
   char[] b = s[1].toCharArray();
   Arrays.sort(a);
   Arrays.sort(b);
   return Arrays.equals(a,b);

}

123 characters

public static boolean a(String...s){return Arrays.equals(s[0].chars().sorted().toArray(),s[1].chars().sorted().toArray());}

Readable version

public static boolean a(String... s) {
    return Arrays.equals(s[0].chars().sorted().toArray(),s[1].chars().sorted().toArray());
}

@obnoxint @Adikso @CodeCrafter47 Your answers are invalid; imports (including java.util.Arrays) are not allowed. Never mind. I misread the problem.

My answer (211 characters):

public static boolean anagram(String o,String t){char[]c=o.toCharArray();char[]d=t.toCharArray();int i=0;for(int j=0;j<d.length;j++)if (c[i]==d[j]){if(++i==c.length)return i==d.length;d[j]=0;j=-1;}return false;}

Ungolfed version, with some debugging code:

public static boolean anagram(String o, String t) {
    char[] c = o.toCharArray();
    char[] d = t.toCharArray();
    int i = 0;
    for(int j = 0; j < d.length; j++) {
        // Start of debug code
        System.out.println("\n " + java.util.Arrays.toString(c).replace('\0','_'));
        for(int n=0; n < i; n++) System.out.print("   ");
        System.out.println("  ^");
        System.out.println(" " + java.util.Arrays.toString(d).replace('\0','_'));
        for(int n=0; n < j; n++) System.out.print("   ");
        System.out.println("  ^");
        // End of debug code
        if (c[i] == d[j]) {
            if (++i == c.length) return i == d.length;
            d[j] = 0;
            j = -1;
        }
    }
    return false;
}

Imports are perfectly valid.

Okay, never mind then. I misread it.

You must have exactly two String params.

I would kinda appreciate it if people didn’t try and get around the rules, but I changed the wording in the thread anyways.

136 Characters

With white space

public static boolean c(String... a) {
    return Arrays.stream(a).map(d -> Arrays.toString(d.chars().sorted().toArray())).distinct().count() < 2;
}

Minified:

public static boolean c(String...a){return Arrays.stream(a).map(d->Arrays.toString(d.chars().sorted().toArray())).distinct().count()<2;}

Noone tried to get around the rules and you just changed them in the middle of the competition.

“Should” means recommended. The term you were looking for is “must”, which means absolute requirement.

1 Like

To be fair, if you’re going to use a vararg, you should at least properly check that there are a minimum of two strings instead of just assuming there are. I consider potential, non-handled exceptions as code failure.

If we don’t care about possible exceptions and incorrect returns, we may as well just assume that this method will return false most of the time, and finish it by just automatically returning it as such.

public static boolean anagram(String... s){return false;}

Just my two cents.

“should”, “consider”, “may”… You just turned this little game into a farce. Nothing of this is agreed upon and you just make things up to feel morally predominant.

Those are my two cents.

wat. I’m not even the one who posted this challenge…

Similar to @jus1in and @CodeCrafter47’s solution

public static boolean a(String a,String b){return Arrays.equals(a.chars().sorted().toArray(),b.chars().sorted().toArray());}

Length: 124

That is a lot closer to @CodeCrafter47’s solution. Only a few characters different actually.

Not a winner, but here’s an alternative, recursive solution:

public static boolean areAnagrams(String a, String b) {
	return a.length() == b.length() && (a.length() > 0 ? areAnagrams(a.substring(1), b.replaceFirst(a.substring(0, 1), "")) : true);
}

Shortened; 146 characters:

public static boolean a(String a,String b){int c=a.length();return c==b.length()&(c>0?a(a.substring(1),b.replaceFirst(a.substring(0,1),"")):1>0);}

It should be noted that this works only if the parameters do not contain a character that has a special meaning as a regex pattern. All letters is fine.

1 Like

Not the shortest but I wanted to try to solve it without using recursion or imports:

public static boolean a(String a,String b){char[][]c={a.toCharArray(),b.toCharArray()};int m=(8<<28)-1,x=m,l=c[0].length;if(c[1].length!=l)return false;for(char[]i:c){int d=0,p=0;while(d<l){for(int q=d;q<l;q++)if(i[q]<x)x=i[p=q];x=i[p];i[p]=i[d];i[d++]=(char)x;x=m;}}for(x=0;x<l;)if(c[0][x]!=c[1][x++])return false;return true;}

328 characters. It sorts the char arrays in place using selection sort then compares the resulting arrays.

Edit: enlongened version:

[code]static boolean isAnagram(String a, String b) {
char[][] chars = {a.toCharArray(), b.toCharArray()};
int maxInt = (8<<28)-1, x = maxInt, length = chars[0].length;
if (chars[1].length != length) return false;

for (char[] i : chars) {
    int cursor = 0, pointer = 0;
    
    while (cursor < length) {
        for (int pos = cursor; pos < length; pos++)
            if (i[pos] < x) x = i[pointer = pos];
        
        x = i[pointer];
        i[pointer] = i[cursor];
        i[cursor++] = (char)x;
        x = maxInt;
    }        
}

for (x = 0; x < length;) {
    if (chars[0][x] != chars[1][x++]) return false;
}
    
return true;

}[/code]

Congratulations to @simon816 for winning this weeks programming contest! The next challenge will be posted shortly!