package aoc2024

import CharGrid
import RelPos
import println
import readInput

/*
--- Day 10: Hoof It ---
https://adventofcode.com/2024/day/10
*/
fun main() {

    val inlineTestInput = """
89010123
78121874
87430965
96549874
45678903
32019012
01329801
10456732
"""

    fun part1(input: List<String>): Int {
        val grid = CharGrid(input)
        val starts = grid.findMatchesRelPos { it == '0' }
        var sum = 0
        for (startPos in starts) {
            var nodes = listOf(startPos)
            for (c in '1'..'9') {
                nodes = nodes.flatMap { grid.marchMatching(it, CharGrid.PLUS_POS) { char -> char == c } }.distinct()
                if (nodes.isEmpty()) break
            }
            sum += nodes.size
        }

        return sum
    }

    fun walkTrail(grid: CharGrid, c: Char, p: RelPos): Int {
        val newNodes = grid.marchMatching(p, CharGrid.PLUS_POS) { it == c }
        return if (c == '9') newNodes.size else newNodes.sumOf { walkTrail(grid, c + 1, it) }
    }

    fun part2(input: List<String>): Int {
        val grid = CharGrid(input)
        return grid.findMatchesRelPos { it == '0' }.sumOf { walkTrail(grid, '1', it) }
    }

    // test if implementation meets criteria from the description, like:
    val testInput = inlineTestInput.trim().reader().readLines()
    //val testInput = readInput("aoc2024/Day10_test")
    val testInputPart1Result = part1(testInput)
    println("Part 1 Test: $testInputPart1Result")
    val testInputPart2Result = part2(testInput)
    println("Part 2 Test: $testInputPart2Result")
    check(testInputPart1Result == 36)
    check(testInputPart2Result == 81)

    val input = readInput("aoc2024/Day10")
    part1(input).println()
    part2(input).println()
}
