Introduction
Your body is made up of cells that contain DNA.
Those cells regularly wear out and need replacing, which they achieve by dividing into daughter cells.
In fact, the average human body experiences about 10 quadrillion cell divisions in a lifetime!
When cells divide, their DNA replicates too.
Sometimes during this process mistakes happen and single pieces of DNA get encoded with the incorrect information.
If we compare two strands of DNA and count the differences between them, we can see how many mistakes occurred.
This is known as the “Hamming distance”.
The Hamming distance is useful in many areas of science, not just biology, so it’s a nice phrase to be familiar with :)
Instructions
Instructions
Calculate the Hamming distance between two DNA strands.
We read DNA using the letters C, A, G and T.
Two strands might look like this:
GAGCCTACTAACGGGAT
CATCGTAATGACGGCCT
^ ^ ^ ^ ^ ^^
They have 7 differences, and therefore the Hamming distance is 7.
Implementation notes
The Hamming distance is only defined for sequences of equal length, so an attempt to calculate it between sequences of different lengths should not work.
Dig Deeper
zip with count
zip with count
object Hamming {
fun compute(leftStrand: String, rightStrand: String) =
if (leftStrand.length != rightStrand.length)
throw IllegalArgumentException("left and right strands must be of equal length")
else
(leftStrand zip rightStrand).count { it.first != it.second }
}
An object declaration is used to define Hamming as essentially a singleton object instantiation of the class.
This is sufficient, since there is no object state that needs to change with each call of the compute method.
The compute method is implemented by an if/else expression.
Although the function has multiple lines, it consists only of the one if/else expression,
so it is defined using single-expression function syntax,
with the curly braces omitted from the function call and the return type inferred.
An IllegalArgumentException is thrown if the two input Strings are not the same length.
Otherwise, the zip function is used to make a sequence of Pair values of the characters at the same index in both input Strings.
Since zip is marked as an infix function, it can be called between the two strands (i.e. between the left receiver and the right parameter),
as well as called leftStrand.zip(rightStrand).
Which to use is a matter of stylistic preference.
The count function iterates the Pair values and uses the it keyword to count the Pair values that meet the Boolean condition
of the first value in the current Pair not being equal to the second value in the Pair.
Finally, the compute function returns the result of calling count on the zipped Pair values.
Source: Exercism kotlin/hamming