Solving Problems on HackerRank
Solving problems on HackerRank is a fantastic way to keep your coding skills sharp. With the right environment setup and a structured approach, you can solve problems efficiently and effectively. In this guide, I’ll walk you through myenvironment setup and demonstratemy approach to solving thestaircase problem using Test-Driven Development (TDD) in C#.
Environment Setup
The following instructions assume you’ll be using C# with Visual Studio Code. Let's get everything set up!
Step 1 - Install .NET SDK
Note: Skip this step if you already have the .NET SDK installed.
First, head over toMicrosoft’s .NET SDK for Visual Studio Code to install the SDK. Then, verify your installation with the following command:
dotnet--info
You should see output similar to this:
Note: The output may differ depending on your operating system.
❯ dotnet--info.NET SDK: Version: 8.0.108 Commit: 665a05cea7 Workload version: 8.0.100-manifests.109ff937 ...# content truncated for readability
Step 2 - Create a .NET Solution and Test Project
Next, let's create a .NET solution for the problem:
mkdirStaircasecdStaircasedotnet new sln-n Staircase
Then, create a test project and add it to the solution:
dotnet new xunit-n Staircase.Testsdotnet sln add Staircase.Tests
Finally, build and test the solution to ensure everything is set up correctly:
dotnet builddotnettest
If all goes well, your test project should build and run successfully.
Step 3 - Run Tests with Hot Reload
To make your problem-solving process faster, use this command in your solution folder:
dotnet watchtest--project Staircase.Tests
This enables hot reloading, so your tests automatically run whenever you make changes, providing instant feedback. 🚀
The Problem-Solving Process
My approach to solving HackerRank problems involves Test-Driven Development (TDD). Here’s a brief overview of TDD and how I apply it.
A Bit of Theory
TDD is guided by three core laws:
- Write a failing test before writing any production code.
- Write only enough test code to fail, or fail to compile.
- Write only enough production code to make the failing test pass.
These laws guide the Red/Green/Refactor cycle:
- Create a unit test that fails. 🔴
- Write production code to make the test pass. 🟢
- Refactor the code to clean up any mess. ✨
For a deeper dive into TDD, I highly recommend readingThe Cycles of TDD by Uncle Bob.
Problem-Solving in Action
Now, let's apply this process to thestaircase problem.
In yourStaircase.Tests
project:
- Create a
StaircaseTests.cs
file for your tests. - Run
dotnet watch test --project Staircase.Tests
in your terminal.
First Cycle
Let's start with the case when the staircase should beEmptyWhenNoStairs
.
🔴 Create a Unit Test That Fails
Write a unit test that fails in theStaircaseTests.cs
file:
[Fact]publicvoidEmptyWhenNoStairs(){Assert.True(string.IsNullOrEmpty(Result.staircase(0)));}
Your terminal should show output like this:
dotnet watch 🚀 Started Determining projects to restore... All projects are up-to-dateforrestore./path/to/staircase/Staircase.Tests/StaircaseTests.cs(10,42): error CS0103: The name'Result' does not existinthe current context[/path/to/staircase/Staircase.Tests/Staircase.Tests.csproj]dotnet watch ❌ Exited with error code 1dotnet watch ⏳ Waitingfora file to change before restarting dotnet...
🟢 Write Production Code to Make the Test Pass
Create theResult
class and thestaircase
method to fix the failing test:
internalclassResult{internalstaticstringstaircase(intn){returnstring.Empty;}}
✨ Refactor the Code to Clean Up Any Mess
In this step, there’s no mess to clean up, so let’s move on.
Yay! We’ve solved one case, and our production code works! 🎉
Second Cycle
Now, let's move on to the next case:FirstLevelHasOneStair
.
🔴 Create a Unit Test That Fails
[Fact]publicvoidFirstLevelHasOneStair(){Assert.Equal("#",Result.staircase(1));}
dotnet watch test
should show that this test is failing, which is exactly what we want.
🟢 Write Production Code to Make the Test Pass
Update thestaircase
method to make the test pass:
publicstaticstringstaircase(intn){if(n==1)return"#";returnstring.Empty;}
Your terminal should now display:
Passed! - Failed: 0, Passed: 2, Skipped: 0, Total: 2, Duration: 3 ms - Staircase.Tests.dll(net8.0)dotnet watch ⌚ Exiteddotnet watch ⏳ Waitingfora file to change before restarting dotnet...
✨ Refactor the Code to Clean Up Any Mess
Again, there’s no need for cleanup at this point, but always make it a habit to check for any mess that needs tidying up.
⚠️ Remember,test code is as important asproduction code. Keep it clean!
Next Cycles
By now, you’ve got the hang of it. Think about the next small step or the next unit test that should fail.
Here are all the steps I followed, each representing a TDD cycle:
[Fact]publicvoidEmptyWhenNoStairs(){Assert.True(string.IsNullOrEmpty(Result.staircase(0)));}[Fact]publicvoidFirstLevelHasOneStair(){Assert.Equal("#",Result.staircase(1));}[Fact]publicvoidHasTheGivenNumberOfStairs(){varstairs=Result.staircase(10).Split('\n');Assert.Equal(10,stairs.Length);}[Fact]publicvoidEachStairHasTheMaximumWidth(){varstairs=Result.staircase(10).Split('\n');foreach(varstairinstairs){Assert.Equal(10,stair.Length);}}[Fact]publicvoidEachStairEndsWithHash(){varstairs=Result.staircase(10).Split('\n');foreach(varstairinstairs){Assert.Equal('#',stair[10-1]);}}[Fact]publicvoidEachStairHasTheCorrespondingNumberOfHashes(){varstairs=Result.staircase(10).Split('\n');for(inti=0;i<10;i++){varexpectedNoOfHashes=i+1;varactualNoOfHases=stairs[i].ToCharArray().Count(c=>c=='#');Assert.Equal(expectedNoOfHashes,actualNoOfHases);}}
And here’s my final solution for thestaircase
problem:
internalclassResult{internalstaticstringstaircase(intn){varresult=newStringBuilder();for(intcurrentLevel=1;currentLevel<=n;currentLevel++){result.Append(BuildStair(currentLevel,n));}returnresult.ToString();}privatestaticstringBuildStair(intcurrentLevel,intnoOfLevels){varhashes="#".PadLeft(currentLevel,'#');varstair=hashes.PadLeft(noOfLevels,' ');if(currentLevel!=noOfLevels)stair+="\n";returnstair;}}
Conclusion
By setting up your environment correctly and following a disciplined approach like TDD, you can tackle HackerRank challenges efficiently. Each small step in TDD, no matter how trivial, builds up to a robust and well-tested solution. The key is to move slowly and methodically—small, deliberate steps will ultimately lead to faster, more reliable problem-solving. Happy coding! 😄
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse