Codewars: "Square Every Digit" w/ Fun JavaScript One Line Solution ✨

Tee - Sep 20 '19 - - Dev Community

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:

  1. Get a list of digits.
  2. For each digit in the list, square it.
  3. Join each digit.
  4. 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
}
Enter fullscreen mode Exit fullscreen mode

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('')
Enter fullscreen mode Exit fullscreen mode

This will result into an array that looks like this:

['9', '1', '1', '9']
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

We'll use .join('') to join each digit together. This will give us the string representation of our new number:

const squaredNumber = squaredDigits.join('')
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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('')
}
Enter fullscreen mode Exit fullscreen mode

Now what in the world is this one doing?

  1. Array.from() creates a new shallow-copied Array from our input.
  2. Inside this method, we convert our number into a String--an iterable object in JS. This allows Array.from() to create an array of string digits.
  3. Then, we use the optional mapping argument where we'll square our digits,
  4. After, we'll join each digit and convert the String result into a Number using the + operator.



Thanks for reading! As always questions, feedback, and ideas are always encouraged. Happy hacking!
. . . . . . . .