4
\$\begingroup\$

Given two strings with the same length, we check how many chars on the same positions are different. For example: ABCD and ABBD should return 1. Here is a link to a gist with tests, to have a better understanding of what I'm building. Here is my solution:

object Hamming {
 def compute(str1: String, str2: String):Int = {
 if (str1.length != str2.length)
 throw new IllegalArgumentException("Strings have different length")
 (0 to str1.length - 1).filter(i => str1(i) != str2(i)).size
 }
}
200_success
145k22 gold badges190 silver badges478 bronze badges
asked Jul 1, 2015 at 9:01
\$\endgroup\$
1
  • \$\begingroup\$ It's vaguely entertaining to see an Exercism question here. \$\endgroup\$ Commented Aug 22, 2016 at 13:10

2 Answers 2

4
\$\begingroup\$

How about this variant?

object Hamming {
 def apply(a: String, b: String): Int = if (a.length != b.length) {
 throw new IllegalArgumentException(s"Strings a=$a and b=$b have different length.")
 } else a.zip(b).count {
 case (charA, charB) => charA != charB
 }
}

The zip-function does create a new collection of tuples with two corresponding chars side by side in every tuple. (Char, Char) The count-function counts the number of elements for which a boolean evaluation function, passed as an argument, returns true. This should work not only for characters, because it uses pattern matching. Also if there are two arguments of the same type (e.g. for comparison) and I cannot further specify what they are, then I like to name them a and b. I cannot tell if this solution is faster than yours, but I don't think there will be a significant difference.

P.S.:

  • I see the function is named compute. Thats really general and abstract. I named it apply. It can be called like this: Hamming("Alice", "Bob")
  • Look at what I did with the brackets.
  • If you would like to use the function for other sequences than characters you can change the snippet to this:

    def apply(a: Seq[_], b: Seq[_]): Int = if (a.size != b.size) {
     throw new IllegalArgumentException("Parameters have different length.")
    } else a.zip(b).count {
     case (charA, charB) => charA != charB
    }
    
answered Jul 3, 2015 at 14:00
\$\endgroup\$
3
\$\begingroup\$

Note of warning: I haven't done Scala in a while. The style may have changed, or I may have never known the right one, so I could be wrong.

It looks good, except for two things:

  1. Please, put brackets around one-line ifs. It makes things much easier to keep track of in the long run, even if you don't need it now. Before you say "this is just a project to learn the language", if you get into good habits now, you won't have to break bad ones later.
  2. You have a pair of newlines that have no purpose after the beginning and before the end of the object definition

Aside from that, it looks good! I like the 'algorithm' you chose to use; it's actually quite clever and easy to understand.

answered Jul 1, 2015 at 9:36
\$\endgroup\$
2
  • \$\begingroup\$ About if block, I know its a good practice to wrap one liners in javascript. I'm not sure about Scala, I've seen a lot of good code where people didn't do this, so I picked up that style. Maybe someone will have something to say about this case \$\endgroup\$ Commented Jul 1, 2015 at 9:42
  • \$\begingroup\$ @HeeL It's generally a better idea, for lots of reasons -- you see people talking about it in Java, C#, Javascript -- pretty much every language where you can wrap brackets around if blocks, it's said you should. I'd assume the same extends to Scala. \$\endgroup\$ Commented Jul 1, 2015 at 9:46

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.