89 lines
1.3 KiB
Go
89 lines
1.3 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
_ "embed"
|
|
"fmt"
|
|
"strings"
|
|
|
|
aoc "go.sour.is/advent-of-code"
|
|
)
|
|
|
|
// var log = aoc.Log
|
|
|
|
func main() { aoc.MustResult(aoc.Runner(run)) }
|
|
|
|
type result struct {
|
|
valuePT1 int
|
|
valuePT2 int
|
|
}
|
|
|
|
func (r result) String() string { return fmt.Sprintf("%#v", r) }
|
|
|
|
func run(scan *bufio.Scanner) (*result, error) {
|
|
|
|
sum := 0
|
|
sum2 := 0
|
|
|
|
for scan.Scan() {
|
|
txt := scan.Text()
|
|
row := aoc.ReadStringToInts(strings.Fields(txt))
|
|
|
|
good, bad := testSafety(row)
|
|
if good {
|
|
sum++
|
|
sum2++
|
|
continue
|
|
}
|
|
|
|
for i := max(0, bad-1); i < min(bad+2, len(row)); i++ {
|
|
arr := cut(i, row)
|
|
|
|
good, _ := testSafety(arr)
|
|
if good {
|
|
sum2++
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
return &result{valuePT1: sum, valuePT2: sum2}, nil
|
|
}
|
|
|
|
func testSafety(row []int) (bool, int) {
|
|
good := true
|
|
bad := -1
|
|
increasing := false
|
|
decreasing := false
|
|
|
|
for i, v := range row[1:] {
|
|
if v > row[i] {
|
|
increasing = true
|
|
}
|
|
if v < row[i] {
|
|
decreasing = true
|
|
}
|
|
|
|
if difference := aoc.ABS(v - row[i]); difference < 1 || difference > 3 {
|
|
good = false
|
|
bad = i
|
|
break
|
|
}
|
|
|
|
if increasing && decreasing {
|
|
good = false
|
|
bad = i
|
|
break
|
|
}
|
|
}
|
|
|
|
return good, bad
|
|
}
|
|
|
|
func cut(i int, values []int) []int {
|
|
arr := make([]int, 0, len(values))
|
|
arr = append(arr, values[:i]...)
|
|
arr = append(arr, values[i+1:]...)
|
|
return arr
|
|
}
|