Over a million developers have joined DZone.

Java Code Challenge: Chemical Symbol Naming Part One Solution

DZone's Guide to

Java Code Challenge: Chemical Symbol Naming Part One Solution

The solution to Sam Atkinson's most popular code challenge yet!

· Java Zone ·
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

Holy moly. The most popular challenge to date with a whopping 53 solutions!  You can check out the original challenge and all of the solutions (in the comments) over here.

There's no way I can crawl through all 53 solutions, so I've taken something of a random sampling to get an idea of where the solutions are falling.  If you've done yours completely differently then I apologize for not getting to cover it here!

I've also decided just to cover the basic answer for now and not go into the bonus question — we'll save that for another time.

The Basic Solution 

Let's face it; at it's purest this isn't a difficult task, hence the impressive amount of submissions. We have some rules, that can be executed one after another. If all the rules pass, then we have a green light and the symbol is valid. This solution is a fine example of that; just some if statements linked together.

    public static String getValidSymbol(String elementName) {
        if (elementName == null || elementName.length() < 3) {
            return "";

        char letter1 = (char) (elementName.charAt(0) | 96);
        char letter2 = (char) (elementName.charAt(1) | 96);

        for (int i = 1; i < elementName.length(); i++) {
            char letter = (char) (elementName.charAt(i) | 96);
            if (letter < letter1 && i < elementName.length() - 1) {
                letter1 = letter;
                letter2 = elementName.charAt(i + 1);
            if (letter < letter2) {
                letter2 = letter;
        String result = new String(new char[]{(char) (letter1 - 32), letter2});
        return result;

It does the job, it is technically a good solution. It's very similar to what most people have done. But is this type of solution good code?

Cohesion and Coupling

I advise you go read a few solutions.  You'll often see one class solutions- a number of people managed to get the whole thing down to about 6 lines of code.  The thing is, whilst brevity can be very useful in programming, it can also be damaging.  It makes code harder to understand, and so harder to maintain.

Take the solution above; everything is in "PeriodicTableUtil".  Without looking at the code can you tell me what it does?  "Um, it's a utility for periodic table?".  But what does a utility do?  This is a badly name class (and where possible, you should avoid util classes in favour of more object oriented solutions).  

This class is in charge of:

  • Ensuring the input is valid

  • Creating a bunch of rules

  • Looping through a bunch of rules

  • Providing a valid solution

It's doing too much.  Each class should do one thing well! For me, a clean design will have a seperate rule class.  

public interface Rule {

    boolean check(String element, String symbol);

This then means you can have a specific class, which I chose to call ChemicalAnalyzer, which is responsible only for looping through rules and providing a solution.  This provides a clear seperation of concerns and makes the code much easier to read.  I have a section for the mechanics, and I have seperate classes for the rules (although I did choose to have these as anonymous inner).

Clarity of Results

From the solutions I checked out, everyone seemed to stick to the task tightly and not expand on it — specifically their solutions threw booleans around exclusively.  The problem is, it becomes really hard to diagnose and understand what's going on.  When a test would fail incorrectly there is no feedback other than "Was true; expected false".  This is not a great way to debug through.

Even thought it's not required by the end user, I think it's important to expand the solution to pass around a sensible object which has information pertaining to the response; that is, if a chemical symbol is invalid then the response tells us why it's invalid.  I created a class called AnalyzerResponse for this.

 public static final AnalyzerResponse VALID = new AnalyzerResponse(true, "");

    public final Boolean valid;
    public final String description;

    public AnalyzerResponse(Boolean valid, String description) {
        this.valid = valid;
        this.description = description;

Not a particularly lengthy class, but by changing the rule snippet above to use it:

public interface Rule {

    AnalyzerResponse check(String element, String symbol);

It meant that when my test gave a solution I wasn't expecting it was very clear where the solution came from so I knew where to start debugging.  Having verbose objects is very important for debug and inspection purposes and is a great tool to add to your belt.

You can check out my full solution here.

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat

clean code

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}