{"size": 1282, "ext": "js", "max_stars_repo_path": "2021/day12.js", "max_stars_repo_name": "ropaolle/adventofcode", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "2021/day12.js", "max_issues_repo_name": "ropaolle/adventofcode", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "2021/day12.js", "max_forks_repo_name": "ropaolle/adventofcode", "max_forks_repo_forks_event_min_datetime": "2022-01-03T18:49:34.000Z", "max_forks_repo_forks_event_max_datetime": "2022-01-03T18:49:34.000Z"}
{"max_stars_count": null, "max_issues_count": null, "max_forks_count": 1, "avg_line_length": 22.1034482759, "max_line_length": 75, "alphanum_fraction": 0.5436817473}
const parse = (input) => {
  return input.split('\n').map((v) => v.split('-'));
};

const next = (links, u) => [
  ...links.filter((link) => link[0] === u).map((link) => link[1]),
  ...links.filter((link) => link[1] === u).map((link) => link[0]),
];

const pushFrontier = (frontier, v, visited, canSkip) => {
  if (visited.includes(v)) {
    if (canSkip && v !== 'start') {
      frontier.push({ u: v, visited, canSkip: false });
    }
  } else {
    frontier.push({ u: v, visited, canSkip });
  }

  return frontier;
};

const paths = (links, { allowOneSmallCave } = {}) => {
  let frontier = [{ u: 'start', visited: [], canSkip: allowOneSmallCave }];
  let p = 0;

  while (frontier.length > 0) {
    let { u, visited, canSkip } = frontier.pop();

    visited = [...visited];
    if (u === u.toLowerCase()) {
      visited.push(u);
    }

    for (const v of next(links, u)) {
      if (v === 'end') {
        p++;
      } else {
        frontier = pushFrontier(frontier, v, visited, canSkip);
      }
    }
  }

  return p;
};

const partOne = (input) => {
  const data = parse(input);
  return paths(data);
};

const partTwo = (input) => {
  const data = parse(input);
  return paths(data, { allowOneSmallCave: true });
};

exports.partOne = partOne;
exports.partTwo = partTwo;
