Skip to content

Commit

Permalink
2021.12
Browse files Browse the repository at this point in the history
  • Loading branch information
Doruk Gurleyen committed Dec 12, 2021
1 parent 77dceae commit c735ab6
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 0 deletions.
72 changes: 72 additions & 0 deletions challenges/2021/12.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
Code.compile_file(Path.join([__ENV__.file], ["../../../utils/utils.exs"]))

defmodule Challenge do
@moduledoc false

def first_result(input) do
input
|> parse_input
|> build_cave_states
|> explore("start")
end

def second_result(input) do
input
|> parse_input
|> build_cave_states
|> explore("start", 2)
end

defp explore(states, cave, max_sm_cave_visits \\ 1, seen_sm_cave \\ false)
defp explore(_states, "end", _max_sm_cave_visits, _seen_sm_cave), do: 1

defp explore(states, cave, max_sm_cave_visits, seen_sm_cave) do
{adjacencies, visited} = Map.get(states, cave)

cave
|> updated_visited_count(visited, seen_sm_cave, max_sm_cave_visits)
|> case do
nil ->
0

new_visited_count ->
updated_states = Map.put(states, cave, {adjacencies, new_visited_count})

Enum.reduce(
adjacencies,
0,
&(&2 + explore(updated_states, &1, max_sm_cave_visits, seen_sm_cave || visited > 0))
)
end
end

defp updated_visited_count(cave, seen_count, seen_sm_cave, max_sm_cave_visits \\ 1)
defp updated_visited_count(_cave, 1, _, 1), do: nil
defp updated_visited_count(_cave, 2, _seen_sm_cave, 2), do: nil
defp updated_visited_count(_cave, 1, true, 2), do: nil

defp updated_visited_count(cave, seen_count, _seen_sm_cave, _max_sm_cave_visits),
do: if(String.downcase(cave) == cave, do: seen_count + 1, else: 0)

defp build_cave_states(adjacencies) do
Enum.reduce(adjacencies, %{}, fn [left, right], acc ->
left_state = Map.get(acc, left, {[], 0})
right_state = Map.get(acc, right, {[], 0})

updated_left_state = maybe_add_to_adjacencies(right, left_state)
updated_right_state = maybe_add_to_adjacencies(left, right_state)

acc
|> Map.put(left, updated_left_state)
|> Map.put(right, updated_right_state)
end)
end

defp maybe_add_to_adjacencies("start", state), do: state
defp maybe_add_to_adjacencies(cave, state), do: {[cave | elem(state, 0)], elem(state, 1)}

defp parse_input(input), do: Enum.map(input, &String.split(&1, "-"))
end

Utils.run(&Challenge.first_result/1, __ENV__.file, "Q1")
Utils.run(&Challenge.second_result/1, __ENV__.file, "Q2")
61 changes: 61 additions & 0 deletions challenges/2021/12.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Part 1
const solvePuzzle1 = (input) => {
const caveStates = buildCaveStates(parseInput(input));
const getIncrementVisitedBy = (cave, visited) => {
if (visited) return null;
if (cave.toLowerCase() === cave) return 1;
return 0;
};
return explore("start", caveStates, getIncrementVisitedBy);
};

// Part 2
const solvePuzzle2 = (input) => {
const caveStates = buildCaveStates(parseInput(input));
const getIncrementVisitedBy = (cave, visitedCount, visitedSmallCave) => {
if (visitedCount === 2 || (visitedCount === 1 && visitedSmallCave)) return null;
if (cave.toLowerCase() === cave) return 1;
return 0;
};
return explore("start", caveStates, getIncrementVisitedBy);
};

const addCaveToAdjacencies = (cave, state) => {
if (!state) return null;
cave !== "start" && state[0].push(cave);
return state;
};

const buildCaveStates = (input) => {
const caveStates = new Map();
for (let [left, right] of input) {
addCaveToAdjacencies(right, caveStates.get(left)) || caveStates.set(left, createCaveState(right));
addCaveToAdjacencies(left, caveStates.get(right)) || caveStates.set(right, createCaveState(left));
}
return caveStates;
};

const createCaveState = (cave) => (cave !== "start" ? [[cave], 0] : [[], 0]);

const explore = (cave, caveStates, getIncrementVisitedBy, visitedSmallCave = false) => {
if (cave === "end") return 1;

const stateOfTheCave = caveStates.get(cave);
const [adjacencies, visited] = stateOfTheCave;
const incrementVisitedBy = getIncrementVisitedBy(cave, visited, visitedSmallCave);

if (incrementVisitedBy == null) return 0;
stateOfTheCave[1] += incrementVisitedBy;

const pathsFound = adjacencies.reduce(
(acc, val) => acc + explore(val, caveStates, getIncrementVisitedBy, visitedSmallCave || visited),
0
);
stateOfTheCave[1] -= incrementVisitedBy;
return pathsFound;
};

const parseInput = (input) => input.split("\n").map((l) => l.split("-"));

require(__dirname + "/../../utils/test.js").test(__filename, __dirname, solvePuzzle1);
require(__dirname + "/../../utils/test.js").test(__filename, __dirname, solvePuzzle2);
23 changes: 23 additions & 0 deletions challenges/2021/inputs/12.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
pn-TY
rp-ka
az-aw
al-IV
pn-co
end-rp
aw-TY
rp-pn
al-rp
end-al
IV-co
end-TM
co-TY
TY-ka
aw-pn
aw-IV
pn-IV
IV-ka
TM-rp
aw-PD
start-IV
start-co
start-pn

0 comments on commit c735ab6

Please sign in to comment.