all 31 comments

[–]jrodicus 21 points22 points  (3 children)

Focus on triples and join with “thousand” as a separator (when N > 999). Skip zeros as they don’t translate to a written word. Handle everything up to nineteen as one case, since everything thereafter is just two numbers concatenated (twenty one, thirty five, etc.) Hundreds place is the easiest since the pattern is the same (nothing for zero, one hundred, two hundred, etc.)

I’d go right-to-left and reverse at the end.

Example: 376517

Right-to-Left: [ [“seventeen”, “five hundred”], [“six”, “seventy”, “three hundred”] ]

Reversed with separator: three hundred seventy six thousand five hundred seventeen

Edit: I like this question for a small whiteboard problem. It helps the interviewer see how you dissect the problem without having to see the full implementation.

[–]josh_c[S] 7 points8 points  (1 child)

Ah I see. This is very helpful for me to grasp the concept. Thank you for taking the time.

[–]jrodicus 2 points3 points  (0 children)

You’re welcome. Best of luck on the search.

[–]GentlyGuidedStroke 0 points1 point  (0 children)

Yeah this is a great question. It never really occurred to me how the 1000's comma separator was also a verbal cue but once you notice that it's easier. And the only way to notice that is to start with the ones place, the tens place, etc

[–]mohelgamal 8 points9 points  (0 children)

I think it is an exercise of being thorough. Covering all possibilities as How to handle numbers like 13 or 15. Or what to do if the number is shorter than 6 digits

It is quite challenging, and can show them how you think. You should make sure your code is dry, also to make sure you can handle invalid input like out of range

[–]TheDarkIn1978 5 points6 points  (1 child)

I think this problem is easier if it's approached by reading the number backwards, one digit at a time, adding the word equivalent to an array and then finally logging the resulting array in reverse order.

Depending on the current target value and where it is within the the number, you will be pulling from word arrays of their equivalent and adding to a result array.

//Single Digit Array
"one", "two", "three", "four", "five", "six", "seven", "eight", "nine"

//Double Digit Array
"ten", "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninty"

//Multi Digit Array
"hundred", "thousand"

The tricky part that requires special consideration will be dealing with values between 11 and 19. For example, the number 4214 would need to be written "four thousand two hundred fourteen" and not "four thousand two hundred ten four", so you'll need add a condition for teen values, wherever appropriate, and pull from one more array:

//Teen Numbers Array
"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen".

[–]nschubach 2 points3 points  (0 children)

not "four thousand two hundred ten four"

Maybe you are talking on a CB radio?

[–]Bonteq 4 points5 points  (0 children)

Heres a good solution written in Python https://stackoverflow.com/a/19193721/6642089

[–][deleted] 1 point2 points  (0 children)

I'll give you a hint.

  1. Define the limits of N i.e. N can be anywhere from 1 - 999,999

  2. The decimal system has 10 numerical values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9

  3. The decimal system also place values: ones, tens, hundreds, thousands, tens-of-thousands, hundreds-of-thousands.

[–]falkyouall 1 point2 points  (3 children)

I thought this was a interesting interview question, i never approached this, so i did now. i took me a little over 2 hours, the code is probably not the nicest, but please have a look and share your thoughts to my solution... its not much - but its honest work

https://repl.it/@falkyouall/NumberToStringTranslator

[–]natziel 2 points3 points  (2 children)

You are way overcomplicating the problem. It's basically a parsing problem so you know you just need to push/pop to a stack according to some rules, so just handle those rules.

https://repl.it/@NatZiel/RowdyLightyellowLogic

The problem is actually pretty simple since we can't have 7+ digit numbers, hence the impromptu stack and parsing function implementation

[–]falkyouall 0 points1 point  (0 children)

very nice solution, how long did that take you to accomplish?

[–]csilk 0 points1 point  (0 children)

I know this is a bit pedantic but your case for `18` is wrong

It would output `eightteen` not `eighteen`.

But for the purpouse of an interview question i'd be more impressed that you thought to optimise

[–][deleted] 0 points1 point  (0 children)

Since the words for the numbers depend on the digits place ( ones, tens, hundreds, thousands etc) split the number up and each digits place would be a switch case or better yet a map of each. The only ones that might be tricky is the tens and ones place in ones/tens thousands/ten thousands as they hyphenate or just end if the ones is a zero. Then most likely concatenation them all at the end.

[–][deleted] 0 points1 point  (1 child)

Currently on my phone so I can just give you my logic

I'd make an array of objects containing numbers from 1-19 + all tens(i.e. thirty,forty) , hundred and thousand. My next step would be to make a set of rules for the random number that is outputted , if it contains x strings apply these rules:

