Skip to content

Instantly share code, notes, and snippets.

@jsmney
Forked from cchoi34/LoveIsInTheAir.md
Last active February 11, 2020 17:09
Show Gist options
  • Save jsmney/fcdb5b3a84b7a6e9844c506910235813 to your computer and use it in GitHub Desktop.
Save jsmney/fcdb5b3a84b7a6e9844c506910235813 to your computer and use it in GitHub Desktop.

Act II:

Romeo lingers near the Capulet house to talk with Juliet when she appears in her window. The pair declare their love for one another and intend to marry the next day. With the help of Juliet's Nurse, the lovers arrange to marry when Juliet goes for confession at the cell of Friar Laurence. There, they are secretly married (talk about a short engagement).


Prompt

Right before they get married, Romeo forgets what he originally planned to say in his vows! He quickly excuses himself to use the chamber pot to come up with something clever and meaningful. Romeo suddenly remembers that before Juliet was in love with him, she was in love with math! He has this vague memory of her saying something about how much she loves numbers that are happy?

Write a function that determines if a number is considered "happy". Per Juliet's description, a happy number is a positive integer that if the sum each individual digit is squared, the result will eventually become 1. Any other number that repeats into an endless cycle is not considered happy and should return false. Complicated, right? Juliet must really love math...


Examples

// Input: 19
happyNum(19); // should return true

// Explanation
/* 
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1 and therefore happy
*/

// Input: 12
happyNum(12); // should return false

// Explanation
/*
1^2 + 2^2 = 5
5^2 = 25
2^2 + 5^2 = 29
2^2 + 9^2 = 85
8^2 + 5^2 = 89 <-- 
8^2 + 9^2 = 145
1^2 + 4^2 + 5^2 = 42
4^2 + 2^2 = 20
2^2 + 0^2 = 4
4^2 = 16
1^2 + 6^2 = 37
3^2 + 7^2 = 58
5^2 + 8^2 = 89 // REPEAT and therefore not happy :(
*/

Some happy numbers for testing purposes...

1, 7, 10, 13, 19, 23, 28, 31, 32, 44, 49, 68, 70, 79, 82, 86, 91, 94, 97, 100, 103, 109, 129, 130, 133, 139, 167, 176, 188, 190, 192, 193, 203, 208, 219, 226, 230, 236, 239, 262, 263, 280, 291, 293, 301, 302, 310, 313, 319, 320, 326, 329, 331, 338, 356, 362, 365, 367, 368, 376, 379, 383, 386, 391, 392, 397, 404, 409, 440, 446, 464, 469, 478, 487, 490, 496, 536, 556, 563, 565, 566, 608, 617, 622, 623, 632, 635, 637, 638, 644, 649, 653, 655, 656, 665, 671, 673, 680, 683, 694, 700, 709, 716, 736, 739, 748, 761, 763, 784, 790, 793, 802, 806, 818, 820, 833, 836, 847, 860, 863, 874, 881, 888, 899, 901, 904, 907, 910, 912, 913, 921, 923, 931, 932, 937, 940, 946, 964, 970, 973, 989, 998, 1000







Approach

There should be some sort of loop/recursion happening so that we can keep checking the sum of the squares of the digits for each number. When we do this, there are two cases that could occur:

  • The sum of the squares eventually gets to 1 - return true
  • The sequence of sums of the squares starts looping, never reaching 1 - return false

We can check for the first case somewhat easily. But what about the second? We don't want to be trapped in an infinite loop! How can we check if we've been here before? How can we check if we've been here before? How can we check if we've been here before?

... Memoization!

That's right, we can store previously found sums of squares in some kind of data structure! Since we are only storing the number and don't need a key-value pair, we could use something like a Set. Depending on your approach, you can fold this into your function parameters (in a recursive solution) or declare it and use it within the function itself (iterative solution).

Solutions

View these on a repl

Iterative Solution

// helper function
function digitSum (n) {
// divides digits into an array. Returns sum of the squares of each digit
  return n.toString().split('').map(digit => +digit).reduce((acc, cur) => acc += Math.pow(cur, 2), 0)
}

function isHappy (n) {
  let sum = digitSum(n)

  const nSet = new Set()
  nSet.add(n)

  while (sum != 1 && !nSet.has(sum)) {
    nSet.add(sum)
    const newSum = digitSum(sum)
    sum = newSum;
  }
  if (sum === 1) return true;
  if (nSet.has(sum)) return false;

}

Recursive Solution

function isHappy (n, nSet = new Set()) {
  // when recursing, if we have already gotten to this number, we are in an endless cycle - return false :(
    if (nSet.has(n)) return false;
    
  // get all digits
  const digitsArr = n.toString().split('').map(digit => +digit)
  
  // find sum of squares of digits
  const digitSum = digitsArr.reduce((acc, cur) => acc += Math.pow(cur, 2), 0)
  
  // if all squares equal to 1, number is happy!
  if (digitSum === 1) return true;
    
  else {
    nSet.add(n);
    return isHappy(digitSum, nSet)
  }
};

"But soft, what light through yonder window breaks? It is the east, and Juliet is the sun. 932, 7, 899, 19, 86. 847? 226, 13, 301, 313, 28, 478, 736!"

Next Time on Love is in the Air REACTO:

Following the secret marriage, Juliet's cousin Tybalt sends a challenge to Romeo! fencing picture

Back to the main storyline

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment