Goal Function

Here's a puzzle I recently came across. We need to implement a function g as follows

g('al')       -> 'gal'
g()('al')     -> 'goal'
g()()('al')   -> 'gooal'
g()()()('al') -> 'goooal'
and so on.

We can make the following observations

  1. We need to return either a string or a function, depending on the input.
  2. We need to keep track of how many times the function has been called.

So, keeping these in mind, let us start with a simple function that returns a string when supplied with 'al'.

function g(x) {
  if (x === 'al')
    return 'gal';
}

Now, to get the function:

function g(x) {
  if (x === 'al')
    return 'gal';

  else
    return function() {}
}

We know we need to keep track of the number of times the function has been called. We could keep a numeric counter, but then we can just as easily keep a string and keep incrementing it. It would also be simpler to have the logic inside the inner function and have it return either itself, or the final string. And the outer function can simply return the output of the inner function with the initial arguments (to handle the case g('al') -> 'gal'). Here is the final solution:

function g(x) {
  var str = 'g';
  var inner = function inner(x) {
    if (x === 'al')
      return str + 'al';

    else {
      str += 'o';
      return inner;
    }
  };

  return inner(x);
}

console.log(g('al'));     // gal
console.log(g()('al'));   // goal
console.log(g()()('al')); // gooal

I was told that there are a number of solutions out there for the goal function and sure enough, a google search for 'goooal function' returns a number of solutions, all of them quite interesting. My own solution is in this codepen.