diff --git a/.gitignore b/.gitignore index ad683b3..ddd469b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ /build erl_crash.dump -input_*.txt +solve_*.txt diff --git a/src/gloat.gleam b/src/gloat.gleam index e258f17..4fc1873 100644 --- a/src/gloat.gleam +++ b/src/gloat.gleam @@ -3,15 +3,22 @@ import gleam/int import gleam/io import simplifile import solve_2024_01 +import solve_2024_02 pub fn main() -> Nil { case argv.load().arguments { ["2024", "1"] -> display( - "src/input_2024_01.txt", + "src/solve_2024_01.txt", solve_2024_01.part_one, solve_2024_01.part_two, ) + ["2024", "2"] -> + display( + "src/solve_2024_02.txt", + solve_2024_02.part_one, + solve_2024_02.part_two, + ) _ -> io.print("Please provide a year and day") } } diff --git a/src/solve_2024_02.gleam b/src/solve_2024_02.gleam new file mode 100644 index 0000000..73dac4f --- /dev/null +++ b/src/solve_2024_02.gleam @@ -0,0 +1,75 @@ +import gleam/int +import gleam/list +import gleam/order +import gleam/string + +pub fn part_one(input: String) -> Int { + input + |> string.split("\n") + |> list.filter(fn(line) { + let levels = + string.split(line, " ") + |> list.flat_map(fn(item) { + case int.base_parse(item, 10) { + Ok(value) -> [value] + Error(_) -> [] + } + }) + |> list.window_by_2() + + case levels { + [#(first, second), ..] -> + list.all(levels, fn(pair) { + let #(left, right) = pair + safe(left, right, int.compare(first, second)) + }) + + _ -> False + } + }) + |> list.length() +} + +pub fn part_two(input: String) -> Int { + input + |> string.split("\n") + |> list.map(fn(line) { + string.split(line, " ") + |> list.flat_map(fn(item) { + case int.base_parse(item, 10) { + Ok(value) -> [value] + Error(_) -> [] + } + }) + }) + |> list.filter(fn(report) { + [ + report, + ..list.flat_map(report, fn(_) { + list.index_map(report, fn(_, index) { drop_from_list(report, index) }) + }) + ] + |> list.any(fn(comination) { + let levels = list.window_by_2(comination) + case levels { + [#(first, second), ..] -> + levels + |> list.all(fn(pair) { + let #(left, right) = pair + safe(left, right, int.compare(first, second)) + }) + _ -> False + } + }) + }) + |> list.length() +} + +fn safe(left: Int, right: Int, order: order.Order) -> Bool { + let difference = int.absolute_value(left - right) + 1 <= difference && difference <= 3 && order == int.compare(left, right) +} + +fn drop_from_list(list: List(t), index: Int) -> List(t) { + list.append(list.take(list, index), list.drop(list, index + 1)) +} diff --git a/test/test_2024_02.gleam b/test/test_2024_02.gleam new file mode 100644 index 0000000..f539eca --- /dev/null +++ b/test/test_2024_02.gleam @@ -0,0 +1,30 @@ +import gleam/string +import solve_2024_02 + +pub fn part_one_test() { + let input = + " +7 6 4 2 1 +1 2 7 8 9 +9 7 6 2 1 +1 3 2 4 5 +8 6 4 4 1 +1 3 6 7 9 +" + |> string.trim() + assert solve_2024_02.part_one(input) == 2 +} + +pub fn part_two_test() { + let input = + " +7 6 4 2 1 +1 2 7 8 9 +9 7 6 2 1 +1 3 2 4 5 +8 6 4 4 1 +1 3 6 7 9 +" + |> string.trim() + assert solve_2024_02.part_two(input) == 4 +}