This is part of my series where I explain approaches to solving coding problems. This is to help me articulate my thought process better, and inspire new problem solving approaches for developers!
Problem Statement:
In this kata, you are asked to square every digit of a number. For example, if we run 9119 through the function, 811181 will come out, because 92 is 81 and 12 is 1. Note: The function accepts an integer and returns an integer
Approach:
For this problem, we're given an integer (no decimals). We need to return a new number, where every digit is squared.
For example, if we're given the number 9119, we would return 811181, since the 9^2 = 81, and 1^2 = 1. We need to make sure that we return an integer afterwards. You'll see why down below. Here's the general approach:
- Get a list of digits.
- For each digit in the list, square it.
- Join each digit.
- Return the new number with squared digits.
Solution 1:
/**
* Returns a new number with squared digits
* Time complexity: O(n), space complexity: O(n)
* @param {Number} num an integer
* @returns {Number} an integer with squared digits
*/
const squareDigits = num => {
// Get an array of digits
const digits = num.toString().split('')
// Square each digit. Because JavaScript has
// automatic type coercion, it will quietly convert each string
// into a number to perform multiplication
const squaredDigits = digits.map(n => n * n)
// Join each digit together, then use the + operator
// to convert the string into a number
const squaredNumber = squaredDigits.join('')
return +squaredNumber
}
Explanation:
This is a good problem to apply JavaScript's string methods to split the digits and save them into an array. Since there aren't built in methods that can do this, we have to convert the number into a string. Then, we can use array iteration methods to square each digit before we return the new number. Here's how we'll do it.
We use toString()
to create a string representation of the number. If we pass our function 9119
, this will create a string representation of this which would be '9119'
.
Following our toString()
method, we split the string using .split('')
. This means that we're breaking up the number into individual digits, and then saving them to an array.
const digits = num.toString().split('')
This will result into an array that looks like this:
['9', '1', '1', '9']
For each digit, we need to square them. Now that we have an array of strings, we can use map()
look through our original array, and multiply each digit by itself. This saves us space since we're only updating our original array instead of creating a new one.
const squaredDigits = digits.map(n => n * n)
You may be wondering how this is even possible since we're used to multiplying numbers only right? JavaScript hooked us up with something called "automatic type coercion!" This just means that we're using operations with certain types, in this case JavaScript will secretly convert the digits into numeric values!
After, our array will look like this:
[81, 1, 1, 81]
We'll use .join('')
to join each digit together. This will give us the string representation of our new number:
const squaredNumber = squaredDigits.join('')
The problem statment wants a numeric value to be returned, not a string! We can do this easily using the +
prefix before our squaredNumber
constant. This will convert it into a number:
return +squaredNumber
The time complexity for this solution is O(n) since we are squaring each digit in the array. The space complexity is O(n) since we are creating a new array using .split('')
.
Solution 2's a neat one liner one! This was a fun way of applying Array.from:
Solution 2:
/**
* Returns a new number with squared digits
* Time complexity: O(n), space complexity: O(n)
* @param {Number} num an integer
* @returns {Number} an integer with squared digits
*/
const squareDigits = num => {
return +Array.from(num.toString(), n => n * n).join('')
}
Now what in the world is this one doing?
-
Array.from() creates a new shallow-copied
Array
from our input. - Inside this method, we convert our number into a
String
--an iterable object in JS. This allowsArray.from()
to create an array of string digits. - Then, we use the optional mapping argument where we'll square our digits,
- After, we'll join each digit and convert the
String
result into aNumber
using the+
operator.
Thanks for reading! As always questions, feedback, and ideas are always encouraged. Happy hacking!