102 lines
1.6 KiB
Go
102 lines
1.6 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"aoc2024/helper"
|
||
|
"fmt"
|
||
|
"sort"
|
||
|
)
|
||
|
|
||
|
var reports [][]int
|
||
|
|
||
|
func main() {
|
||
|
reports = helper.ReadLinesToIntArrays()
|
||
|
|
||
|
// part 1
|
||
|
save_count := 0
|
||
|
for _, r := range reports {
|
||
|
if isReportSave(r) {
|
||
|
save_count++
|
||
|
}
|
||
|
}
|
||
|
fmt.Printf("Save reports: %d\n", save_count)
|
||
|
|
||
|
// part 2
|
||
|
save_count = 0
|
||
|
for _, r := range reports {
|
||
|
if isReportSaveWithDamper(r) {
|
||
|
save_count++
|
||
|
}
|
||
|
}
|
||
|
fmt.Printf("Save reports (with damper): %d\n", save_count)
|
||
|
}
|
||
|
|
||
|
func isReportSaveWithDamper(report []int) bool {
|
||
|
|
||
|
if isReportSave(report) {
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
for i := range report {
|
||
|
// remove one item from report and try to validate
|
||
|
new_report := removeFromSlice(report, i)
|
||
|
if isReportSave(new_report) {
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
func removeFromSlice(slice []int, dropIndex int) []int {
|
||
|
var newslice []int
|
||
|
for i, v := range slice {
|
||
|
if i != dropIndex {
|
||
|
newslice = append(newslice, v)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return newslice
|
||
|
}
|
||
|
|
||
|
func isReportSave(report []int) bool {
|
||
|
|
||
|
if !isReportSorted(report) {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
for i := range report {
|
||
|
if (i + 1) < len(report) {
|
||
|
if !isPairSave(report[i], report[i+1]) {
|
||
|
return false
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
func isReportSorted(slice []int) bool {
|
||
|
ascSorted := sort.SliceIsSorted(
|
||
|
slice,
|
||
|
func(i, j int) bool { return slice[i] < slice[j] },
|
||
|
)
|
||
|
descSorted := sort.SliceIsSorted(
|
||
|
slice,
|
||
|
func(i, j int) bool { return slice[i] > slice[j] },
|
||
|
)
|
||
|
|
||
|
return ascSorted || descSorted
|
||
|
|
||
|
}
|
||
|
|
||
|
func isPairSave(x int, y int) bool {
|
||
|
if x == y {
|
||
|
return false
|
||
|
}
|
||
|
diff := helper.Abs(x - y)
|
||
|
if diff > 3 {
|
||
|
return false
|
||
|
}
|
||
|
return true
|
||
|
}
|