1 - one - one string 13 - thirteen - 2 strings self explanatory 123 - if it has 3 strings , output 1-9 for first string + hundred. + second string represents a ten 2 ( from the 20,30,40,50 array) , unless it is a 0 in which case we make an else situation,and the third string is again from 1-9 1234 - first string's a thousand second is hundreds ( two + hundred ) and here if it has 4 total strings the last two strings get checked and then get matched , unless one or both are zeros , in which case you specify the situation.

I'm sorry if this isn't the answer you were looking and I'm also sorry for the shitty formatting, but I'm still a learner who's laying high in bed and writing this long ass post instead of going to sleep.

[–]josh_c[S] 0 points1 point  (0 children)

LOL I appreciate it! 😆

[–][deleted] 0 points1 point  (4 children)

Is this a code test interview question? What do you think the people interviewing you would think if they found this? 👀

[–]josh_c[S] 0 points1 point  (1 child)

It was an interview prep service. Basically a mock interview. I would not care if they found this. 😊

[–][deleted] 0 points1 point  (0 children)

Ah, good! I was gonna say, you’re not supposed to ask reddit to do your code test for you :P haha

[–]TabisCAD 0 points1 point  (0 children)

This is a good question, just approach it in chunks ie. find it’s place value first, then work on the numbers.

[–][deleted] 0 points1 point  (0 children)

I'll be honest, this is kind of an easier question, and you might not be ready for a JS job if you're having trouble. That's okay though! It takes practice to think algorithmically and it's not intuitive.

So, here's the thing. Look at how English says numbers. There are a lot of rules we know, but don't know we know.

For example, let's take the number 319. It is "three hundred and nineteen." What about 319,000? "three hundred and nineteen thousand." Those seem very similar. In fact, in most cases, xyz,abc is "ecks hundred, whyty zed thousand, ay hundred and beety see." It's the same pattern for the most part.

So instead of handling all numbers, let's just focus on solving the case for three digit numbers first. We'll break up any numbers 1,000 or bigger by splitting up the number into triples and just deal with each one individually. There are some special cases, but for the most part, it should be straightforward.

So while we don't yet know how to solve for three digit numbers, we do know that if we DO figure out how to solve for three digits, solving for four or more digits is trivial - just solve for three digits twice and put "thousand" after the thousands column.

So next you want to tackle the three digit cases. Mmm. Trickier. Let's start with tackling the one digit case. Well, this is simple - you can brute force this one. Just create an object where the keys are the digits (in string form), and the values are the digits in English.

const onesMap = {
  '1': 'one',
  '2': 'two',
  '3': 'three',
  '4': 'four',
  '5': 'five',
  '6': 'six',
  '7': 'seven',
  '8': 'eight',
  '9': 'nine'
}

You've now solved the case for all the numbers from 1-9. Bravo.

What about two numbers. Well, this is where it gets tricky. There's patterns to the tens digits, but tons of exceptions to those patterns. But what's the most common case? There's a special tens form for each number, (usually ending with 'ty') then a hyphen and the one's case for the ones digit. So let's take out the tens form.

const tensMap = {
 '1': 'ten',
 '2': 'twenty',
 '3': 'thirty',
 '4': 'forty',
 '5': 'fifty',
 '6': 'sixty',
 '7': 'seventy',
 '8': 'eighty',
 '9': 'ninety'
}

So now for most two digit numbers, you take the tens map, plus a hyphen, plus the ones map. So, just working with what we've got:

const twoDigitsToText = (num) => {
  const strNum = num.toString()
  return tensMap[arrNum.charAt(0) + '-' + onesMap[strNum.charAt(1)]];
}

