This series of problem solving exercises are based on problems found on Codewars or Hackerank.
You should have attended the previous problem solving session. You will have learned the outline procedure for solving problems by:
- Understanding what the problem statement is asking you to do
- Using abstraction to identify what is important
- Using decomposition to break the problem down into smaller problems.
- Solve the smaller problems, one at a time
- You will get more practice on that today.
- How to use abstraction
- ow to use decomposition
- How to use repetition
- What you'll need
- No specific tools are required, although you will need to make notes so either pencil and paper or a text editor on your laptop.
You will be presented with a problem. You will learn how to understand the problem and break the problem down into steps that help you work towards a solution.
Todays problem can be found here: https://www.codewars.com/kata/5b4e779c578c6a898e0005c5.
After the class finishes, you should submit a solution to the problem using the link above.
We want to output a drawing of some stairs.
Given a number n, draw stairs using the letter "I", n tall and n wide, with the tallest in the top left.
Examples: We are given two examples.
Example 1
For example, n = 3 would return:
"I\n␣I\n␣␣I"If you print that string in a console.log it would look look like this:
I
␣I
␣␣INote that the ␣ character represents a space and \n is a newline. These characters are part of a group of characters known as "white space" characters and when printed are invisible. Another white space character is a tab, written as \t in Javascript. The ␣ is only shown here so that we can see and count spaces. A space intended to be printed like this is part of a string in Javascript so should be surrounded by quote characters. Note that "" is an empty string where as " " is a string containing one space.
Another example, a 7-step stairs should be drawn like this:
I
␣I
␣␣I
␣␣␣I
␣␣␣␣I
␣␣␣␣␣I
␣␣␣␣␣␣Ifunction drawStairs(n) {
// your code here
}- Make sure you understand the problem.
- Discuss any questions as a group before continuing.
- Make a list of all the features that look important. Ignore anything that is not essential to solving the problem. In this problem, look for patterns.
- Discuss your solution to this step as a group. Does everyone have the same list of important elements or are there differences? Resolve your differences so everyone agrees what is important.
- The input to the function is
n, representing the number of steps. - The function should return the complete string (although we could optionally print it before returning the string).
- We are building up a string containing only the characters;
space,I, and\n. - There will be exactly
noccurences ofIin each string. - Every
Iexcept the final one will be followed by a\nand a number of spaces to correctly format the string.
We are given two examples. Here they are again.
For example, n = 3 would return:
"I\n␣I\n␣␣I"If you print that string in a console.log it would look look like this:
I
␣I
␣␣IAnother example, a 7-step stairs should be drawn like this:
I
␣I
␣␣I
␣␣␣I
␣␣␣␣I
␣␣␣␣␣I
␣␣␣␣␣␣I- In the 3-step example we are shown the actual string and what it looks like printed. In the 7-step example we are only shown what it looks like printed. Write down what the actual string will be for the 7-step example.
- Write down the string generated when n is 1.
- Write down the string generated when n is 5.
- Do you notice any patterns?
Lets put the examples in order of the value of n.
When n = 1, the return string is:
"I"When n = 3 the return string is:
"I\n␣I\n␣␣I"When n is equal to 5, the returned string is:
"I\n␣I\n␣␣I\n␣␣␣I\n␣␣␣␣I"When n is equal to 7, the returned string is:
"I\n␣I\n␣␣I\n␣␣␣I\n␣␣␣␣I\n␣␣␣␣␣I\n␣␣␣␣␣␣I"There are some patterns to note:
- The first character in EVERY returned string is
"I" - There is a
\nfollowing EVERY I EXCEPT the last. Our solution will need a way of knowing when we are adding the last I so we don't add too many\ncharacters. - After the first
I, there is ALWAYS a sequence of one or more spaces before the nextI. Our solution will need a way of calculating the correct number of spaces before the nextI. We might note here that there is ONE space after the FIRSTI, TWO spaces after the SECONDI, THREE spaces after the THIRDI, and so on.
It is useful to note these patterns because we can use them when designing the solution later.
- Can you decompose this problem into smaller ones? Hint: Think about the characters we are adding to the result string. Decomposing a problem is all about not trying to do everything at once. Describe your decomposition in English without reference to programming code of any kind, although you might want to use variable names to refer to certain values.
- Discuss as group the different decompositions you have come up with. Resolve any differences.
Step 1: There is a simple version of the problem that we can solve first. Ignore all characters except the I and generate and return a string containing the correct number of I characters. This will be our version 1.
Step 2: Modify version 1 so that the correct number of \n characters are added. This will be our version 2.
Step 3: Modify version 2 so that the correct number of spaces are added. This will be our version 3 (final version).
In version 1, we are going to return a string containing only the correct number of I characters.
n=0we need to return""n=1we need to return"I"n=2we need to return"II"n=3we need to return"III"
and so on...
Here is a design for version 1.
- We are building a string so start with a variable called
resultwhich is an empty string"". We will append all the subsequent characters toresult. - If the value of
nis less than1, there is nothing to do, so returnresult. - Use a variable call
iCountto count the number ofIcharacters we have appended so far, currently its value should be0. while iCountis less thann, repeat:- Append an
Itoresult - Increment the value of
iCountby onereturn result
- Append an
Write the plan above in Javascript and check that it works. You might need to check the documentation for how to append to a string. There is more than one way to do that.
Here is the code for version 1:
function drawStairs(n) {
let result = "";
if (n < 1) return result; // nothing to do, the function returns here
// we only get past the above line when n >= 1, we don't need an else
let iCount = 0;
while (iCount < n) {
// append an I
result = result.concat("I");
// or you could have ...
// result = result + "I";
// update the count
iCount = iCount + 1;
}
return result;
}If we run version 1 in codewars we will see the following output:

