84 lines
1.3 KiB
Go
84 lines
1.3 KiB
Go
package day02
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"aoc2024/internal/common"
|
|
)
|
|
|
|
type Difference int
|
|
|
|
const (
|
|
None Difference = iota
|
|
Positive
|
|
Negative
|
|
)
|
|
|
|
func (d Difference) IsTransitionOk(diff Difference) bool {
|
|
if d == None && diff != None {
|
|
return true
|
|
}
|
|
if d == diff && d != None {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func Handle(input []string) (int, int) {
|
|
safe := 0
|
|
dampened := 0
|
|
for _, line := range input {
|
|
levels := strings.Split(line, " ")
|
|
|
|
if isSafe(levels) {
|
|
safe++
|
|
dampened++
|
|
} else if isSafeWithDeletion(levels) {
|
|
dampened++
|
|
}
|
|
}
|
|
return safe, dampened
|
|
}
|
|
|
|
func getTrend(diff int) Difference {
|
|
if diff >= 1 && diff <= 3 {
|
|
return Positive
|
|
}
|
|
if diff <= -1 && diff >= -3 {
|
|
return Negative
|
|
}
|
|
return None
|
|
}
|
|
|
|
func isSafe(row []string) bool {
|
|
trend := None
|
|
for i := 0; i < len(row)-1; i++ {
|
|
diff := common.StrToInt(row[i]) - common.StrToInt(row[i+1])
|
|
newTrend := getTrend(diff)
|
|
|
|
if !trend.IsTransitionOk(newTrend) {
|
|
return false
|
|
|
|
}
|
|
trend = newTrend
|
|
}
|
|
return true
|
|
}
|
|
|
|
func isSafeWithDeletion(row []string) bool {
|
|
safe := false
|
|
for i := range row {
|
|
copyRow := make([]string, len(row))
|
|
copy(copyRow, row)
|
|
if i == len(row)-1 {
|
|
safe = isSafe(copyRow[:i])
|
|
} else {
|
|
safe = isSafe(append(copyRow[:i], copyRow[i+1:]...))
|
|
}
|
|
if safe {
|
|
return safe
|
|
}
|
|
}
|
|
return false
|
|
}
|