aoc_2024/day04.kts

83 lines
2.5 KiB
Plaintext
Raw Normal View History

2024-12-04 07:31:12 +00:00
#!/usr/bin/env kotlin
import java.io.File
import java.util.Scanner
val scanner = Scanner(File("day04input.txt"))
val xMasSearchWord = listOf("M", "A", "S") // Skip X because that triggers the search at 0,0 offset.
val xMasSearchOffsets = listOf(
listOf(Pair(0, 1), Pair(0, 2), Pair(0, 3)),
listOf(Pair(1, 0), Pair(2, 0), Pair(3, 0)),
listOf(Pair(0, -1), Pair(0, -2), Pair(0, -3)),
listOf(Pair(-1, 0), Pair(-2, 0), Pair(-3, 0)),
listOf(Pair(1, 1), Pair(2, 2), Pair(3, 3)),
listOf(Pair(-1, 1), Pair(-2, 2), Pair(-3, 3)),
listOf(Pair(-1, -1), Pair(-2, -2), Pair(-3, -3)),
listOf(Pair(1, -1), Pair(2, -2), Pair(3, -3))
)
var ycoordinates = mutableListOf<List<String>>()
while (scanner.hasNextLine()) {
val line = scanner.nextLine()
val xcoordinates = line.split("").filter { it.isNotEmpty() }
ycoordinates.add(xcoordinates)
}
var xMasCount = 0
var masXCount = 0
for (y in ycoordinates.indices) {
for (x in ycoordinates[y].indices) {
if (ycoordinates[y][x] == "X") {
xMasCount += findXmas(y, x)
}
if (ycoordinates[y][x] == "A") {
masXCount += findMasX(y, x)
}
}
}
fun findXmas(y: Int, x: Int): Int {
var xmasfound = 0
for (searchOffset in xMasSearchOffsets) {
val last = searchOffset.last()
if ((y+last.first) !in ycoordinates.indices || (x+last.second) !in ycoordinates[y].indices){
continue
}
var match = true
for (i in searchOffset.indices) {
val (dy, dx) = searchOffset[i]
val search = xMasSearchWord[i]
if (ycoordinates[y+dy][x+dx] != search) {
match = false
break
}
}
if (match) {
xmasfound += 1
}
}
return xmasfound
}
println("Xmas count: $xMasCount")
println("Mas X count: $masXCount")
fun findMasX(y: Int, x: Int): Int {
if (y == 0 || x == 0 || y == ycoordinates.lastIndex || x == ycoordinates[y].lastIndex) {
return 0
}
val validChars = mutableListOf("M", "S")
if (ycoordinates[y - 1][x - 1] !in validChars) {
return 0
}
val remainsOne = validChars[if(validChars.indexOf(ycoordinates[y - 1][x - 1]) == 0) 1 else 0]
if (ycoordinates[y + 1][x + 1] != remainsOne) {
return 0
}
if (ycoordinates[y - 1][x + 1] !in validChars) {
return 0
}
val remainsTwo = validChars[if(validChars.indexOf(ycoordinates[y - 1][x + 1]) == 0) 1 else 0]
if (ycoordinates[y + 1][x - 1] != remainsTwo) {
return 0
}
return 1
}