solve = (solution, problem) => {
  for (const part of problem) {
    if (part === '.' || part === '') {
      // no-op
    } else if (part === '..') {
      if (solution.length === 0) {
        return false;
      }
      solution.pop();
    } else {
      solution.push(part);
    }
  }
  return true;
}
Advances a partial module specifier solution by following the path
components in the given problem.
The problem may not produce a path that escapes the solution, that is, the
problem may not traverse up from an empty solution.
`Solve` returns false if the problem attempts to escape.
Advanding a partial solution is the core of `resolve`, `join`, and
`relativize`, which have different invariants.

@param {Array<string>} solution - fully resolved path components, including
any from a prior path resolution initially.
@param {Array<string>} problem - partially resolved path components, that
is, including '.' and '..' components.
@returns {boolean} whether the solver terminated early because of a
nonsensical attempt to traverse above the root directory.