Skip to content

Commit e82fac2

Browse files
committed
Day 8 part 1
1 parent b1da31e commit e82fac2

File tree

3 files changed

+109
-1
lines changed

3 files changed

+109
-1
lines changed

src/adventofcode2024.gleam

+3-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import day4
1414
import day5
1515
import day6
1616
import day7
17+
import day8
1718

1819
pub fn main() {
1920
case argv.load().arguments {
@@ -22,7 +23,7 @@ pub fn main() {
2223
Ok(d) -> run(d)
2324
Error(_) -> io.println("Invalid day: " <> arg)
2425
}
25-
_ -> list.range(1, 7) |> list.each(fn(d) { run(d) })
26+
_ -> list.range(1, 8) |> list.each(fn(d) { run(d) })
2627
}
2728
}
2829

@@ -37,6 +38,7 @@ fn run(d: Int) -> Nil {
3738
5 -> day5.part1(input) |> int.to_string
3839
6 -> day6.part1(input) |> int.to_string
3940
7 -> day7.part1(input) |> int.to_string
41+
8 -> day8.part1(input) |> int.to_string
4042
_ -> "(not implemented)"
4143
}
4244
})

src/day8.gleam

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import gleam/dict.{type Dict}
2+
import gleam/list
3+
import gleam/result
4+
import gleam/string
5+
import grid.{type Pos}
6+
import parse
7+
8+
pub fn part1(input: String) -> Int {
9+
let #(antennas, width, height) = parse_input(input)
10+
11+
antennas
12+
|> dict.keys
13+
|> list.flat_map(fn(label) { antinodes_for(antennas, label, width, height) })
14+
|> list.unique
15+
|> list.length
16+
}
17+
18+
fn antinodes_for(
19+
antennas: Dict(String, List(Pos)),
20+
label: String,
21+
width: Int,
22+
height: Int,
23+
) -> List(Pos) {
24+
antennas
25+
|> dict.get(label)
26+
|> result.unwrap([])
27+
|> list.combination_pairs
28+
|> list.flat_map(fn(pair) {
29+
[individual_antinode(pair.0, pair.1), individual_antinode(pair.1, pair.0)]
30+
})
31+
|> list.filter(fn(pos) {
32+
pos.0 >= 0 && pos.0 < width && pos.1 >= 0 && pos.1 < height
33+
})
34+
}
35+
36+
fn individual_antinode(a: Pos, b: Pos) -> Pos {
37+
let dx = a.0 - b.0
38+
let dy = a.1 - b.1
39+
#(a.0 + dx, a.1 + dy)
40+
}
41+
42+
fn parse_input(input: String) -> #(Dict(String, List(Pos)), Int, Int) {
43+
let lines = parse.lines(input)
44+
45+
let pos_to_char =
46+
lines
47+
|> list.index_map(fn(line, y) {
48+
line
49+
|> string.to_graphemes
50+
|> list.index_map(fn(char, x) { #(#(x, y), char) })
51+
|> list.filter(fn(poschar) { poschar.1 != "." })
52+
})
53+
|> list.flatten
54+
|> dict.from_list
55+
56+
let width = lines |> list.first |> result.unwrap("") |> string.length
57+
let height = lines |> list.length
58+
59+
#(
60+
pos_to_char
61+
|> dict.values
62+
|> list.unique
63+
|> list.map(fn(char) {
64+
#(
65+
char,
66+
pos_to_char
67+
|> dict.to_list
68+
|> list.filter_map(fn(poschar) {
69+
case poschar.1 == char {
70+
True -> Ok(poschar.0)
71+
False -> Error(Nil)
72+
}
73+
}),
74+
)
75+
})
76+
|> dict.from_list,
77+
width,
78+
height,
79+
)
80+
}

test/day8_test.gleam

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import gleeunit
2+
import gleeunit/should
3+
4+
import day8
5+
6+
pub fn main() {
7+
gleeunit.main()
8+
}
9+
10+
const example1 = "............
11+
........0...
12+
.....0......
13+
.......0....
14+
....0.......
15+
......A.....
16+
............
17+
............
18+
........A...
19+
.........A..
20+
............
21+
............
22+
"
23+
24+
pub fn part1_test() {
25+
day8.part1(example1) |> should.equal(14)
26+
}

0 commit comments

Comments
 (0)