From a3edcaeaf4395b95ff5b21238e5fd2e45a5f14a4 Mon Sep 17 00:00:00 2001 From: HJ Date: Wed, 13 Dec 2023 18:20:30 -0500 Subject: day 13 gleam complete --- aoc2023/.DS_Store | Bin 0 -> 6148 bytes aoc2023/src/day13/.gitignore | 1 + aoc2023/src/day13/solve.gleam | 84 ++++++++++++++++++++++++++++++++++++ aoc2023/test/day13/day13_test.gleam | 76 ++++++++++++++++++++++++++++++++ 4 files changed, 161 insertions(+) create mode 100644 aoc2023/.DS_Store create mode 100644 aoc2023/src/day13/.gitignore create mode 100644 aoc2023/src/day13/solve.gleam create mode 100644 aoc2023/test/day13/day13_test.gleam (limited to 'aoc2023') diff --git a/aoc2023/.DS_Store b/aoc2023/.DS_Store new file mode 100644 index 0000000..5172429 Binary files /dev/null and b/aoc2023/.DS_Store differ diff --git a/aoc2023/src/day13/.gitignore b/aoc2023/src/day13/.gitignore new file mode 100644 index 0000000..ae40cea --- /dev/null +++ b/aoc2023/src/day13/.gitignore @@ -0,0 +1 @@ +input.txt \ No newline at end of file diff --git a/aoc2023/src/day13/solve.gleam b/aoc2023/src/day13/solve.gleam new file mode 100644 index 0000000..a597074 --- /dev/null +++ b/aoc2023/src/day13/solve.gleam @@ -0,0 +1,84 @@ +import adglent.{First, Second} +import gleam/io +import gleam/list +import gleam/string +import gleam/result + +type SymmetryType { + Horizontal(Int) + Vertical(Int) +} + +fn is_symmetric(xs: List(List(a)), errors: Int, index: Int) -> Result(Int, Nil) { + case list.split(xs, index) { + #(_, []) -> Error(Nil) + #(ls, rs) -> { + let zipped = list.zip(list.flatten(list.reverse(ls)), list.flatten(rs)) + let found_errors = + zipped + |> list.filter(fn(tup) { tup.1 != tup.0 }) + |> list.length + case found_errors == errors { + True -> Ok(index) + False -> is_symmetric(xs, errors, index + 1) + } + } + } +} + +fn get_symmetry_type(xs: List(List(String)), errors: Int) { + result.or( + xs + |> is_symmetric(errors, 1) + |> result.map(Horizontal(_)), + xs + |> list.transpose() + |> is_symmetric(errors, 1) + |> result.map(Vertical(_)), + ) +} + +fn summarize_notes(symmetries: List(SymmetryType)) { + use acc, note <- list.fold(symmetries, 0) + case note { + Horizontal(n) -> 100 * n + Vertical(n) -> n + } + acc +} + +fn solve(input: String, errors: Int) { + input + |> string.split("\n\n") + |> list.map(fn(strs) { + strs + |> string.split("\n") + |> list.map(string.to_graphemes) + |> get_symmetry_type(errors) + }) + |> result.values + |> summarize_notes + |> string.inspect +} + +pub fn part1(input: String) { + solve(input, 0) +} + +pub fn part2(input: String) { + solve(input, 1) +} + +pub fn main() { + let assert Ok(part) = adglent.get_part() + let assert Ok(input) = adglent.get_input("13") + case part { + First -> + part1(input) + |> adglent.inspect + |> io.println + Second -> + part2(input) + |> adglent.inspect + |> io.println + } +} diff --git a/aoc2023/test/day13/day13_test.gleam b/aoc2023/test/day13/day13_test.gleam new file mode 100644 index 0000000..7c65bed --- /dev/null +++ b/aoc2023/test/day13/day13_test.gleam @@ -0,0 +1,76 @@ +import gleam/list +import showtime/tests/should +import adglent.{type Example, Example} +import day13/solve + +type Problem1AnswerType = + String + +type Problem2AnswerType = + String + +/// Add examples for part 1 here: +/// ```gleam +///const part1_examples: List(Example(Problem1AnswerType)) = [Example("some input", "")] +/// ``` +const part1_examples: List(Example(Problem1AnswerType)) = [ + Example( + "#.##..##. +..#.##.#. +##......# +##......# +..#.##.#. +..##..##. +#.#.##.#. + +#...##..# +#....#..# +..##..### +#####.##. +#####.##. +..##..### +#....#..#", + "405", + ), +] + +/// Add examples for part 2 here: +/// ```gleam +///const part2_examples: List(Example(Problem2AnswerType)) = [Example("some input", "")] +/// ``` +const part2_examples: List(Example(Problem2AnswerType)) = [ + Example( + "#.##..##. +..#.##.#. +##......# +##......# +..#.##.#. +..##..##. +#.#.##.#. + +#...##..# +#....#..# +..##..### +#####.##. +#####.##. +..##..### +#....#..#", + "400", + ), +] + +pub fn part1_test() { + part1_examples + |> should.not_equal([]) + use example <- list.map(part1_examples) + solve.part1(example.input) + |> should.equal(example.answer) +} + +pub fn part2_test() { + part2_examples + |> should.not_equal([]) + use example <- list.map(part2_examples) + solve.part2(example.input) + |> should.equal(example.answer) +} -- cgit v1.2.3