Is there such a thing as a "wrong way" providing the code works?

Hi

I have been plodding through the Intermediate Algorithm challenges and every time I solve one I always check what the provided solution was in “Get a Hint” to see if I went the same way about approaching the problem.

Most of the time, the solutions are more elegant than mine, however on the Roman Numeral Project, I used a RegExp function which I feel is a more logical approach than the solutions.

Code (with notes):

function convertToRoman(num) {
//Define Lists to store initial split, regex lookups and replacements
let li = [];
let findList = [
    /IIIII/g, /IIII/g, /VV/g, /VIV/g, /XXXXX/g, /XXXX/g, /LL/g, /LXL/g, /CCCCC/g, /CCCC/g, /DD/g,       /DCD/g,]
let replaceList = [
    "V", "IV", "X", "IX", "L", "XL", "C", "XC", "D", "CD", "M", "CM",];

//Define the replacement function with arguments for find, replace.
let reg = function(find, replace) {
    li = li.replace(find, replace)
}
//break your initial argument to a list of the smallest unit "I"
//eg 5 => ["I", "I", "I", "I", "I"]
 for (let i = 0; i < num; i++) {
     li.unshift("I")
 };
//Join it back to a string ready for our RegExp function
 li = li.join("");

//Iterate through the find list, replacing larger and larger denominations
//eg replace all instances of "IIIII" with "V", then "IIII" with "IV" etc. 
for (let i = 0; i< findList.length; i++) {
    reg(findList[i], replaceList[i]);
}
return li
}
convertToRoman(3999);

My question is in the title - Is there such a thing as a “Wrong Solution” providing the code works?

For a challenge like this I know its not a huge deal, but for those who are working in a coding job - is this something you keep in mind when working & how does it affect your design choices?

Thank you for reading

Without getting too technical, it is possible to solve a problem so poorly that it is wrong for the context you might be working in.

For example, you may be using nested loops in such a way that the performance of your algorithm is unacceptable in production, whereas a more efficient algorithm might be possible.

This isn’t super important to concern yourself with right now, but eventually you might like to read up a little on Big O notation.

Hey that’s a really good question, and something I’ve asked myself a lot! The most important thing you should strive for is code readability and that you can understand each and every line. If you were to look back at this code in 6 months time, do you think it would still make sense?

When you start working on a large project at a company, you will see code written from 1,5,10 or even 20 years ago… I guess the main thing to remember is that best practices change all the time… and you might be shocked at how problems were solved back then!

There are a couple of ways to think about this, which are more broad concepts, not entirely specific to your situation:

  1. If you are working on a piece of software / web application then there most certainly will be someone who will look over your code and say “hey, this could be optimized for x,y,z”. That’s nothing to be worried about per se … at least you have come up with a orking solution … they might now just be offering an optimization because maybe they are a senior dev who understands the software/systems a lot better than you. It’s hard to know the difference, so in this case if your code makes sense and is readable by the team, then it should be fine :slight_smile:

  2. On top of that, your manager or a senior dev might want you to tidy things up so that the code is easily reusable across an application. This might mean tweaking the function’s arguments/parameters. Also, this is especially true if you are manipulating the DOM. If your algorithm is targeting a DOM element, then you definitely have to think about the naming of that element and how you target it (I prefer data attributes as they are more obvious to the developer than classes or ID’s). Again, it would be more of a nitpick, but it is an essential part of writing reusable, maintainable code.

The best way to improve your algorithms is by using Codewars. It’s an incredible platform that lets you search for problems based on a huge variety of topics, language features and skill levels. The best thing is that once you complete the algorithm you then get to see how everyone else solved it! People upvote best practices and clever solutions so you really get to see how things can be done in a more elegant/efficient manner. It will definitely put you to shame too haha, some solutions like yours above might well be boiled down to a single one liner!

Hope that helps!

Jack

Thank you taking the time to provide such a thought-out answer, Jack.

I will definitely check out codewars when I move on to the Front-End Libraries course as I dont want to forget anything!

From what you wrote, it sounds like code needs to be a balance of readable, portable and efficient. I think once I get my head around some of the methods like Math and map I will be more comfortable using them all on one line. Same for arrow functions.

Coding is a muscle i guess so it’ll get stronger the more I do it! The main concern is that I don’t want to embed a behavior of approaching problems the wrong way.

In general, there usually isn’t a “wrong way” to write code, provided the code works, as you said.

There are some “fine points” to note however:

  • As pointed out already, there’s “Big O notation”, or put it more accurately, “asymptotic analysis”. This basically refers to the performance of your code—i.e., the runtime, as in, how long it takes the computer to run your code. This does NOT mean the actual length of real-world time the computer takes, but rather something else—because to put it in plain English, modern computers are so darn fast. How the heck are you supposed to measure how long it takes to run code? To sum this point up, there are efficient ways of writing code, and then there are less than efficient ways of writing code. Generally you should try to stick to the efficient ways of writing code. :wink:
  • Speaking to the point of RegEx specifically, RegEx is a string-matching tool, and it can be considered to be a “cheat” or “hack” in a sense, because it makes string-matching so convenient. In other words, RegEx is a great tool to use for real-world coding scenarios where you have to do complex string-matching. However, the point of FCC’s Intermediate Algorithm challenges is to get you to think algorithmically. Not by using “cheats” to avoid thinking about how to solve an algorithmic problem. So while your solution isn’t “wrong” per se, it’s not really the approach that FCC wants you to take. Challenge yourself to avoid using RegEx and come up with an alternate approach without it.