diff --git a/src/aoc2024/Day04.kt b/src/aoc2024/Day04.kt new file mode 100644 index 0000000..6203e40 --- /dev/null +++ b/src/aoc2024/Day04.kt @@ -0,0 +1,113 @@ +package aoc2024 + +import CharGrid +import RelPos +import println +import readInput + +/* +--- Day 4: Ceres Search --- +"Looks like the Chief's not here. Next!" One of The Historians pulls out a device and pushes the only button on it. After a brief flash, you recognize the interior of the Ceres monitoring station! +As the search for the Chief continues, a small Elf who lives on the station tugs on your shirt; she'd like to know if you could help her with her word search (your puzzle input). She only has to find one word: XMAS. +This word search allows words to be horizontal, vertical, diagonal, written backwards, or even overlapping other words. It's a little unusual, though, as you don't merely need to find one instance of XMAS - you need to find all of them. Here are a few ways XMAS might appear, where irrelevant characters have been replaced with .: +..X... +.SAMX. +.A..A. +XMAS.S +.X.... + +The actual word search will be full of letters instead. For example: +MMMSXXMASM +MSAMXMSMSA +AMXSXMAAMM +MSAMASMSMX +XMASAMXAMM +XXAMMXXAMA +SMSMSASXSS +SAXAMASAAA +MAMMMXMMMM +MXMXAXMASX + +In this word search, XMAS occurs a total of 18 times; here's the same word search again, but where letters not involved in any XMAS have been replaced with .: +....XXMAS. +.SAMXMS... +...S..A... +..A.A.MS.X +XMASAMX.MM +X.....XA.A +S.S.S.S.SS +.A.A.A.A.A +..M.M.M.MM +.X.X.XMASX + +Take a look at the little Elf's word search. How many times does XMAS appear? + +*/ +fun main() { + + val inlineTestInput = """ +MMMSXXMASM +MSAMXMSMSA +AMXSXMAAMM +MSAMASMSMX +XMASAMXAMM +XXAMMXXAMA +SMSMSASXSS +SAXAMASAAA +MAMMMXMMMM +MXMXAXMASX +""" + + fun part1(input: List): Int { + val grid = CharGrid(input) + val relposes = listOf( + listOf(RelPos(0, 0), RelPos(1, 0), RelPos(2, 0), RelPos(3, 0)), + listOf(RelPos(0, 0), RelPos(-1, 0), RelPos(-2, 0), RelPos(-3, 0)), + listOf(RelPos(0, 0), RelPos(1, 1), RelPos(2, 2), RelPos(3, 3)), + listOf(RelPos(0, 0), RelPos(-1, -1), RelPos(-2, -2), RelPos(-3, -3)), + listOf(RelPos(0, 0), RelPos(-1, 1), RelPos(-2, 2), RelPos(-3, 3)), + listOf(RelPos(0, 0), RelPos(1, -1), RelPos(2, -2), RelPos(3, -3)), + listOf(RelPos(0, 0), RelPos(0, 1), RelPos(0, 2), RelPos(0, 3)), + listOf(RelPos(0, 0), RelPos(0, -1), RelPos(0, -2), RelPos(0, -3)), + ) + var sum = 0 + for (x in 0 until grid.width) { + for (y in 0 until grid.height) { + for (rp in relposes) { + val st = grid.collectRelative(x, y, rp).joinToString("") + if (st == "XMAS") sum++ + } + } + } + return sum + } + + fun part2(input: List): Int { + val grid = CharGrid(input) + val rp1 = listOf(RelPos(-1, -1), RelPos(0, 0), RelPos(1, 1)) + val rp2 = listOf(RelPos(-1, 1), RelPos(0, 0), RelPos(1, -1)) + var sum = 0 + for (x in 0 until grid.width) { + for (y in 0 until grid.height) { + val st1 = grid.collectRelative(x, y, rp1).joinToString("") + val st2 = grid.collectRelative(x, y, rp2).joinToString("") + if ((st1 == "MAS" || st1 == "SAM") && (st2 == "MAS" || st2 == "SAM")) sum++ + } + } + return sum + } + + // test if implementation meets criteria from the description, like: + val testInput = inlineTestInput.trim().reader().readLines() + //val testInput = readInput("aoc2024/Day04_test") + val testInputPart1Result = part1(testInput) + println("Part 1 Test: $testInputPart1Result") + val testInputPart2Result = part2(testInput) + println("Part 2 Test: $testInputPart2Result") + check(testInputPart1Result == 18) + check(testInputPart2Result == 9) + + val input = readInput("aoc2024/Day04") + part1(input).println() + part2(input).println() +}