Skip to content

Commit

Permalink
day 08: part B initial commit (off by 2)
Browse files Browse the repository at this point in the history
  • Loading branch information
sreedevk committed Dec 8, 2024
1 parent f1dc4f0 commit 40e238d
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 14 deletions.
131 changes: 118 additions & 13 deletions src/resonant_collinearity.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ type Point =
type Grid =
Dict(Point, String)

type Direction {
Forward
Reverse
}

fn parse_column(line, y) {
use grid, char, x <- list.index_fold(line, dict.new())
dict.insert(grid, #(x, y), char)
Expand All @@ -24,7 +29,10 @@ fn square(input: Float) -> Float {
}
}

fn find_collinears(point_a: Point, point_b: Point) -> List(Point) {
fn find_collinear_vector(
point_a: Point,
point_b: Point,
) -> #(Float, #(Float, Float)) {
let #(x1, y1) = point_a
let #(x2, y2) = point_b

Expand All @@ -43,18 +51,96 @@ fn find_collinears(point_a: Point, point_b: Point) -> List(Point) {
let assert Ok(dx) = float.divide(float.subtract(x2f, x1f), distance)
let assert Ok(dy) = float.divide(float.subtract(y2f, y1f), distance)

let x3f_forward = float.add(x2f, float.multiply(dx, distance))
let y3f_forward = float.add(y2f, float.multiply(dy, distance))
let x3f_reverse = float.subtract(x1f, float.multiply(dx, distance))
let y3f_reverse = float.subtract(y1f, float.multiply(dy, distance))
#(distance, #(dx, dy))
}

fn find_collinear_in_direction(
point_a: Point,
point_b: Point,
direction: Direction,
) -> Point {
let #(distance, #(dx, dy)) = find_collinear_vector(point_a, point_b)
let #(x1, y1) = point_a
let #(x2, y2) = point_b

let x1f = int.to_float(x1)
let y1f = int.to_float(y1)

let x2f = int.to_float(x2)
let y2f = int.to_float(y2)

case direction {
Forward -> #(
float.round(float.subtract(x1f, float.multiply(dx, distance))),
float.round(float.subtract(y1f, float.multiply(dy, distance))),
)
Reverse -> #(
float.round(float.add(x2f, float.multiply(dx, distance))),
float.round(float.add(y2f, float.multiply(dy, distance))),
)
}
}

fn points_within_map(points: List(Point), grid: Grid) -> Bool {
list.all(points, point_within_map(_, grid))
}

fn find_forward_harmonic_collinears(
found: List(Point),
grid: Grid,
) -> List(Point) {
let #(head, _rest) = list.split(found, 2)
let assert [p1, p2] = head
case points_within_map(head, grid) {
True -> {
find_forward_harmonic_collinears(
list.append(
list.wrap(find_collinear_in_direction(p1, p2, Forward)),
found,
),
grid,
)
}
False -> found
}
}

let x3_forward = float.round(x3f_forward)
let y3_forward = float.round(y3f_forward)
fn find_reverse_harmonic_collinears(
found: List(Point),
grid: Grid,
) -> List(Point) {
let #(head, _rest) = list.split(found, 2)
let assert [p1, p2] = head
case points_within_map(head, grid) {
True -> {
find_reverse_harmonic_collinears(
list.append(
list.wrap(find_collinear_in_direction(p1, p2, Reverse)),
found,
),
grid,
)
}
False -> found
}
}

let x3_reverse = float.round(x3f_reverse)
let y3_reverse = float.round(y3f_reverse)
fn find_all_harmonic_collinears(
point_a: Point,
point_b: Point,
grid: Grid,
) -> List(Point) {
list.append(
find_forward_harmonic_collinears([point_a, point_b], grid),
find_reverse_harmonic_collinears([point_a, point_b], grid),
)
}

[#(x3_forward, y3_forward), #(x3_reverse, y3_reverse)]
fn find_all_collinears(point_a: Point, point_b: Point) -> List(Point) {
[
find_collinear_in_direction(point_a, point_b, Forward),
find_collinear_in_direction(point_a, point_b, Reverse),
]
}

fn is_not_empty(cell: String) -> Bool {
Expand All @@ -77,7 +163,20 @@ fn collinears_for_antenna(antenna: String, g: Grid) -> List(Point) {
|> list.combinations(2)
|> list.flat_map(fn(points) {
case points {
[l1, l2] -> find_collinears(l1, l2)
[l1, l2] -> find_all_collinears(l1, l2)
_ -> []
}
})
|> list.filter(point_within_map(_, g))
|> list.unique
}

fn harmonic_collinears_for_antenna(antenna: String, g: Grid) -> List(Point) {
find_antenna_locations(antenna, g)
|> list.combinations(2)
|> list.flat_map(fn(points) {
case points {
[l1, l2] -> find_all_harmonic_collinears(l1, l2, g)
_ -> []
}
})
Expand Down Expand Up @@ -105,6 +204,12 @@ pub fn solve_a(input: String) -> Int {
|> list.length
}

pub fn solve_b(_inp: String) -> Int {
0
pub fn solve_b(input: String) -> Int {
let grid = parse_input(input)

list.filter(list.unique(dict.values(grid)), is_not_empty)
|> list.map(harmonic_collinears_for_antenna(_, grid))
|> list.flatten
|> list.unique
|> list.length
}
2 changes: 1 addition & 1 deletion test/resonant_collinearity_test.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ pub fn solve_a_test() {
}

pub fn solve_b_test() {
should.equal(day08.solve_b(test_data()), 0)
should.equal(day08.solve_b(test_data()), 34)
}

0 comments on commit 40e238d

Please sign in to comment.