package main

import (
	"fmt"
	"strconv"
	"strings"

	helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
)

func main() {
	inp := helpers.StdinToStringSlice()
	part1(inp)
	part2(inp)
}

func part1(inp []string) {
	var ret int
	for _, report := range inp {
		wrk := cleanReport(report)
		if testReport(wrk) {
			ret++
		}
	}
	fmt.Println("# Part 1")
	fmt.Printf("%d reports are safe\n", ret)
}

func part2(inp []string) {
	var ret int
	for _, report := range inp {
		wrk := cleanReport(report)
		if testReport(wrk) {
			ret++
		} else {
			if testDampenedReport(wrk) {
				ret++
			}
		}
	}
	fmt.Println("# Part 2")
	fmt.Printf("%d reports are safe\n", ret)
}

func cleanReport(inp string) []int {
	var ret []int
	wrk := strings.Split(inp, " ")
	for i := range wrk {
		w, err := strconv.Atoi(wrk[i])
		if err != nil {
			panic(err)
		}
		ret = append(ret, w)
	}
	return ret
}

func testReport(report []int) bool {
	var prev int
	var dir int
	for idx, val := range report {
		switch idx {
		case 0:
			prev = val
		case 1:
			if val < prev {
				dir = -1
			} else {
				dir = 1
			}
			fallthrough
		default:
			if (val < prev && dir == 1) || (val > prev && dir == -1) {
				return false
			}
			if dir == 1 {
				if (val-prev < 1) || (val-prev > 3) {
					return false
				}
			} else {
				if (prev-val < 1) || (prev-val > 3) {
					return false
				}
			}
			prev = val
		}
	}
	return true
}

func testDampenedReport(report []int) bool {
	for i := range report {
		wrk := removeIdx(report, i)
		if testReport(wrk) {
			return true
		}
	}
	return false
}

func removeIdx(a []int, idx int) []int {
	var ret []int
	for i := range a {
		if i == idx {
			continue
		}
		ret = append(ret, a[i])
	}
	return ret
}