public Puzzle solve_r(Stack<Puzzle> stack) {

    while (!stack.empty()) {
      Puzzle current = stack.pop();
      if (current.isSolved()) {
        return current;
      }
      int hashCode = current.hashCode();
      if (current.getNumMoves() < maxDepth
          && (!visited.containsKey(hashCode)
              || (visited.containsKey(hashCode)
                  && visited.get(hashCode) > current.getNumMoves()))) {
        visited.put(hashCode, current.getNumMoves());
        for (Puzzle.Move move : current.getPossibleMoves()) {
          stack.push(current.swap(move));
        }
      }
    }
    return null;
  }