From abb0225d064653bd8ff228d71667c3e1bce2cbae Mon Sep 17 00:00:00 2001 From: chrisly42 Date: Tue, 10 Dec 2024 06:26:53 +0100 Subject: [PATCH] Day 10. --- src/Utils.kt | 7 +++++ src/aoc2024/Day10.kt | 64 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 src/aoc2024/Day10.kt diff --git a/src/Utils.kt b/src/Utils.kt index d95f024..f4ca8a2 100644 --- a/src/Utils.kt +++ b/src/Utils.kt @@ -196,10 +196,17 @@ class CharGrid { fun matchRelative(c: Int, r: Int, relposes: Iterable, predicate: (char: Char) -> Boolean): List = relposes.filter { predicate(get(c + it.dc, r + it.dr)) } + fun marchMatching(pos: RelPos, relposes: Iterable, predicate: (char: Char) -> Boolean): List = + relposes.map { pos.translate(it) }.filter { predicate(get(it)) } + fun findMatches(predicate: (char: Char) -> Boolean): List> { return generateGridPos().filter { predicate(get(it)) }.map { it.dc to it.dr }.toList() } + fun findMatchesRelPos(predicate: (char: Char) -> Boolean): List { + return generateGridPos().filter { predicate(get(it)) }.toList() + } + fun collectMatches(predicate: (char: Char) -> Boolean): List> { return generateGridPos().filter { predicate(get(it)) }.map { get(it) to it }.toList() } diff --git a/src/aoc2024/Day10.kt b/src/aoc2024/Day10.kt new file mode 100644 index 0000000..c6e3be5 --- /dev/null +++ b/src/aoc2024/Day10.kt @@ -0,0 +1,64 @@ +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): 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): 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() +}