DEV Community

Jan Küster
Jan Küster

Posted on

Javascript puzzle - seal the secret

Write a function seal that receives an input String str and "saves" the string.

When passing the exact String again it should return true, while passing any other argument it should return false.

seal(str) // saved
seal(str) // true
seal(otherStr) // false
Enter fullscreen mode Exit fullscreen mode

Conditions:

The string should not be revealed when printing the function or any of it's properties via toString.

Beginners:

  • use any technique you like

Advanced:

  • the function should be self-contained and independent from any externals

Note:

  • don't expect a solution to be something usable for a production environment

Top comments (3)

Collapse
 
thormeier profile image
Pascal Thormeier

Really nice exercise! Got me thinking. Simplest approach would be to introduce state to the function, i.e. a member variable (this.strings = []), but that wouldn't seal the strings away. A quick inspection of the code via .toString() would reveal the name of the member and thus reveal the strings.

I went on to more of a scripting approach by introducing a factory function that would create a seal function that would then store away the strings, never to be accessed outside of the function itself:

const sealFactory = (sealedStrings = []) => {
   return (string) => {
     if (sealedStrings.includes(string)) {
       return true
     }

     sealedStrings.push(string)
     seal = sealFactory(sealedStrings)

     return false
   }
}

let seal = sealFactory()

console.log(seal("Foo")) // false
console.log(seal("Bar")) // false
console.log(seal("Foo")) // true
console.log(seal("Bar")) // true
Enter fullscreen mode Exit fullscreen mode

I didn't really find a quick way to put this all in a single function that doesn't return a function via side effect, so I kinda violated the "externals" and "self-contained" constraints, but at least the strings are safe!

Collapse
 
alexmustiere profile image
Alex Mustiere

Using an IIFE should do the trick

const seal = ((sealedStrings = []) => {
  let sealedString;
  return (str) => {
    if (sealedString === str) {
      return true;
    }
    if (sealedString === undefined) {
      sealedString = str;
      return 'saved';
    }
    return false;
  };
})();

console.log(seal("Foo")); // saved
console.log(seal("Bar")); // false
console.log(seal("Foo")); // true
console.log(seal("Bar")); // false
Enter fullscreen mode Exit fullscreen mode


`

Collapse
 
thormeier profile image
Pascal Thormeier

I used an empty array to seal more than one string. The factory function could take an empty array initially, but I thought I'd add it as the default value. For some reason I thought multi string support was an unclearly communicated requirement, but it doesn't really change much.