Version 1 passes the test for n=1. It fails when n=3 and n=5 but we expected that. If you read the message printed for the 3-step test, it says
expected 'III' to equal 'I\n I\n I'We can see that version 1 is doing exactly what we intended. In the 3-step test, version 1 returns a string containing three I characters. In the 5-step test, version 1 returns a string containing five I characters.
Version 2 will return strings containing only I and \n characters. Here is what we are aiming at:
n=0we need to return""n=1we need to return"I"n=2we need to return"II"n=3we need to return"III"
and so on...
We note that when we add an I, if it was not the last I, we add a \n. Here is the relevant code with a comment added:
while (iCount < n) {
// append an I
result = result.concat("I");
// update the count
iCount = iCount + 1;
// if that wasn't the last I, append a \n
}Write the code indicated by our comment to complete version 2.
To correctly add a newline when required, we need to add:
if (iCount < n) {
result = result.concat("\n");
}We should test this and check the output is what we expect.
The final version of our code will include space characters. This is what we are aiming at:
n=0we need to return""n=1we need to return"I"n=2we need to return"II"n=3we need to return"III"
and so on...
We should notice that
- the spaces come after the
\ncharacter for everyIexcept the last. - the number of spaces is the same as the number of
Icharacters we have appended so far. - Modify version 2 so that it includes the code to append the correct number of spaces. Hint: The algorithm to use is to count spaces and repeatedly add a space until you have enough.
Here is the code to add the right number of spaces:
// add the \n when required
if (iCount < n) {
result = result.concat("\n");
// add the spaces too
let spaceCount = 0;
while (spaceCount < iCount) {
result = result.concat(" ");
spaceCount = spaceCount + 1;
}
}You might have written the following:
// add the \n when required
if (iCount < n) {
result = result.concat("\n");
}
// now add the spaces
if (iCount < n) {
let spaceCount = 0;
while (spaceCount < iCount) {
result = result.concat(" ");
spaceCount = spaceCount + 1;
}
}but we don't need the second if statement because both if statements test whether (iCount < n) and the neither if statement changes iCount or n. Therefore we can merge the two into one if statement.
One if statement is simpler than two, simpler is almost always better.
- Our learners get feedback on their work through code review.
At work, colleagues review each others code to understand code, look for problems, and both share and learn better ways of doing things.
At HYF every learner should get code review on their work especially for the PR.
- The coach will review a pull request, and talk out loud about what they’re looking for and doing.
- The learner(s) will ask questions as they do.
Hints and tips
- How did you understand what the goal of the PR is? Reading the title and description, looking at the coursework exercises, etc.
- The uses of the different tabs in a PR: Conversation, Commits, Files changed.
- What made a PR easy or hard to review:
- Where unrelated files/lines changed?
- Was code consistently formatted? Did indentation help or hurt understanding?
- How did you review the code? Did you read top-to-bottom? Did you jump around into and out-of functions? Did you look at tests? Did you clone the code locally and try running it?
This is time for you to get help with whatever you need help with.
If you didn’t understand something in the prep, ask about it.
If you were struggling with a coursework exercise, get help with it.
If you weren’t quite sure of something in a workshop, discuss it.
If you don’t have any problems, keep working through the coursework until you need help.
It can be useful to get into groups with others facing the same problem, or working on the same backlog item.
Don’t be scared to approach people and ask what they’re working on - see if you can help them out, or stretch their understanding.
If lots of people have the same problems, maybe you can put together a demonstration or a workshop to help them understand.
If absolutely no one needs help, consider reviewing some PRs.