diff --git a/src/day_02.gleam b/src/day_02.gleam new file mode 100644 index 0000000..16d4b95 --- /dev/null +++ b/src/day_02.gleam @@ -0,0 +1,61 @@ +import gleam/bool +import gleam/int +import gleam/list +import gleam/string + +pub type Range { + Range(min: Int, max: Int) +} + +pub fn format_input(input: String) -> List(Range) { + input + |> string.split(",") + |> list.map(fn (range) { + let assert [min, max] = + range + |> string.replace(each: "\n", with: "") + |> string.split("-") + let assert Ok(min_int) = int.parse(min) + let assert Ok(max_int) = int.parse(max) + + Range(min: min_int, max: max_int) + }) +} + +fn is_repeated(number: String) -> Bool { + let number_length = string.length(number) + + use <- bool.guard(when: number_length % 2 != 0, return: False) + + number + |> string.slice(at_index: number_length / 2, length: number_length) + |> string.starts_with(number, _) +} + +fn find_duplicates(range: Range, acc: List(Int)) -> List(Int) { + let Range(min: min, max: max) = range + + use <- bool.guard(when: min > max, return: acc) + + case min |> int.to_string |> is_repeated { + True -> find_duplicates( + Range(min: min + 1, max: max), + [min, ..acc] + ) + False -> find_duplicates( + Range(min: min + 1, max: max), + acc + ) + } +} + +pub fn calculate_duplicates(ranges: List(Range)) -> Int { + ranges + |> list.fold(0, fn (acc, range) { + let arr = range + |> find_duplicates([]) + |> list.fold(0, fn (a, b) { a + b }) + + acc + arr + }) +} diff --git a/test/day_02_test.gleam b/test/day_02_test.gleam new file mode 100644 index 0000000..c9a60e2 --- /dev/null +++ b/test/day_02_test.gleam @@ -0,0 +1,36 @@ +import simplifile +import day_02.{Range} + +pub fn read_input_test() { + assert "11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124" + |> day_02.format_input + == [ + Range(min: 11, max: 22), + Range(min: 95, max: 115), + Range(min: 998, max: 1012), + Range(min: 1188511880, max: 1188511890), + Range(min: 222220, max: 222224), + Range(min: 1698522, max: 1698528), + Range(min: 446443, max: 446449), + Range(min: 38593856, max: 38593862), + Range(min: 565653, max: 565659), + Range(min: 824824821, max: 824824827), + Range(min: 2121212118, max: 2121212124), + ] +} + +pub fn calculate_duplicates_test() { + assert "11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124" + |> day_02.format_input + |> day_02.calculate_duplicates + == 1227775554 +} + +pub fn calculate_duplicates_for_real_test() { + let assert Ok(file) = simplifile.read("input/day_02") + + assert file + |> day_02.format_input + |> day_02.calculate_duplicates + == 18595663903 +}