Skip to content

Commit

Permalink
day 08: part A
Browse files Browse the repository at this point in the history
  • Loading branch information
sreedevk committed Dec 8, 2024
1 parent e7d1ed1 commit f1dc4f0
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/advent_of_code.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import historian_hysteria as day01
import mull_it_over as day03
import print_queue as day05
import red_nosed_reports as day02
import resonant_collinearity as day08
import simplifile.{read}

pub fn main() {
Expand Down Expand Up @@ -110,6 +111,20 @@ pub fn main() {
Nil,
)
}

["8"] -> {
result.unwrap(
result.map(read("data/day8.txt"), fn(data) {
io.println(
"[8] Bridge Repair (Part 1): " <> int.to_string(day08.solve_a(data)),
)
io.println(
"[8] Bridge Repair (Part 2): " <> int.to_string(day08.solve_b(data)),
)
}),
Nil,
)
}
_ -> io.println_error("invalid arguments!")
}
}
110 changes: 110 additions & 0 deletions src/resonant_collinearity.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import gleam/dict.{type Dict}
import gleam/float
import gleam/int
import gleam/io
import gleam/list
import gleam/result
import gleam/string

type Point =
#(Int, Int)

type Grid =
Dict(Point, String)

fn parse_column(line, y) {
use grid, char, x <- list.index_fold(line, dict.new())
dict.insert(grid, #(x, y), char)
}

fn square(input: Float) -> Float {
case float.power(input, 2.0) {
Ok(val) -> val
_ -> 0.0
}
}

fn find_collinears(point_a: Point, point_b: Point) -> List(Point) {
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)

let assert Ok(distance) =
float.add(
square(float.subtract(x2f, x1f)),
square(float.subtract(y2f, y1f)),
)
|> float.square_root

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))

let x3_forward = float.round(x3f_forward)
let y3_forward = float.round(y3f_forward)

let x3_reverse = float.round(x3f_reverse)
let y3_reverse = float.round(y3f_reverse)

[#(x3_forward, y3_forward), #(x3_reverse, y3_reverse)]
}

fn is_not_empty(cell: String) -> Bool {
case cell {
"." -> False
_ -> True
}
}

fn find_antenna_locations(antenna: String, grid: Grid) -> List(Point) {
dict.keys(dict.filter(grid, fn(_, ant) { ant == antenna }))
}

fn point_within_map(point: Point, g: Grid) -> Bool {
result.is_ok(list.find(dict.keys(g), fn(x) { x == point }))
}

fn 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_collinears(l1, l2)
_ -> []
}
})
|> list.filter(point_within_map(_, g))
|> list.unique
}

fn parse_input(input: String) -> Grid {
input
|> string.trim()
|> string.split("\n")
|> list.map(string.to_graphemes)
|> list.index_map(parse_column)
|> list.reduce(dict.merge)
|> result.unwrap(dict.new())
}

pub fn solve_a(input: String) -> Int {
let grid = parse_input(input)

list.filter(list.unique(dict.values(grid)), is_not_empty)
|> list.map(collinears_for_antenna(_, grid))
|> list.flatten
|> list.unique
|> list.length
}

pub fn solve_b(_inp: String) -> Int {
0
}
22 changes: 22 additions & 0 deletions test/resonant_collinearity_test.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import gleam/string
import gleeunit/should
import resonant_collinearity as day08

fn test_data() -> String {
string.join(
[
"............", "........0...", ".....0......", ".......0....",
"....0.......", "......A.....", "............", "............",
"........A...", ".........A..", "............", "............",
],
"\n",
)
}

pub fn solve_a_test() {
should.equal(day08.solve_a(test_data()), 14)
}

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

0 comments on commit f1dc4f0

Please sign in to comment.