1
0
Fork 0
adventofcode/2024/02/main.go

103 lines
1.7 KiB
Go
Raw Normal View History

2024-12-02 12:30:04 +00:00
package main
import (
"fmt"
"sort"
"aoc/helper"
2024-12-02 12:30:04 +00:00
)
type reports []report
type report struct {
levels []int
}
2024-12-02 12:30:04 +00:00
func main() {
// generate reports
var reports reports
for _, val := range helper.ReadLinesToIntSlices() {
reports = append(reports, report{levels: val})
}
2024-12-02 12:30:04 +00:00
// part 1
save_count := 0
for _, r := range reports {
if r.isSave() {
2024-12-02 12:30:04 +00:00
save_count++
}
}
fmt.Printf("Save reports: %d\n", save_count)
// part 2
save_count = 0
for _, r := range reports {
if r.isSaveWithDamper() {
2024-12-02 12:30:04 +00:00
save_count++
}
}
fmt.Printf("Save reports (with damper): %d\n", save_count)
}
func (r report) isSave() bool {
if !r.isSorted() {
2024-12-02 12:30:04 +00:00
return false
}
2024-12-05 15:15:54 +00:00
for i := range len(r.levels) - 1 { // iterate til second last level
if !isValidLevelDifference(r.levels[i], r.levels[i+1]) {
return false
2024-12-02 12:30:04 +00:00
}
}
return true
}
func (r report) isSorted() bool {
2024-12-02 12:30:04 +00:00
ascSorted := sort.SliceIsSorted(
r.levels,
func(i, j int) bool { return r.levels[i] < r.levels[j] },
2024-12-02 12:30:04 +00:00
)
descSorted := sort.SliceIsSorted(
r.levels,
func(i, j int) bool { return r.levels[i] > r.levels[j] },
2024-12-02 12:30:04 +00:00
)
return ascSorted || descSorted
}
func isValidLevelDifference(i int, j int) bool {
if i == j {
2024-12-02 12:30:04 +00:00
return false
}
if helper.Abs(i-j) > 3 {
2024-12-02 12:30:04 +00:00
return false
}
2024-12-02 12:30:04 +00:00
return true
}
func (r report) isSaveWithDamper() bool {
if r.isSave() {
return true
}
for i := range r.levels {
// remove one item from report and try to validate
if r.removeLevelByIndex(i).isSave() {
return true
}
}
return false
}
func (r report) removeLevelByIndex(dropIndex int) report {
var newlevels []int
// create new slice w/o passed index position
newlevels = append(newlevels, r.levels[:dropIndex]...)
newlevels = append(newlevels, r.levels[dropIndex+1:]...)
return report{levels: newlevels}
}