I have failed a coding challenge some time ago. It looked like a simple enough problem. However, afer struggling to come up with an answer in the allowed time, I blew it.
As a software professional with about two decades of progressive experience I was disappointed. I decided to do a mini retrospective to see what I can learn from this experience; what went wrong and how I can do better next time. I skimmed through the “Cracking the Coding Interview” book in preparation for the interview. However, I still made the most common interviewing mistake. I jumped into coding too soon without formulating a solution in my head first.
The task looked pretty simple; write a function that converts an integer to roman numeral. I thought I had a pretty good understanding of the problem and that I would be able to come up with an algorithm on the spot. I was unable to find a pattern to code.
I remembered the advice to practice solving coding challenges on paper for practice and decided to give it a try. I have had good luck with what I call “table approach” where you put all the relevant variables in a table and track their values for each iteration.
Started with writing down the rules:
- M: 1000, D: 500, C: 100, L: 50, X: 10, I: 1
- Symbols to the right increment, symbols to the left decrement
- Max 3 consecutive roman numerals are allowed
- Maximum number representable in roman numerals is 3999
- 0 has no equivalent symbol
The last three rules were not immediately obvious before writing them down. It’s easy to see the early exit conditions. If the number is 0 or greater than 3999, there is nothing to do.
Here is a table that shows the roman numerals to represent numbers 1-9 in different places.
1000s | 100s | 10s | 1s | |
---|---|---|---|---|
1 | M | C | X | I |
2 | MM | CC | XX | II |
3 | MMM | CCC | XXX | III |
4 | - | CD | XL | IV |
5 | - | D | L | V |
6 | - | DC | LX | VI |
7 | - | DCC | LXX | VII |
8 | - | DCCC | LXXX | VIII |
9 | - | CM | XC | IX |
Here is the pattern I see:
Pattern | |
---|---|
1 | a |
2 | aa |
3 | aaa |
4 | ab |
5 | b |
6 | ba |
7 | baa |
8 | baaa |
9 | ac |
Let’s code this pattern in javascript:
1 | function convertDigit(c, p, gp, digitNumber){ |
Every digit in an integer can be represented by 3 roman numerals:
- 1s: I, V, X
- 10s: X, L, C
- 100s: C, D, M
Sounds like a simple Map.
1 | function getDigitRomanNumeralsMap(){ |
Now I can:
- Iterate over each digit
- Pick the 3 roman numerals for the digit place
- Convert each digit to roman numeral
- Concatenate roman numerals
See the code in action here.
Retro time… What have I learned from this experience?
- Read the entire question, ask for clarification and make assumptions explicit
- Read the entire question, ask for clarification and make assumptions explicit (not a typo)
- Do not skip the steps above regardless of how easy the question might seem
- Avoid multitasking, formulate a solution and then write the code
- Draw a table to visualize the available data
- Try to detect a pattern
- Optionally write some pseudocode to mentally test the pattern
- Write code to implement the pattern/algorithm
You’re welcome, future self.