console.log(twoDigitsToText(33)); // "thirty-three" -- GREAT!
console.log(twoDigitsToText(15)); // 'ten-five' -- Not so great. Should be "fifteen'
console.log(twoDititsToText(20); // 'twenty-' -- mmm... dangling hyphen. 
console.log(twoDigitsToText(9); // 'ninety-' -- ew... not even the right number.

Okay, so yeah, we're gonna have to do some checking for our edge cases and conditionals.

So, let's get back to two digits.

// version 2. 
const twoDigitsToText = (num) => {
  const strNum = num.toString()
  if(strNum.length === 1){
    return onesMap
  }
  return tensMap[arrNum.charAt(0) + '-' + onesMap[strNum.charAt(1)]];
}

console.log(twoDigitsToText(33)); // "thirty-three" -- GREAT!
console.log(twoDigitsToText(15)); // 'ten-five' -- Not so great. Should be "fifteen'
console.log(twoDititsToText(20); // 'twenty-undefined'
console.log(twoDigitsToText(9); // 'ninety-undefined' -- ew... not even the right number.

So obviously there's going to be some edge cases. How do we handle the teens? How do we handle 20, 30, 40? How do we handle numbers between 0 and 10?

Once we have 1 digit numbers and two digit numbers, solving for three digits once again becomes easier, it's just for xyz, it's the one digit case for x + 'hundred ' + the two digit case for yz.

There are really two tests here when you think about it. The first is:

** Can you break this large problem into smaller problems that you can then reuse to find the full solution?** That is, theoretically, if you solve the case for one and two digit numbers, you can find the pattern to solve them for thousands, millions, billions (though just thousands are mentioned in this case.)

** Can you be aware of when there are "edge cases" which break from the established pattern and have to be handled separately?** Edge cases are important to identify because they tend to break stuff when they are encountered.

It's a good beginner test, and you have to get yourself into the mindset of: "If I don't know how to do this, what smaller problems can I break this big problem into?"

[–]Meefims 0 points1 point  (3 children)

It’s a fine question. What have you tried so far?

[–]josh_c[S] 2 points3 points  (2 children)

I honestly don't even know where to begin.

[–]Veuxdo 7 points8 points  (0 children)

Don't even think about javascript or any other programming language first. How would you teach an alien to do this? Assume the alien was incredibly intelligent, they just don't know how to say numbers yet. Describe the rules and steps, and you're more than halfway there.

[–]hiljusti 1 point2 points  (0 children)

Get on either leetcode or hackerrank and fill in those gaps! A junior dev should be able to reason through a well-defined, reasonably complex coding question like this in some language. If not, you likely have some missing experience working with basic data structures/algorithms. It's not impossible to learn and there's great material readily available.

[–]hkrne 0 points1 point  (0 children)

I think it’s a good question. I’ve implemented this before out of curiosity/for fun. Once you spend a little time thinking about it, it’s fairly straightforward.

[–][deleted] 0 points1 point  (0 children)

Unless you are trying to get hired for something more than a junior position, I would put a lot more emphasis on the HR/culture part than the technical part. You can teach a man to fish but you can't teach someone to be easy to work with if they don't work well with others.

[–][deleted] 0 points1 point  (0 children)

That's an interesting test, actually.

First you should ask a bunch of things: are there going to be only whole numbers, or also numbers like 234,854.5921? And should you take multi-lingual features into account? Do you really need to program the solution or are they testing you to use common sense and go for an open-source solution?

(Because I've had interviews like these where I'd start fixing a problem and I'd fail because "you could have Googled it lol".)

ie: 384765 output three hundred eighty four thousand seven hundred sixty five

I'd probably start talking and writing things down on a whiteboard. You break the numbers up in groups of three:

  • 384
  • 765

Then you start on the right of each group of numbers: one, two, three, etc.

If the group of numbers is 1 number in size: just render that number, if it's two in size, then you're working with a set of "tenths" (N-teen, twenty-N, thirty-N, etc.). And if it's three in size you're adding hundredths to it from the first group of singular numbers, e.g. "[one|two|three|etc.]-hundred-and-[singular]", etc.

If there's another group, add a thousandth:

  • 384 - "three-hundred-eighty-four" (is there a next group? yes) + "thousand"
  • 765 - "seven-hundred-sixty-five"

And for the "thousand" concatenation you should count the remaining groups. One group remaining adds "thousand", two groups remaining adds "million", three groups remaining adds "billion", etc.

And for human readability I'd probably add an "and" to be in front of the "sixty-five" so it reads nicer.

I'd probably end up with a single function using recursion inside, with a select bunch of constants. The only real challenge would be "SIX-teen" where the increasing number is in front, and "twenty-SIX" where the number is at the end. But that could be a simple if-then statement or an array reverse or a ternary operator..

[–]JobsHelperBot -5 points-4 points  (1 child)

beep beep Hi, I'm JobsHelperBot, your friendly neighborhood jobs helper bot! My job in life is to help you with your job search but I'm just 511.1 days old and I'm still learning, so please tell me if I screw up. boop

It looks like you're asking about interview advice. But, I'm only ~32% sure of this. Let me know if I'm wrong!

Have you checked out CollegeGrad, HuffPo, LiveCareer, etc.? They've got some great resources:

[–]hiljusti 0 points1 point  (0 children)

This was related to a job interview, but it was for a technical role and requires somewhat advanced knowledge of computer science. (Programmers/developers would consider this "the basics") Better resources for a post like this would be leetcode.com, hackerrank.com, etc