24 votes

Programming Challenge: Anagram checking.

It's been over a week since the last programming challenge and the previous one was a bit more difficult, so let's do something easier and more accessible to newer programmers in particular. Write a function that takes two strings as input and returns true if they're anagrams of each other, or false if they're not.

Extra credit tasks:

  • Don't consider the strings anagrams if they're the same barring punctuation.
  • Write an efficient implementation (in terms of time and/or space complexity).
  • Minimize your use of built-in functions and methods to bare essentials.
  • Write the worst--but still working--implementation that you can conceive of.

57 comments

  1. [2]
    joelthelion Link
    Haskell is pretty cool :)

    (\f x y -> f x == f y) (sort . map toLower . filter isAlpha)

    Haskell is pretty cool :)

    10 votes
  2. [4]
    bee (edited ) Link
    This was fun! I'm doing this one in go. I'm fairly new to go, so if I'm making any obvious mistakes feel free to point them out :) package main import ( "fmt" "sort" "strings" ) func main() { one...

    This was fun! I'm doing this one in go. I'm fairly new to go, so if I'm making any obvious mistakes feel free to point them out :)

    package main
    
    import (
    	"fmt"
    	"sort"
    	"strings"
    )
    
    func main() {
    	one := testAnagram([]string{"yes", "no"})
    	two := testAnagram([]string{"HoSe", "shoE"})
    	fmt.Println(one, two)
    }
    
    func testAnagram(str []string) bool {
    
    	for i := range str {
    		str[i] = strings.ToLower(str[i])
    		temp := strings.Split(str[i], "")
    		sort.Strings(temp)
    		str[i] = strings.Join(temp, "")
    	}
    
    	return str[0] == str[1]
    }
    

    Edited with /u/Emerald_Knight's findings.

    3 votes
    1. [3]
      Emerald_Knight Link Parent
      Almost! Consider the following test case: three := testAnagram([]string{"Hose", "shoe"}) These should evaluate as being anagrams, but don't :)

      Almost! Consider the following test case:

      three := testAnagram([]string{"Hose", "shoe"})
      

      These should evaluate as being anagrams, but don't :)

      2 votes
      1. [2]
        bee Link Parent
        You're right! I completely forgot about letter casing. I've edited the comment :)

        You're right! I completely forgot about letter casing. I've edited the comment :)

        2 votes
        1. Emerald_Knight Link Parent
          Ah, right, I think there's also a problem with punctuation. I forgot to bring that up. Anagrams should generally be punctuation-agnostic :)

          Ah, right, I think there's also a problem with punctuation. I forgot to bring that up. Anagrams should generally be punctuation-agnostic :)

  3. [8]
    panic Link
    A C solution that counts characters: bool is_anagram_of(char *a, char *b) { size_t counts[256] = {0}; for (; *a; ++a) counts[tolower(*a)] += (bool)isalpha(*a); for (; *b; ++b) counts[tolower(*b)]...

    A C solution that counts characters:

    bool is_anagram_of(char *a, char *b)
    {
        size_t counts[256] = {0};
        for (; *a; ++a)
            counts[tolower(*a)] += (bool)isalpha(*a);
        for (; *b; ++b)
            counts[tolower(*b)] -= (bool)isalpha(*b);
        for (int i = 0; i < 256; ++i) {
            if (counts[i] != 0)
                return false;
        }
        return true;
    }
    
    3 votes
    1. [3]
      joelthelion Link Parent
      Very nice! But it doesn't work with Unicode :-p

      Very nice! But it doesn't work with Unicode :-p

      1. [2]
        panic Link Parent
        Yeah, that's a much harder problem. In Turkish, for example, "William Shakespeare" is not an anagram for "I am a weakish speller" because the lowercase version of "I" is "ı", not "i".

        Yeah, that's a much harder problem. In Turkish, for example, "William Shakespeare" is not an anagram for "I am a weakish speller" because the lowercase version of "I" is "ı", not "i".

        1 vote
        1. Emerald_Knight Link Parent
          Yeah, I give a pass on unicode because then you need to have localization awareness in order to maintain accuracy, and that's beyond the scope of a quick programming challenge and begins to dive...

          Yeah, I give a pass on unicode because then you need to have localization awareness in order to maintain accuracy, and that's beyond the scope of a quick programming challenge and begins to dive into a full-blown project that could take a very long time to get right, and even then you're likely to miss some edge cases. ASCII is sufficient for the purposes of this challenge :)

    2. Emerald_Knight Link Parent
      A very space-efficient array version. I like the zero-offset check!

      A very space-efficient array version. I like the zero-offset check!

    3. [3]
      Gyrfalcon Link Parent
      I have never seen that for loop syntax with pointers before. Googling it gives a lot of results with char arrays, but can it be generalized to other types of arrays?

      I have never seen that for loop syntax with pointers before. Googling it gives a lot of results with char arrays, but can it be generalized to other types of arrays?

      1. [2]
        panic Link Parent
        Yes! The same syntax works for any array that ends with a zero. It's common for char arrays because strings in C are represented by char arrays ending in a zero byte (by convention).

        Yes! The same syntax works for any array that ends with a zero. It's common for char arrays because strings in C are represented by char arrays ending in a zero byte (by convention).

        1 vote
        1. Gyrfalcon Link Parent
          Ah okay, so if I were to use it on a numeric array I would need to ensure that it has a terminating 0. I'll have to play with that a bit. Thanks!

          Ah okay, so if I were to use it on a numeric array I would need to ensure that it has a terminating 0. I'll have to play with that a bit. Thanks!

          1 vote
  4. [4]
    teaearlgraycold (edited ) Link
    def anagram(*words): normalized = [sorted(word.lower()) for word in words] return all(word == normalized[0] for word in normalized) I always feel icky writing functions like this that work on...
    def anagram(*words):
        normalized = [sorted(word.lower()) for word in words]
        return all(word == normalized[0] for word in normalized)
    

    I always feel icky writing functions like this that work on specifically two inputs. So I've generalized the code to work with 0 or more strings (providing 0 or 1 string will always result in a True return value).

    Edit:

    O(n * m) runtime! :D (where the average word length is n and there are m words).

    from collections import Counter
    
    def anagram(*words):
        normalized = [Counter(word.lower()) for word in words]
        return all(word == normalized[0] for word in normalized)
    
    2 votes
    1. [3]
      Emerald_Knight Link Parent
      Different amounts of white space or punctuation will cause the check to fail. I'm liking the variable-length parameters, though! Also, I remember you from the first programming challenge I posted!...

      Different amounts of white space or punctuation will cause the check to fail. I'm liking the variable-length parameters, though!

      Also, I remember you from the first programming challenge I posted! Good to see you here again :)

      1 vote
      1. [2]
        teaearlgraycold Link Parent
        Given that the argument is words and not strings, in my world the programmer should handle that before passing in values :P

        Different amounts of white space or punctuation will cause the check to fail.

        Given that the argument is words and not strings, in my world the programmer should handle that before passing in values :P

        2 votes
        1. Emerald_Knight Link Parent
          Relying on the user to properly strip non-alpha characters? I, too, like to live dangerously ;)

          Relying on the user to properly strip non-alpha characters? I, too, like to live dangerously ;)

          2 votes
  5. [5]
    jono (edited ) Link
    Rust I've only just started learning Rust and have only coded as a hobby. How'd I do? fn main() { let s1 = "anagram".to_string(); let s2 = "nag a ram".to_string(); assert!(anagram(s1, s2)); //...

    Rust

    I've only just started learning Rust and have only coded as a hobby. How'd I do?

    fn main() {
        let s1 = "anagram".to_string();
        let s2 = "nag a ram".to_string();
        assert!(anagram(s1, s2)); // True
    }
    
    fn anagram(s1: String, s2: String) -> bool {
        let sorted_s1 = sort_string(s1);
        let sorted_s2 = sort_string(s2);
        sorted_s1 == sorted_s2
    }
    
    fn sort_string(mut s: String) -> Vec<u8> {
        s.retain(|c| !c.is_whitespace());
        let mut sorted_s = s.to_lowercase().into_bytes();
        sorted_s.sort_unstable();
        sorted_s
    }
    

    Edit: cargo bench puts it at 572 ns/iter (+/- 11) to run the function anagram():

    mod tests {
        use super::*;
        use test::Bencher;
    
        #[bench]
        fn count_letters_bench(b: &mut Bencher) {
            b.iter(|| anagram("nag a ram".to_string(), "anagram".to_string()))
        }
    
    }
    
    2 votes
    1. [3]
      Emerald_Knight Link Parent
      Your solution doesn't appear to account for punctuation. That being said, your solution otherwise appears correct to my non-Rusted eyes :)

      Your solution doesn't appear to account for punctuation. That being said, your solution otherwise appears correct to my non-Rusted eyes :)

      1 vote
      1. [2]
        jono Link Parent
        Change !c.is_whitespace() to c.is_alphabetic() for any alphabetic character, or otherwise c.is_digit(36) for any 0-9 A-z.

        Change !c.is_whitespace() to c.is_alphabetic() for any alphabetic character, or otherwise c.is_digit(36) for any 0-9 A-z.

        1 vote
        1. Emerald_Knight Link Parent
          Yeah, that sounds like it would do it!

          Yeah, that sounds like it would do it!

    2. jono Link Parent
      I decided to modify it to work with more than two strings, the function requiring a vector of strings instead. It is however slightly slower for two strings. fn main() { let s_vec = vec![...

      I decided to modify it to work with more than two strings, the function requiring a vector of strings instead. It is however slightly slower for two strings.

      fn main() {
          let s_vec = vec![
              "anagram".to_string(),
              "nag a ram".to_string(),
              "mana rag".to_string(),
          ];
          assert!(anagram(s_vec));
      }
      
      fn anagram(s_vec: Vec<String>) -> bool {
          let mut sorted_s_vec: Vec<Vec<u8>> = Vec::new();
          for mut s in s_vec {
              s.retain(|c| c.is_alphabetic());
              let mut sorted_s = s.to_lowercase().into_bytes();
              sorted_s.sort_unstable();
              sorted_s_vec.push(sorted_s)
          }
          sorted_s_vec.dedup();
          sorted_s_vec.len() == 1 || sorted_s_vec.len() == 0
      }
      
  6. Crestwave (edited ) Link
    Late, but here's a pure Bash 4+ solution: #!/usr/bin/env bash shopt -s nocasematch set -- "${1//[[:space:]]}" "${2//[[:space:]]}" string=$2 for (( i = 0; i < ${#1}; i++ )); do...

    Late, but here's a pure Bash 4+ solution:

    #!/usr/bin/env bash
    
    shopt -s nocasematch
    set -- "${1//[[:space:]]}" "${2//[[:space:]]}"
    string=$2
    
    for (( i = 0; i < ${#1}; i++ )); do
    	string=${string/"${1:i:1}"}
    done
    
    (( i == ${#2} && ${#string} == 0 ))
    exit
    
    2 votes
  7. [7]
    Emerald_Knight (edited ) Link
    As for me, I've had a long week starting at my new job, so I'm going to keep my solution simple this time: <?php function getSortedLowercaseCharacters($string) { preg_match_all('/([a-zA-Z]+)/',...

    As for me, I've had a long week starting at my new job, so I'm going to keep my solution simple this time:

    <?php
    
    function getSortedLowercaseCharacters($string) {
        preg_match_all('/([a-zA-Z]+)/', $string, $matches);
        
        $words = $matches[0];
        $lower_case_chars = strtolower(implode('', $words));
        $char_array = str_split($lower_case_chars);
        
        sort($char_array);
        
        $sorted_char_string = implode('', $char_array);
        return $sorted_char_string;
    }
    
    function anagramCheck($string1, $string2) {
        $string1_stripped = getSortedLowercaseCharacters($string1);
        $string2_stripped = getSortedLowercaseCharacters($string2);
        
        return $string1_stripped === $string2_stripped;
    }
    
    ?>
    
    1 vote
    1. [6]
      bee Link Parent
      Just out of curiosity, why is PHP your language of choice for programming challenges?

      Just out of curiosity, why is PHP your language of choice for programming challenges?

      1 vote
      1. [5]
        Emerald_Knight Link Parent
        It just happens to be the language I work with professionally at present. Since it's the one I use the most, it's naturally the one I'll turn to when writing up a quick solution to something....

        It just happens to be the language I work with professionally at present. Since it's the one I use the most, it's naturally the one I'll turn to when writing up a quick solution to something. Additionally, me being a web programming makes JavaScript the second most frequently used language for me.

        That being said, it's not my favorite language. Personally, I have a bit of a fondness for Java, though I haven't touched it in quite a while. I've seen some other interesting languages around, too, but I tend not to dabble too much in new, shiny tools and languages very often. I'm very pragmatic and tend to grab tools as I need them or foresee myself needing them.

        2 votes
        1. [4]
          bee Link Parent
          Great response, thanks. What do you enjoy about Java? I've found it a bit, too expressive(?) for my liking.

          Great response, thanks. What do you enjoy about Java? I've found it a bit, too expressive(?) for my liking.

          1 vote
          1. [2]
            teaearlgraycold Link Parent
            You probably mean verbose.

            I've found it a bit, too expressive(?)

            You probably mean verbose.

            3 votes
            1. bee Link Parent
              That's it, thanks.

              That's it, thanks.

          2. Emerald_Knight Link Parent
            I suppose to some extent I find the verbosity of the language to be acceptable in return for the flexibility it can provide, though at times it can be frustrating trying to fiddle with types. I...

            I suppose to some extent I find the verbosity of the language to be acceptable in return for the flexibility it can provide, though at times it can be frustrating trying to fiddle with types. I haven't used it myself, but I imagine Kotlin would be more your cup of tea. I really should try it out sometime myself.

            2 votes
  8. [2]
    jzimbel (edited ) Link
    I wanted to try it without doing a sort, so here's a questionably-readable solution in JavaScript (ES6) that compares the strings by counting instances of each character. const getCharCountObject...

    I wanted to try it without doing a sort, so here's a questionably-readable solution in JavaScript (ES6) that compares the strings by counting instances of each character.

    const getCharCountObject = string =>
      [...string.toLowerCase().replace(/[^a-z]/g, "")].reduce(
        (accumulator, letter) => ({
          ...accumulator,
          [letter]: (accumulator[letter] || 0) + 1
        }),
        {}
      );
    const charCountObjectsEqual = (cc1, cc2) => {
      const firstKeys = Object.keys(cc1);
      return (
        firstKeys.length === Object.keys(cc2).length &&
        firstKeys.every(key => cc1[key] === cc2[key])
      );
    };
    const isAnagram = ([...strings]) =>
      strings.every(string =>
        charCountObjectsEqual(
          getCharCountObject(strings[0]),
          getCharCountObject(string)
        )
      );
    

    Quick tests:

    > isAnagram(['Madam Curie', 'Radium came', 'Radium came.'])
    < true
    > isAnagram(['Edward Gorey', 'Ogdred Weary', 'Regera Dowdy',  'E. G. Deadworry'])
    < true
    > isAnagram(['Madam Curie', 'Rdium came'])
    < false
    
    1 vote
    1. Emerald_Knight Link Parent
      Interesting solution! You really took advantage of JavaScript's feature set. Nicely done :)

      Interesting solution! You really took advantage of JavaScript's feature set. Nicely done :)

  9. [3]
    Staross (edited ) Link
    Julia version, it might be possible to do a non-allocating version, but I'm not sure how. sorted_split(s) = lowercase(s) |> s->split(s,"") |> sort anagram(s1,s2) = all( s1 == s2 for (s1,s2) in...

    Julia version, it might be possible to do a non-allocating version, but I'm not sure how.

    sorted_split(s) = lowercase(s) |> s->split(s,"") |> sort 
    
    anagram(s1,s2) = all( s1 == s2 for (s1,s2) in zip(sorted_split(s1),sorted_split(s2)) )
    
    @assert anagram("yes","no") == false
    @assert anagram("restful","fluster") == true
    @assert anagram("Madam Curie", "Radium came") == true
    
    function test(s)
        f = [anagram(s1,s2)  for (s1,s2) in s]
        mean(f)
    end
    
    s = [(randstring(3),randstring(3)) for i=1:10_000]
    
    Main> @time test(s)
    0.022325 seconds (290.42 k allocations: 15.129 MiB, 25.91% gc time)   
    0.0004
    
    1 vote
    1. [2]
      Emerald_Knight Link Parent
      I don't think your solution accounts for varying punctuation, even whitespace. Julia seems like an interesting language, though, and your solution seems correct otherwise. I'm glad to be seeing...

      I don't think your solution accounts for varying punctuation, even whitespace. Julia seems like an interesting language, though, and your solution seems correct otherwise. I'm glad to be seeing languages in here that I'm not familiar with :)

      1. Staross Link Parent
        Yeah I would need some filter after the split. Julia is awesome, you can write functional-like stuff like that, vectorized, or C-like loops and you basically get the same near-optimal performance....

        Yeah I would need some filter after the split. Julia is awesome, you can write functional-like stuff like that, vectorized, or C-like loops and you basically get the same near-optimal performance. It's better for numerical/scientific computing rather than string processing though.

        1 vote
  10. [8]
    Soptik (edited ) Link
    I've made version without any sorting, so I think, I might have one of the fastest versions here. Time complexity is linear, memory complexity is constant. I've used python, which I've started...

    I've made version without any sorting, so I think, I might have one of the fastest versions here. Time complexity is linear, memory complexity is constant.

    I've used python, which I've started with few days ago.

    first = [ "abc", "def", "ghi" ]
    second = [ "cab", "DeF", "ihg" ]
    
    def encodeString(string):
        string = string.lower()
        total = 0
        for ch in string:
            val = ord(ch) - ord('a')
            # Now I have value of all letters. 
            # 'a' is 0, 'b' is 1, etc... Now, I can set the value to 2^x
            # so 'a' is 1, 'b' is 2, 'c' is 4... This will generate unique number
            # for each word. "ab" is 3, "bc" is 6, "abc" is 7, etc
            total += 2 ** val
    
        return total
    
    
    
    def areStringsAnagrams(string1, string2):
        return len(string1) == len(string2) and encodeString(string1) == encodeString(string2)
    
    
    for i in range(0, 3):
        for j in range(0, 3):
            print(areStringsAnagrams(first[i], second[j]))
    

    Edit: Added syntax highlighting

    1 vote
    1. [6]
      joelthelion Link Parent
      Unfortunately this doesn't work when letters are repeated:

      Unfortunately this doesn't work when letters are repeated:

      In [2]: areStringsAnagrams("aa","b")
      Out[2]: True

      2 votes
      1. [5]
        Soptik Link Parent
        Thank you, this doesn't work when the strings do not have equal length. I've edited it.

        Thank you, this doesn't work when the strings do not have equal length. I've edited it.

        1. [4]
          joelthelion Link Parent
          Unfortunately I can still break it, if I'm not mistaken: I don't think it's possible to fix it.

          Unfortunately I can still break it, if I'm not mistaken:

          In [4]: areStringsAnagrams("aaaac","bbbaa")
          Out[4]: True

          I don't think it's possible to fix it.

          1 vote
          1. [3]
            Soptik Link Parent
            Hm... I think you are right. The problem is with multiple characters. I've wanted to follow Flag logic: enum Result { Ok = 1, Error = 2, IOError = 4, NetworkError = 8, ... } And you can combine...

            Hm... I think you are right. The problem is with multiple characters.

            I've wanted to follow Flag logic:

            enum Result {
                Ok = 1,
                Error = 2,
                IOError = 4,
                NetworkError = 8,
                ...
            }
            

            And you can combine the states:

            res = Result.IOError | Result.NetworkError // 12
            

            The problem is with multiple letters. I think you are right, this problem can be solved without sorting only by counting letters.

            1 vote
            1. [2]
              joelthelion Link Parent
              Exactly, it's the principle of binary numeration, but that decomposition is only unique when each digit is unique.

              Exactly, it's the principle of binary numeration, but that decomposition is only unique when each digit is unique.

              1 vote
              1. Emerald_Knight Link Parent
                For the sake of providing an explanation to less experienced readers: The submitted solution was trying to take advantage of a property of adding powers of 2 that is often used in what are called...

                For the sake of providing an explanation to less experienced readers:

                The submitted solution was trying to take advantage of a property of adding powers of 2 that is often used in what are called "bitmasks", a tool I highly recommend reading up on. The idea is basically that you can tell whether or not something exists by examining a specific bit in the mask.

                The problem is that this only works for existence checking. The reason is because if you add together two identical powers of 2 in the form 2n + 2n, then you get 2n + 2n = 2 x 2n = 2n+1. Thus, the string "ff" will appear equal to "g", for example.

                2 votes
    2. [2]
      Comment deleted by author
      Link Parent
      1. Soptik Link Parent
        You are right, I should use loops, but it was only for me to test if it is working correctly, plus in vim, it's often faster to do it this dumb way instead of loops. But you're right, I'll change it.

        You are right, I should use loops, but it was only for me to test if it is working correctly, plus in vim, it's often faster to do it this dumb way instead of loops.

        But you're right, I'll change it.

        1 vote
  11. [5]
    pseudolobster Link
    Figured I'd try something stupid and convoluted, so I came up with the idea to create two temporary directories, inside which, create a file for each letter in each word, then simply compare the...

    Figured I'd try something stupid and convoluted, so I came up with the idea to create two temporary directories, inside which, create a file for each letter in each word, then simply compare the two directories.

    #!/bin/bash
    t1=$(mktemp -d) && echo $1 | sed -e "s|.|touch $t1/\L&\n|g" | bash
    t2=$(mktemp -d) && echo $2 | sed -e "s|.|touch $t2/\L&\n|g" | bash
    diff $t1 $t2 && { echo Anagrams; }
    

    By the time I finished I realized the flaw of course is that it doesn't account for repeating characters. "foo" and "oooooooooof" are considered anagrams. Oh well. And of course this has numerous other problems as well. Can't deal with spaces or a lot of punctuation. Probably exploitable by directory traversal attacks etc.

    1 vote
    1. [4]
      Emerald_Knight Link Parent
      It may be a non-working solution, but I love the ingenuity! I'm sure that with some modifications, this could be a perfectly horrible implementation :)

      It may be a non-working solution, but I love the ingenuity! I'm sure that with some modifications, this could be a perfectly horrible implementation :)

      1 vote
      1. [3]
        pseudolobster Link Parent
        Alright, well such a thing clearly shouldn't exist, but after smoking a jazz cigarette and a bit of introspection, you've inspired me to finish what I started. #!/bin/bash # #Anagram.sh...

        Alright, well such a thing clearly shouldn't exist, but after smoking a jazz cigarette and a bit of introspection, you've inspired me to finish what I started.

        #!/bin/bash
        #
        #	Anagram.sh
        #	----------
        #	a BASH function for determining if two strings are anagrams.
        #
        #	Usage:
        #	if ./anagram.sh "hello world" "wello horld"; then echo true;fi
        #
        t1=$(mktemp -d); echo $1 | sed -e "s|.|n=$t1/\L&;while [ -f \$n ];do n=\"\$n\${n: -1}\";done;touch \$n\n|g" | bash
        t2=$(mktemp -d); echo $2 | sed -e "s|.|n=$t2/\L&;while [ -f \$n ];do n=\"\$n\${n: -1}\";done;touch \$n\n|g" | bash
        diff $t1 $t2 && { exit 0; } || { exit -1; }
        

        Now it handles duplicate letters just fine. Handles mixed case, handles strings with spaces (though spaces are ignored).

        Still has glaring issues if you try using any special characters such as ! or / or & you'll end up with wildly unexpected results.

        Now I think I need a long shower and to think about what I'm doing with my life.

        2 votes
        1. [2]
          Emerald_Knight Link Parent
          This is simultaneously beautiful and horrifying. Bravo.

          This is simultaneously beautiful and horrifying. Bravo.

          1 vote
          1. pseudolobster Link Parent
            Thanks! Just following the UNIX "everything is a file" philosophy to its logical end.

            Thanks! Just following the UNIX "everything is a file" philosophy to its logical end.

            1 vote
  12. [2]
    burntcookie90 Link
    still in my kotlin comfort zone, heavily leaning on the stdlib fun testAnagram(input1: String, input2: String) = input1.length == input2.length && input1.toLowerCase().toSortedSet() ==...

    still in my kotlin comfort zone, heavily leaning on the stdlib

    fun testAnagram(input1: String, input2: String) = input1.length == input2.length
        && input1.toLowerCase().toSortedSet() == input2.toLowerCase().toSortedSet()
    
    1 vote
    1. Emerald_Knight Link Parent
      It doesn't look like your solution would handle differing whitespace or punctuation. You may want to account for that. That aside, it looks like you're using a very functional programming style. I...

      It doesn't look like your solution would handle differing whitespace or punctuation. You may want to account for that.

      That aside, it looks like you're using a very functional programming style. I haven't used Kotlin myself, so I wasn't aware that this was supported by the language!

  13. Gyrfalcon Link
    I wanted to try my hand at this. I did something a little different, since the most reasonable approach I can think of in C appears to be here already. lazyGram does a few checks that should work...

    I wanted to try my hand at this. I did something a little different, since the most reasonable approach I can think of in C appears to be here already. lazyGram does a few checks that should work in almost all cases, but it's probably still possible to confuse it and get a wrong result. That said, I haven't yet managed to mess it up yet, but maybe someone here can find a good test case.

    int lazyGram(char *str1, char *str2)
    {
      int sum1 = 0;
      int sum2 = 0;
      int count1 = 0;
      int count2 = 0;
      int anagram = 1;
      for(int i = 0 ; i < 256 ; i++)
      {
        sum1 += tolower(*(str1+i));
        sum2 += tolower(*(str2+i));
        if(*(str1+i))
        {
          count1++;
        }
        if(*(str2+i))
        {
          count2++;
        }
      }
      if(sum1 != sum2)
      {
        anagram = 0;
      }
      else if(count1 != count2)
      {
        anagram = 0;
      }
      else
      {
        for(int i = 0 ; i < count1 ; i++)
        {
          int found = 0;
          for(int j = 0 ; j < count2 ; j++)
          {
            if(tolower(*(str1+i)) == tolower(*(str2+j)))
            {
              found = 1;
            }
          }
          if(!found)
          {
            anagram = 0;
          }
        }
      }
      return anagram;
    }
    
    1 vote
  14. 39hp Link
    Second time submitting a solution. Yuss! In Python: word1=list(input('Gimmie a word!\n')) word2=list(input('Gimmie another word!\n')) word1.sort() word2.sort() word1s=''.join(word1)...

    Second time submitting a solution. Yuss!

    In Python:

    word1=list(input('Gimmie a word!\n'))
    word2=list(input('Gimmie another word!\n'))
    
    word1.sort()
    word2.sort()
    
    word1s=''.join(word1)
    word2s=''.join(word2)
    
    if len(word1)==len(word2):
        if word1s.lower()==word2s.lower():
            print("S'an anagram, bruh.")
        else:
            print("S'not an anagram, bruh.")
    
    1 vote
  15. [2]
    Flashynuff Link
    Saw this pop up and thought it was this week's. Oops! Posting anyways since I already did it. Did mine in ruby: def anagram_check(x, y) x.gsub(/\W/, '').downcase.chars.sort == y.gsub(/\W/,...

    Saw this pop up and thought it was this week's. Oops! Posting anyways since I already did it. Did mine in ruby:

    def anagram_check(x, y)
    	x.gsub(/\W/, '').downcase.chars.sort == y.gsub(/\W/, '').downcase.chars.sort
    end
    
    puts "Enter first word or phrase to check: "
    word1 = gets.chomp
    puts "Enter second word or phrase to check: "
    word2 = gets.chomp
    
    puts anagram_check word1, word2
    
    1 vote
    1. Emerald_Knight Link Parent
      These challenges aren't meant to be restricted to the week in which they're posted. Please feel free to submit your own solutions to any challenges you want at any time :)

      These challenges aren't meant to be restricted to the week in which they're posted. Please feel free to submit your own solutions to any challenges you want at any time :)

      1 vote
  16. JustABanana Link
    Don't have a laptop on me right now and I'm a newbie but I'd sort them(not sure if sort functions would work on a string, so I'd probably assaign numbers to letters) and then compare both arrays

    Don't have a laptop on me right now and I'm a newbie but I'd sort them(not sure if sort functions would work on a string, so I'd probably assaign numbers to letters) and then compare both arrays

  17. onyxleopard Link
    Here’s some ugly, ugly bash: $ function sortstr () { tr [A-Z] [a-z] | grep -o . | sort | tr -d "\n" echo "" } $ function anagrams () { count="$(while read w1 w2; do sortstr <<< $w1; sortstr <<<...

    Write the worst--but still working--implementation that you can conceive of.

    Here’s some ugly, ugly bash:

    $ function sortstr () {
        tr [A-Z] [a-z] | grep -o . | sort | tr -d "\n"
        echo ""
    }
    $ function anagrams () {
        count="$(while read w1 w2; do sortstr <<< $w1; sortstr <<< $w2; done | sort | uniq | wc -l | tr -d ' ')"
        [[ $count = 1 ]] && echo 'anagrams' || echo 'not anagrams'
    }
    $ echo 'foo foo' | anagrams
    anagrams
    $ echo 'foo Foo' | anagrams
    anagrams
    $ echo 'foo oof' | anagrams
    anagrams
    $ echo 'foo off' | anagrams
    not anagrams