🎄Advent of Code - Day 3 part 2

This commit is contained in:
Denis-Cosmin Nutiu 2023-12-03 18:58:12 +02:00
parent 7d5c2834c2
commit 7a06f3bf01

View file

@ -3,6 +3,7 @@ package AdventOfCode2023.day3
import AdventOfCode.Puzzle import AdventOfCode.Puzzle
data class EnginePart(var number: Int, var row: Int, var startIndex: Int, var endIndex: Int) data class EnginePart(var number: Int, var row: Int, var startIndex: Int, var endIndex: Int)
data class Gear(var row: Int, val column: Int, var engineParts: MutableSet<EnginePart>)
class GearRatios : Puzzle { class GearRatios : Puzzle {
@ -12,7 +13,7 @@ class GearRatios : Puzzle {
// Step 1: Scan for index parts. // Step 1: Scan for index parts.
data.forEachIndexed { rowIndex, row -> data.forEachIndexed { rowIndex, row ->
val numberDigits: MutableList<Char> = mutableListOf() val numberDigits: MutableList<Char> = mutableListOf()
var currentEnginePart = EnginePart(0, 0, 0,0) var currentEnginePart = EnginePart(0, 0, 0, 0)
var foundNumber = false var foundNumber = false
row.forEachIndexed { colIndex, col -> row.forEachIndexed { colIndex, col ->
// first digit // first digit
@ -23,23 +24,23 @@ class GearRatios : Puzzle {
numberDigits.add(col) numberDigits.add(col)
} }
// inside number // inside number
else if(col.isDigit() && foundNumber) { else if (col.isDigit() && foundNumber) {
currentEnginePart.endIndex = colIndex currentEnginePart.endIndex = colIndex
numberDigits.add(col) numberDigits.add(col)
} }
// exit number // exit number
else if(!col.isDigit() && foundNumber) { else if (!col.isDigit() && foundNumber) {
currentEnginePart.number = numberDigits.joinToString(separator = "").toInt() currentEnginePart.number = numberDigits.joinToString(separator = "").toInt()
currentEnginePart.endIndex = colIndex-1 currentEnginePart.endIndex = colIndex - 1
foundEngineParts.add(currentEnginePart) foundEngineParts.add(currentEnginePart)
// reset // reset
currentEnginePart = EnginePart(0, 0, 0,0) currentEnginePart = EnginePart(0, 0, 0, 0)
numberDigits.clear() numberDigits.clear()
foundNumber = false foundNumber = false
} }
// Number is at edge // Number is at edge
if (foundNumber && colIndex == row.length-1) { if (foundNumber && colIndex == row.length - 1) {
currentEnginePart.number = numberDigits.joinToString(separator = "").toInt() currentEnginePart.number = numberDigits.joinToString(separator = "").toInt()
currentEnginePart.endIndex = colIndex currentEnginePart.endIndex = colIndex
foundEngineParts.add(currentEnginePart) foundEngineParts.add(currentEnginePart)
@ -56,16 +57,16 @@ class GearRatios : Puzzle {
engineParts.forEach { enginePart -> engineParts.forEach { enginePart ->
for (i in enginePart.startIndex..enginePart.endIndex) { for (i in enginePart.startIndex..enginePart.endIndex) {
val movesOfXY = listOf( val movesOfXY = listOf(
Pair(i-1, enginePart.row), // left Pair(i - 1, enginePart.row), // left
Pair(i-1, enginePart.row-1), // let top Pair(i - 1, enginePart.row - 1), // let top
Pair(i, enginePart.row-1),// top Pair(i, enginePart.row - 1),// top
Pair(i+1, enginePart.row-1), // right top Pair(i + 1, enginePart.row - 1), // right top
Pair(i+1, enginePart.row), // right Pair(i + 1, enginePart.row), // right
Pair(i+1, enginePart.row+1), // right bottom Pair(i + 1, enginePart.row + 1), // right bottom
Pair(i, enginePart.row+1), // bottom Pair(i, enginePart.row + 1), // bottom
Pair(i-1, enginePart.row+1) // left bottom Pair(i - 1, enginePart.row + 1) // left bottom
) )
movesOfXY.forEach movesForeach@ { movesOfXY.forEach movesForeach@{
if ((it.second >= 0 && it.second < data.size) && (it.first >= 0 && it.first < data[it.second].length)) { if ((it.second >= 0 && it.second < data.size) && (it.first >= 0 && it.first < data[it.second].length)) {
val symbol = data[it.second][it.first] val symbol = data[it.second][it.first]
if (!symbol.isDigit() && symbol != '.') { if (!symbol.isDigit() && symbol != '.') {
@ -98,28 +99,28 @@ class GearRatios : Puzzle {
override fun partTwo() { override fun partTwo() {
val inputData = this.readInputFromFile("3") val inputData = this.readInputFromFile("3")
val foundEngineParts: List<EnginePart> = scanForEnginePats(inputData) val foundEngineParts: List<EnginePart> = scanForEnginePats(inputData)
var gears: MutableList<MutableSet<EnginePart>> = mutableListOf() val gears: MutableList<Gear> = mutableListOf()
inputData.forEachIndexed { row, rowElement -> inputData.forEachIndexed { row, rowElement ->
rowElement.forEachIndexed { col, colElement -> rowElement.forEachIndexed { col, colElement ->
if (colElement == '*') { if (colElement == '*') {
val enginePartsForGear: MutableSet<EnginePart> = mutableSetOf() val enginePartsForGear: MutableSet<EnginePart> = mutableSetOf()
val movesOfXY = listOf( val movesOfXY = listOf(
Pair(col-1, row), // left Pair(col - 1, row), // left
Pair(col-1, row-1), // let top Pair(col - 1, row - 1), // let top
Pair(col, row-1),// top Pair(col, row - 1),// top
Pair(col+1, row-1), // right top Pair(col + 1, row - 1), // right top
Pair(col+1, row), // right Pair(col + 1, row), // right
Pair(col+1, row+1), // right bottom Pair(col + 1, row + 1), // right bottom
Pair(col, row+1), // bottom Pair(col, row + 1), // bottom
Pair(col-1, row+1) // left bottom Pair(col - 1, row + 1) // left bottom
) )
movesOfXY.forEach movesForeach@ { movesOfXY.forEach {
if ((it.second >= 0 && it.second < inputData.size) && (it.first >= 0 && it.first < inputData[it.second].length)) { if ((it.second >= 0 && it.second < inputData.size) && (it.first >= 0 && it.first < inputData[it.second].length)) {
val symbol = inputData[it.second][it.first] val symbol = inputData[it.second][it.first]
if (symbol.isDigit()) { if (symbol.isDigit()) {
// search engine part // search engine part
foundEngineParts.forEach {part -> foundEngineParts.forEach { part ->
if (part.row == it.second && (it.first >= part.startIndex && it.first <= part.endIndex)) { if (part.row == it.second && (it.first >= part.startIndex && it.first <= part.endIndex)) {
enginePartsForGear.add(part) enginePartsForGear.add(part)
} }
@ -127,13 +128,13 @@ class GearRatios : Puzzle {
} }
} }
} }
gears.add(enginePartsForGear) gears.add(Gear(row, col, enginePartsForGear))
} }
} }
} }
gears.filter { it.size == 2 }.map { gears.filter { it.engineParts.size == 2 }.map {
it.map { it.number }.reduce { acc, i -> acc * i } it.engineParts.map { it.number }.reduce { acc, i -> acc * i }
}.sum().let { }.sum().let {
println("The gear ratio is $it") println("The gear ratio is $it")
} }