Play some Code Wars with me

Though unfortunately blogs don’t make it easy to play along so how about you read with me. I’ll also paste the link to the kata I’m going to be working on at the top. If you want to try it yourself before you read my solution let me know in the comments how you got on.

For anyone who hasn’t heard of Code Wars before, here is a brief explanation: It’s a website where you can learn to code and develop your skills. It has katas (which are pieces of unfinished code) written by other users. There are instructions alongside these katas to help you understand what you are expected to achieve with the completed code. In addition to this, there are also what are known as unit tests. These tests will check if your code achieves what it is supposed to as laid out in the instructions.

These katas are divided by language and by level. Note: 8kyu is easier code, and 1kyu is the hard code. Or impossible, for me.

Today I’m going to start with a 7kyu. It is called Love vs Friendship. If you want to try it at home before you see my answer click on that link and a new tab should open. I will hopefully see you checking in later.

For everyone else, here we go.

First we look at the instructions:

Love vs friendship instructions, source: CodeWars

Ok, so that’s not the most descriptive lot of instructions I have seen but I guess we will see.

Next let’s check out the kata we have:

using System;

public static class Kata
{
  public static int WordsToMarks(string str)
  {
    throw new NotImplementedException();
  }
}

Note: I am working with C# for this but there are several other languages available for this kata.

As the instructions were basic, I also want to show you the tests which are included with this kata to give you a better example of what is expected from the completed code.

namespace Solution 
{
  using NUnit.Framework;
  using System;
  
  [TestFixture]
  public class SampleTest
  {
    public static TestCaseData[] testCases = new TestCaseData[]
    {
      new TestCaseData("attitude").Returns(100).SetDescription("Input: \"attitude\"\n      Expected: 100"),
      new TestCaseData("friends").Returns(75).SetDescription("Input: \"friends\"\n      Expected: 75"),
      new TestCaseData("family").Returns(66).SetDescription("Input: \"family\"\n      Expected: 66"),
      new TestCaseData("selfness").Returns(99).SetDescription("Input: \"selfness\"\n      Expected: 99"),
      new TestCaseData("knowledge").Returns(96).SetDescription("Input: \"knowledge\"\n      Expected: 96"),
    };
  
    [Test, TestCaseSource("testCases")]
    public int Test(string str) =>
      Kata.WordsToMarks(str);
  }
}

These unit tests are written using the NUnit test framework in C#. For those of you not familiar with reading tests, these tests are stating that each word should equal the number on the same line. For example, the first test is attitude. This is expected to return 100. The instructions are explaining that each letter in the alphabet is given the value of its position in the alphabet. Therefore attitude would turn to:

a = 1

t = 20

t = 20

i = 9

t = 20

u = 21

d = 4

e = 5

1 + 20 + 20 + 9 + 20 + 21 + 4 + 5 = 100

Ok so now we understand what we need the code to do we can start coding. My first task is to get the alphabet. Now, one option is to type every letter into a variable. For example:

var a = new List<char>()
{ 'A', 'B', 'C' ... 'Z' };

But that will be exhausting! So instead, there is a trick I could use (though this is my first time trying this so we’ll see how it goes.

for (var i = 'A'; c <= 'Z'; i++)
{

}

First I better check that it works. So I’m going to open a new console application in Visual Studio and see what this code prints out:

When I run this code a nice alphabet appears in the console window. So there we go. However, printing the letters to the console is only a way of checking if it works, I still need to store it somewhere.

So my next bit of code looks like this:

var alphabet = new List<char>();


for (var i = 'A'; i <= 'Z'; i++)
{
   alphabet.Add(i);
} 

What have I done here? Ok well I have first created a new list variable which I have named “alphabet”. I’ve initialised it (that’s the bit after the equals sign) as an empty list. I have also changed the code in the for loop so that each letter is now stored in the list. You see, the alphabet list pretty much does what it says in the tin: it lists the alphabet. So there we go, first step done!

We have our letters but we also need our numbers.

There is a simple way to figure this out. We know that the number that the letter is valued at is equal to its position in the alphabet. But how do we find out what that index is?

Ok so now I’m going to pull out a different loop option. This time I am going to use a foreach loop. Similar to the for loop as it will look at each item in the collection (or list, in this example).

foreach (var letter in str)
{
  
}

That is our foreach loop set up. Next we need to find out what the index of each letter in the “str” variable is when we search for the same letter in the alphabet list. For that I am going to use the IndexOf() method in the Systems object.

alphabet.IndexOf(letter) + 1;

So in that line of code we are search the “alphabet” list to find the index of the character which is equal to the “letter” in the “str”. One thing to note here is that I have added “+1” to the end of the line. This is because Lists start their index at 0. As the instructions from CodeWars show we need A to be equal to 1 not 0, so this is covered by the +1.

Next we need to bring this all together.

But wait, stop! I’ve missed something out from the instructions. So far I’ve been keeping the letters to capitals. However the tests are case-sensitive so this needs to be switched. Thankfully this is not a huge job. I quickly go back to the for loop where I created the alphabet list and change the ‘A’ to ‘a’ and the ‘Z’ to ‘z’ and it’s crisis averted.

Ok so how do we get that final result, the score, how do we figure out what each string is worth?

Well next I am going to create a new variable called “score”. I am going to initialise that at 0, and then in the foreach loop I will add the value of the index (+1) to that score. Then we will terminate the code by returning the score.

var alphabet = new List<char>();
var score = 0;


for (var i = 'a'; i <= 'z'; i++)
{
   alphabet.Add(i);
}

foreach(var letter in str)
{
   score += alphabet.IndexOf(letter)+1;
}
return score;

That’s it. That’s our code. But right now we are working in the Visual Studio IDE, so I need to paste this (including the using statements which Visual Studio will automatically fill in for us) into the terminal on CodeWars.

The CodeWars page with my code pasted into the solution window.

Next I click ‘Test’ which will run the unit tests which I previously mentioned.

The Output window has now changed to show the results of our tests

Yay we have passed all of the tests. Next we need to click the “Attempt” button. This time the code will be tested again some secret tests.

The Output window has changed to display the results of the secret tests

Great news, we have passed again. That’s good because now we have two options: refactor the code, or submit our result. For the purposes of this post I am going to choose to Submit the code for now. This will add our result to the list of other solutions which have been submitted successfully by other users.

Once we do this, you can unlock the solutions and going through those solutions will help you see other ways to code the same solutions.

If you’ve stuck with me so far, thank you and I really hoped this gave you an introduction to CodeWars and an idea of how I break solutions down.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: