package aoc2024 import CharGrid import println import readInput /* --- Day 14: Restroom Redoubt --- https://adventofcode.com/2024/day/14 */ fun main() { val inlineTestInput = """ p=0,4 v=3,-3 p=6,3 v=-1,-3 p=10,3 v=-1,2 p=2,0 v=2,-1 p=0,0 v=1,3 p=3,0 v=-2,-2 p=7,6 v=-1,-3 p=3,0 v=-1,-2 p=9,3 v=2,3 p=7,3 v=-1,2 p=2,4 v=2,-3 p=9,5 v=-3,-3 """ fun part1(input: List, time: Int, w: Int, h: Int): Int { val robots = input.map { "p=(\\d+),(\\d+) v=(-?\\d+),(-?\\d+)".toRegex().find(it)!!.groupValues.drop(1).map { it.toInt() }.toIntArray() } for (r in robots) { r[0] = (r[0] + time * (r[2] + w)) % w r[1] = (r[1] + time * (r[3] + h)) % h } val q1 = robots.count { it[0] < w / 2 && it[1] < h / 2 } val q2 = robots.count { it[0] > w / 2 && it[1] < h / 2 } val q3 = robots.count { it[0] < w / 2 && it[1] > h / 2 } val q4 = robots.count { it[0] > w / 2 && it[1] > h / 2 } return q1 * q2 * q3 * q4 } fun part2(input: List, w: Int, h: Int): Int { val robots = input.map { "p=(\\d+),(\\d+) v=(-?\\d+),(-?\\d+)".toRegex().find(it)!!.groupValues.drop(1).map { it.toInt() }.toIntArray() } /* either: 1) x == w/2 -+ c, y == c c in [0..w/2] or : 2) x == w/2, y in (w/2..h) 1) px + t * (vx + w) % w = w/2 - c; py + t * (vy + h) % h = c px + t * (vx + w) % w = w/2 - (py + t * (vy + h) % h) (px - py) + t * (((vx + w) % w) - ((vy + h) % h)) = w/2 2) px == w/2, py > w/2 % h */ val z = Array(robots.size) { IntArray(4) } for (t in 1..w * h) { /*val good = robots.all { val x = ((it[0] + t * (it[2] + w)) % w).toInt() val y = ((it[1] + t * (it[3] + h)) % h).toInt() (y <= w / 2 && ((x >= w / 2 - y) && (x <= w / 2 + y))) || (x == w / 2 && y > w / 2) } if (!good) continue*/ for ((i, r) in robots.withIndex()) { z[i][0] = ((r[0] + t * (r[2] + w)) % w).toInt() z[i][1] = ((r[1] + t * (r[3] + h)) % h).toInt() } if (z.map { it[0] to it[1] }.distinct().count() < robots.size) continue println("Solution $t") val grid = CharGrid(w, h, '.') z.forEach { grid[it[0], it[1]] = '*' } grid.debug() println() return t } return 0 } // test if implementation meets criteria from the description, like: val testInput = inlineTestInput.trim().reader().readLines() //val testInput = readInput("aoc2024/Day14_test") val testInputPart1Result = part1(testInput, 100, 11, 7) println("Part 1 Test: $testInputPart1Result") //val testInputPart2Result = part2(testInput, 11, 7) //println("Part 2 Test: $testInputPart2Result") check(testInputPart1Result == 12) //check(testInputPart2Result == 0) val input = readInput("aoc2024/Day14") part1(input, 100, 101, 103).println() part2(input, 101, 103).println() }