Single responsibility principle : a Kata

Some time ago I was browsing on http://rubyquiz.com/ and found a really interesting exercise there. It’s name is Getting to 100. The rules are quite simple:

1. You are given the sequence of numbers 123456789
2. Each number in the interval [1-9] has to be present in the sequence
3. Each number must appear once and only once
4. Numbers should be in increasing order
5. You are given three operators: two minuses and one plus that you have to insert between those numbers
6. The resulting equation should be give 100

The actual task is to:

• check whether an equation is correct syntactically and mathematically
• generate equations and tell whether they are correct or not

I thought it would make a good kata for our self improvement group. I even challenged some of my friends:  Zsolt, Marcell, Lajos and Attila.

It turns out that we all tended to write quite ugly and complicated code at first. However, after several retries and some refactoring, it can be solved with somewhat low amount of code.

Note: When solving the kata, you have to keep in mind the principle of single responsibility. This means that each and every method has to be doing one and only one thing. Of course this idea holds for classes too.

And now, Spoiler Alert! This is part of my solution to the kata to show how easily it can be solved with regular expressions. You are welcome to come up with your own solution if you feel like.  So, here we go:

This class is meant to check whether the equation is correct from the syntactical point of view:

package hu.tamasgyorfi.kata.equations;

public class EquationsValidator {

private static final String OPERATOR = "[-|+]";
private static final String NUMBERS = "[1-9]+";

public boolean isSyntacticallyCorrect(String equation) {
return correctFormat(equation) && correctNumberOfOperators(equation)
&& allNumbersContained(equation);
}

private boolean allNumbersContained(String equation) {
return equation.replaceAll("-", "").replaceAll("\\+", "")
.matches("123456789");
}

private boolean correctNumberOfOperators(String equation) {
return containsTwoMinusOperators(equation)
&& containsOnePlusOperator(equation);
}

private boolean containsOnePlusOperator(String equation) {
return equation.replaceAll(NUMBERS, "").replaceAll("-", "")
.matches("\\+");
}

private boolean containsTwoMinusOperators(String equation) {
return equation.replaceAll(NUMBERS, "").replaceAll("\\+", "")
.matches("--");
}

private boolean correctFormat(String equation) {
return equation.matches(NUMBERS + OPERATOR + NUMBERS + OPERATOR
+ NUMBERS + OPERATOR + NUMBERS);
}
}

And here I have to mention the idea of my colleague Attila Szabó. The credit goes to him for pointing out that eliminating characters and matching the rest against a pattern makes the code more elegant. I took it a bit further and used it almost everywhere. Obtained a class half as long as the original one. Nice catch, Attila 🙂

My full source code can be found here (not fully optimized). 