Solving the Sea Monster TED-Ed Riddle using Vanilla Javascript

Seantarzy
5 min readNov 20, 2020

I am a huge fan of TED-Ed riddles. When quarantine was in full-swing, my brother and I would pop one on the TV, and try to see who can solve it first (or if either of us could solve it at all). As a coder, I find that working through these riddles flexes the same kind of problem-solving muscles excersized in creating apps. I found that there was such a strong link between TED-Ed Riddles and coding, that I decided to bridge the gap even closer.

In this Blog Post, I will walk through how to solve a TED-Ed riddle using a single Javascript file. The riddle today will be the “Sea Monster Riddle.” Let’s check that out first:

Pretty heavy stuff. Ok, so I’ll assume you at least watched up until around the 2 minute mark, before the answer is revealed.

To summarize:

  • A host of sea monsters, 7 LeviathinLords, 10 crackenCommanders, and 12 mermiteMinions, are threatening to destroy your city
  • They will go away if they receive a ransom of pearls
  • The pearls must be given to the Leviathin Lords first, divided evenly among the 7 of them, then each lord will evently take his or her share as well as disperse the rest of the shares to the rest of his or her 10 Cracken Commanders. Each commander will do the same with his or herself and his or her 12 minions.
  • We have to give them an amount of treasure that will be evenly distributed from the first Leviathin Lord to the last Mermite Minion. If one pearl is left over, our city of Atlantarctica is destroyed. Tough but fair.
  • We have 5 treasure chests of pears to choose from. Each chest has symbols on it that we do not have time to translate into numbers. One chest is the one that will save the city, the other four will lead to doom.

Let’s gather our variables, starting with the creatures we have to appease:

const leviathinLords = {count: 7}const crackenCommanders = {count: 10}const mermiteMinions = {count: 12}

Ok great, now let’s list out the treasure chests that we have to choose from:

const treasureChests = [treasureChestOne = {chestSymbols:'TNT NTN'},treasureChestTwo = {chestSymbols: 'EFK EFK'},treasureChestThree = {chestSymbols: 'TEC CET'},treasureChestFour = {chestSymbols: 'KKZ ZCC'},treasureChestFive = {chestSymbols: 'HTE TEH'}]

I think I did a pretty decent job of converting the weird symbols into letters based on what they look like. The real point is that they are not numbers and we don’t know what numbers they represent.

Ok, that’s all the variables we need. Now we can start our function:

function saveAtlantarctica(lords, commanders, minions, treasures){}

First thing I’ll do is calculate the shares that must be distributed:

let firstShare = lords.count;let secondShare = commanders.count + 1;//has to be divided among the 10 cracken commanders, plus one for the Leviathin Lordlet thirdShare = minions.count + 1//has to be divided among the 12 Mermite Minions, plus one for the Cracken Commander

Great. So the thing is, we have to make sure whatever number of treasure we give out, it has to be divided evenly, from the lords down to the minions. We can calculate the least common multiple to find out multiples of what we can give to our creature friends that will be fully divided evenly. It’s actually very simple to calculate in this case. Why? Because all the share numbers are prime! Let’s have our code check to make sure each one is prime:

function isPrime(num){let potentialFactor = Math.floor(num/2);while(potentialFactor > 1){if(num % potentialFactor == 0){//if the number can be divided evenly by a number that//is not itself or one, return falsereturn false}potentialFactor--}//if it refuses to be divided by anything, it's primereturn true}

So now that we have a function to check if every number share is prime, let’s talk about what will it mean for our numbers to be prime. That means that the least common multiple is simply all of those numbers multiplied by each other, so…

let LCM;if (isPrime(firstShare) && isPrime(secondShare) && isPrime(thirdShare)) {LCM = firstShare * secondShare * thirdShare;//since all of the inputs are prime, that means that the amount of gold we will need//is a multiple of this ^ LCM (Lowest Common Multiple)}

Ok, so the LCM in our case is 7 X 11 X 13, which equals 1001.

1001. Cool. But our chest symbols look like they translate to 6 digit numbers. Our “lucky length” is 6:

//There is no way to decode what the actual numbers on the chest are, but we can look for patterns//first thing, would be find the length of the string (minus the space in the middle)// since they are all the same length, any chest will doconst luckyLength = treasures[0].chestSymbols.length - 1;

So let’s write a function to find an array of multiples of our LCM (1001) that have 6 digits:

function reachLuckyLength(num, length){let multiplier = 2copyOfNum = numnumbersToDecode = []while(num.toString().length <= length){num = copyOfNum * multipliermultiplier++if(num.toString().length == length){numbersToDecode.push(num);}}return numbersToDecode}

Let’s look at the first one:

let numbersToDecode = reachLuckyLength(LCM, luckyLength);console.log(numbersToDecode[0])
//result: 100100

100,100. That’s a pattern if I’ve ever seen one. Let’s print out more to see if the pattern persists:

// console.log(numbersToDecode.slice(1,60));//next 60 results: [101101, 102102, 103103, 104104, 105105,// 106106, 107107, 108108, 109109, 110110,// 111111, 112112, 113113, 114114, 115115,// 116116, 117117, 118118, 119119, 120120,// 121121, 122122, 123123, 124124, 125125,// 126126, 127127, 128128, 129129, 130130,// 131131, 132132, 133133, 134134, 135135,// 136136, 137137, 138138, 139139, 140140,// 141141, 142142, 143143, 144144, 145145,// 146146, 147147, 148148, 149149, 150150,// 151151, 152152, 153153, 154154, 155155,// 156156, 157157, 158158, 159159]

Yup. It persists. Let’s define the pattern we see: Looks like the first three numbers (or in the treasure chest’s case, the first three characters) can be anything, however the last three numbers (or characters) MUST repeat the sequence.

This is pretty simple…

To check if one chest is the one we want:

function isSecretJackPot(symbols) {let symbolsByParts = symbols.split(" ");//split the symbols about the middle spacelet firstSequence = symbolsByParts[0];let secondSequence = symbolsByParts[1];if (firstSequence == secondSequence) {return true;} else {return false;}

Now let’s just write a function that iterates through all of the chests and uses the above function at each iteration:

function findTheSecretJackpot(treasureArray) {for (let i = 0; i < treasureArray.length; i++) {//   console.log(treasureArray[i].chestSymbols)if (isSecretJackPot(treasureArray[i].chestSymbols)) {return treasureArray[i];}}}

Define the jackpot, baby!

let secretJackpot = findTheSecretJackpot(treasures);

Upon returning it…

console.log(`The chest we want to give to save the day is: ${secretJackpot}`);return secretJackpot;//result: { chestSymbols: 'EFK EFK' }

The result is the second one in our list: “EFK EFK.”

Dope. Die another day.

Watch the rest of the riddle and you’ll see it checks out.

Full Code: https://github.com/seanytdawg/Sea-Monster-TED-Ed-Riddle/tree/main

--

--