Skip to content

Commit 8f58e71

Browse files
committed
finished day 5
1 parent a49f0dc commit 8f58e71

File tree

4 files changed

+130
-2
lines changed

4 files changed

+130
-2
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Advent of Code 2025
22

33
[![Tests](https://github.com/devries/advent_of_code_2025/actions/workflows/test.yml/badge.svg)](https://github.com/devries/advent_of_code_2025/actions/workflows/test.yml)
4-
[![Stars: 8](https://img.shields.io/badge/⭐_Stars-8-yellow)](https://adventofcode.com/2025)
4+
[![Stars: 10](https://img.shields.io/badge/⭐_Stars-10-yellow)](https://adventofcode.com/2025)
55

66
This year will be my second year doing Advent of Code in [Gleam](https://gleam.run).
77
Last year I was still learning the language, and in the past year I have used it
@@ -39,3 +39,4 @@ information.
3939
- [Day 2](https://adventofcode.com/2025/day/2): [⭐ ⭐ solution](src/day02/solution.gleam)
4040
- [Day 3](https://adventofcode.com/2025/day/3): [⭐ ⭐ solution](src/day03/solution.gleam)
4141
- [Day 4](https://adventofcode.com/2025/day/4): [⭐ ⭐ solution](src/day04/solution.gleam)
42+
- [Day 5](https://adventofcode.com/2025/day/5): [⭐ ⭐ solution](src/day05/solution.gleam)

inputs

src/day05/solution.gleam

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import gleam/int
2+
import gleam/io
3+
import gleam/list
4+
import gleam/result
5+
import gleam/string
6+
import internal/aoc_utils
7+
8+
pub fn main() {
9+
let filename = "inputs/day05.txt"
10+
11+
let lines_result = aoc_utils.read_lines(from: filename)
12+
case lines_result {
13+
Ok(lines) -> {
14+
// If the file was converting into a list of lines
15+
// successfully then run each part of the problem
16+
aoc_utils.run_part_and_print("Part 1", fn() { solve_p1(lines) })
17+
aoc_utils.run_part_and_print("Part 2", fn() { solve_p2(lines) })
18+
}
19+
Error(_) -> io.println("Error reading file")
20+
}
21+
}
22+
23+
// Part 1
24+
pub fn solve_p1(lines: List(String)) -> Result(String, String) {
25+
let #(ranges, values) = parse_input(lines)
26+
27+
values
28+
|> list.filter(fn(val) {
29+
list.fold_until(ranges, False, fn(_, range) {
30+
case val >= range.0 && val <= range.1 {
31+
True -> list.Stop(True)
32+
False -> list.Continue(False)
33+
}
34+
})
35+
})
36+
|> list.length
37+
|> int.to_string
38+
|> Ok
39+
}
40+
41+
// Part 2
42+
pub fn solve_p2(lines: List(String)) -> Result(String, String) {
43+
let #(ranges, _) = parse_input(lines)
44+
45+
merge_overlaps(ranges)
46+
|> list.map(fn(range) { range.1 - range.0 + 1 })
47+
|> int.sum
48+
|> int.to_string
49+
|> Ok
50+
}
51+
52+
fn parse_range(line: String) -> Result(#(Int, Int), Nil) {
53+
use string_vals <- result.try(string.split_once(line, "-"))
54+
55+
use first <- result.try(int.parse(string_vals.0))
56+
use second <- result.try(int.parse(string_vals.1))
57+
58+
Ok(#(first, second))
59+
}
60+
61+
fn parse_input(lines: List(String)) -> #(List(#(Int, Int)), List(Int)) {
62+
let #(range_part, rest) = list.split_while(lines, fn(l) { l != "" })
63+
64+
let value_part = list.drop(rest, 1)
65+
66+
let assert Ok(ranges) =
67+
range_part
68+
|> list.map(parse_range)
69+
|> result.all
70+
71+
let assert Ok(values) = value_part |> list.map(int.parse) |> result.all
72+
73+
#(ranges, values)
74+
}
75+
76+
fn merge_overlaps(ranges: List(#(Int, Int))) -> List(#(Int, Int)) {
77+
ranges
78+
|> list.sort(fn(ra, rb) { int.compare(ra.0, rb.0) })
79+
|> merge_sorted_overlaps([])
80+
}
81+
82+
fn merge_sorted_overlaps(
83+
remain: List(#(Int, Int)),
84+
complete: List(#(Int, Int)),
85+
) -> List(#(Int, Int)) {
86+
case remain {
87+
[] -> complete
88+
[range] -> [range, ..complete]
89+
[current, next, ..rest] -> {
90+
let #(current_start, current_end) = current
91+
let #(next_start, next_end) = next
92+
93+
case next_start <= current_end, next_end <= current_end {
94+
True, True -> merge_sorted_overlaps([current, ..rest], complete)
95+
True, False ->
96+
merge_sorted_overlaps([#(current_start, next_end), ..rest], complete)
97+
False, True -> panic as "ranges are not in order"
98+
False, False ->
99+
merge_sorted_overlaps([next, ..rest], [current, ..complete])
100+
}
101+
}
102+
}
103+
}

test/day05_test.gleam

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import day05/solution
2+
import gleam/string
3+
4+
const testinput = "3-5
5+
10-14
6+
16-20
7+
12-18
8+
9+
1
10+
5
11+
8
12+
11
13+
17
14+
32"
15+
16+
pub fn part1_test() {
17+
let lines = string.split(testinput, "\n")
18+
assert solution.solve_p1(lines) == Ok("3")
19+
}
20+
21+
pub fn part2_test() {
22+
let lines = string.split(testinput, "\n")
23+
assert solution.solve_p2(lines) == Ok("14")
24+
}

0 commit comments

Comments
 (0)