feat: completed day 5 for advent of code 2025
Some checks failed
gofmt / format (push) Has been cancelled

This commit is contained in:
Ceferino Patino 2025-12-04 23:46:24 -06:00
commit ed7885cb22
Signed by: c4patino
SSH key fingerprint: SHA256:Wu+cU1t+7zVT9wzew/4meNmeulo66NzMqc22MdDBgXI
4 changed files with 179 additions and 0 deletions

View file

@ -13,6 +13,7 @@ import (
"cpatino.com/advent-of-code/2025/day02"
"cpatino.com/advent-of-code/2025/day03"
"cpatino.com/advent-of-code/2025/day04"
"cpatino.com/advent-of-code/2025/day05"
)
var days = map[int]func(string) (any, any){
@ -20,6 +21,7 @@ var days = map[int]func(string) (any, any){
2: day02.Run,
3: day03.Run,
4: day04.Run,
5: day05.Run,
}
var rootCmd = &cobra.Command{

132
2025/day05/day05.go Executable file
View file

@ -0,0 +1,132 @@
package day05
import (
"bufio"
"os"
"strconv"
"strings"
)
func Part1(ranges [][2]int, ids []int) int {
freshCount := 0
for _, id := range ids {
for _, r := range ranges {
if id >= r[0] && id <= r[1] {
freshCount++
break
}
}
}
return freshCount
}
func Part2(ranges [][2]int) int {
if len(ranges) == 0 {
return 0
}
sorted := make([][2]int, len(ranges))
copy(sorted, ranges)
for i := 0; i < len(sorted)-1; i++ {
for j := i + 1; j < len(sorted); j++ {
if sorted[j][0] < sorted[i][0] {
sorted[i], sorted[j] = sorted[j], sorted[i]
}
}
}
merged := make([][2]int, 0)
current := sorted[0]
for i := 1; i < len(sorted); i++ {
next := sorted[i]
if next[0] <= current[1]+1 {
if next[1] > current[1] {
current[1] = next[1]
}
} else {
merged = append(merged, current)
current = next
}
}
merged = append(merged, current)
total := 0
for _, r := range merged {
total += r[1] - r[0] + 1
}
return total
}
func Run(filename string) (any, any) {
file, err := os.Open(filename)
if err != nil {
panic(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
lines := make([]string, 0)
for scanner.Scan() {
lines = append(lines, scanner.Text())
}
if err := scanner.Err(); err != nil {
panic(err)
}
sep := 0
for i, line := range lines {
if line == "" {
sep = i
break
}
}
rangeLines := lines[:sep]
idLines := lines[sep+1:]
ranges := parseRanges(rangeLines)
ids := parseIDs(idLines)
part1 := Part1(ranges, ids)
part2 := Part2(ranges)
return part1, part2
}
func parseRanges(lines []string) [][2]int {
ranges := make([][2]int, 0)
for _, line := range lines {
if line == "" {
continue
}
parts := strings.Split(line, "-")
if len(parts) != 2 {
continue
}
start, err1 := strconv.Atoi(parts[0])
end, err2 := strconv.Atoi(parts[1])
if err1 == nil && err2 == nil {
ranges = append(ranges, [2]int{start, end})
}
}
return ranges
}
func parseIDs(lines []string) []int {
ids := make([]int, 0)
for _, line := range lines {
if line == "" {
continue
}
id, err := strconv.Atoi(line)
if err == nil {
ids = append(ids, id)
}
}
return ids
}

34
2025/day05/day05_test.go Executable file
View file

@ -0,0 +1,34 @@
package day05
import (
"os"
"testing"
)
type TestCase struct {
FileName string
Part1 any
Part2 any
}
func TestDay05(t *testing.T) {
tests := []TestCase{
{"test.txt", 3, 14},
{"input.txt", 798, 366181852921027},
}
for _, test := range tests {
if _, err := os.Stat(test.FileName); os.IsNotExist(err) {
t.Fatalf("test file does not exist: %v", test.FileName)
}
part1, part2 := Run(test.FileName)
if test.Part1 != nil && part1 != test.Part1 {
t.Fatalf("%s: unexpected part1:\nwant:\t%v\ngot:\t%v", test.FileName, test.Part1, part1)
}
if test.Part2 != nil && part2 != test.Part2 {
t.Fatalf("%s: unexpected part2:\nwant:\t%v\ngot:\t%v", test.FileName, test.Part2, part2)
}
}
}

11
2025/day05/test.txt Executable file
View file

@ -0,0 +1,11 @@
3-5
10-14
16-20
12-18
1
5
8
11
17
32