Skip to content

Commit

Permalink
feat: add 2023/11
Browse files Browse the repository at this point in the history
  • Loading branch information
mtsknn committed Oct 18, 2024
1 parent 5e1697c commit b283e0c
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,5 @@ Though note that the test assertions use my personal results
and then calculate the polygon's area,
and then subtract the amount of boundary (non-interior) points from the area...
who would have thought!

- [`year_2023/day_11.gleam`](./src/year_2023/day_11.gleam) × [adventofcode.com/2023/day/11](https://adventofcode.com/2023/day/11)
92 changes: 92 additions & 0 deletions src/year_2023/day_11.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import gleam/int
import gleam/list
import gleam/result
import gleam/string

const rows_to_cols = list.transpose

// This could be simplified to just call `part_2` with `expansion_factor: 2`,
// but I'm keeping this naiver approach because why not
pub fn part_1(input: String) -> Int {
input
|> input_to_rows
|> expand_empty_rows
|> rows_to_cols
|> expand_empty_rows
|> list.index_map(fn(col, x) {
col
|> list.index_map(fn(char, y) {
case char {
"." -> Error(Nil)
___ -> Ok(#(x, y))
}
})
})
|> list.flatten
|> result.values
|> distances
}

pub fn part_2(input: String, expansion_factor expansion_factor: Int) -> Int {
let rows = input |> input_to_rows
let row_indexes = rows |> indexes(expansion_factor:)

let cols = rows |> list.transpose
let col_indexes = cols |> indexes(expansion_factor:)

list.map2(rows, row_indexes, fn(row, y) {
list.map2(row, col_indexes, fn(char, x) {
case char {
"." -> Error(Nil)
___ -> Ok(#(x, y))
}
})
})
|> list.flatten
|> result.values
|> distances
}

fn input_to_rows(input: String) -> List(List(String)) {
input
|> string.trim
|> string.split("\n")
|> list.map(string.to_graphemes)
}

fn expand_empty_rows(rows: List(List(String))) {
rows
|> list.flat_map(fn(row) {
case row |> is_empty {
True -> [row, row]
False -> [row]
}
})
}

fn is_empty(row: List(String)) -> Bool {
row |> list.all(fn(char) { char == "." })
}

fn distances(coords: List(#(Int, Int))) -> Int {
coords
|> list.combination_pairs
|> list.map(fn(pair) {
let #(#(x1, y1), #(x2, y2)) = pair
int.absolute_value(y1 - y2) + int.absolute_value(x1 - x2)
})
|> int.sum
}

fn indexes(
rows: List(List(String)),
expansion_factor expansion_factor: Int,
) -> List(Int) {
rows
|> list.scan(0, fn(index, row) {
case row |> is_empty {
True -> index + expansion_factor
False -> index + 1
}
})
}
45 changes: 45 additions & 0 deletions test/year_2023/day_11_test.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import glacier/should
import gleam/result
import utils
import year_2023/day_11

pub fn part_1_with_example_input_test() {
day_11.part_1(example_input)
|> should.equal(374)
}

pub fn part_2_with_example_input_test() {
// Basically the same as part 1:
day_11.part_2(example_input, expansion_factor: 2)
|> should.equal(374)

day_11.part_2(example_input, expansion_factor: 10)
|> should.equal(1030)

day_11.part_2(example_input, expansion_factor: 100)
|> should.equal(8410)
}

pub fn full_input_test() {
utils.read_input(2023, 11)
|> result.map(fn(input) {
day_11.part_1(input)
|> should.equal(9_591_768)

day_11.part_2(input, expansion_factor: 1_000_000)
|> should.equal(746_962_097_860)
})
}

const example_input = "
...#......
.......#..
#.........
..........
......#...
.#........
.........#
..........
.......#..
#...#.....
"

0 comments on commit b283e0c

Please sign in to comment.