master
Raw Download raw file
  1package main
  2
  3import (
  4	"advent/internal/aoc"
  5	"log"
  6	"strconv"
  7	"strings"
  8)
  9
 10type direction int
 11
 12const (
 13	unknown    direction = iota
 14	increasing direction = iota
 15	decreasing direction = iota
 16	volitile   direction = iota
 17)
 18
 19type report struct {
 20	levels     []int
 21	direction  direction
 22	safe       bool
 23	violations int
 24}
 25
 26func parse(line string) report {
 27	sl := strings.Split(line, " ")
 28
 29	r := report{
 30		levels:     make([]int, len(sl), len(sl)),
 31		direction:  unknown,
 32		safe:       true,
 33		violations: 0,
 34	}
 35
 36	previousLevel := -1
 37	for i, s := range sl {
 38
 39		level, err := strconv.Atoi(s)
 40		if err != nil {
 41			log.Fatalf("failed to parse level=%q: %s\n", s, err)
 42		}
 43		r.levels[i] = level
 44
 45		if previousLevel == -1 {
 46			previousLevel = level
 47			continue
 48		}
 49
 50		direction := unknown
 51		if level > previousLevel {
 52			direction = increasing
 53		}
 54		if level < previousLevel {
 55			direction = decreasing
 56		}
 57		if r.direction == unknown {
 58			r.direction = direction
 59		}
 60		if (r.direction == increasing && direction == decreasing) ||
 61			(r.direction == decreasing && direction == increasing) {
 62			r.direction = volitile
 63			r.safe = false
 64			r.violations += 1
 65		}
 66
 67		diff := level - previousLevel
 68		if diff < 0 {
 69			diff = -diff
 70		}
 71		if diff < 1 || diff > 3 {
 72			r.safe = false
 73			r.violations += 1
 74		}
 75
 76		previousLevel = level
 77	}
 78	//fmt.Printf("%+v\n", r)
 79	return r
 80}
 81
 82func solvePart1(input []string) (solution int) {
 83	safeReportSum := 0
 84	for _, l := range input {
 85		r := parse(l)
 86		if r.safe {
 87			safeReportSum += 1
 88		}
 89	}
 90	return safeReportSum
 91}
 92
 93func solvePart2(input []string) (solution int) {
 94	safeReportSum := 0
 95	for _, l := range input {
 96		r := parse(l)
 97		if r.safe || r.violations == 1 {
 98			safeReportSum += 1
 99		}
100	}
101	return safeReportSum
102}
103
104func main() {
105	day := aoc.Day2
106	aoc.SolveExample(day, aoc.Part1, solvePart1, 2)
107	aoc.SolvePuzzle(day, aoc.Part1, solvePart1, 564)
108	aoc.SolveExample(day, aoc.Part2, solvePart2, 4)
109	aoc.SolvePuzzle(day, aoc.Part2, solvePart2, aoc.UnknownExpected)
110}