14 Dec 2023
Solución Advent of Code 2023 día 2
El problema puede encontrarse aquí: Advent of Code 2023 día 2.
Parte 1
En la primera parte se debe verificar cuales juegos son posibles y sumar los IDs, esto significa que similar al reto del día 1 hay que iterar a través de cada línea, por tanto obtenemos las entradas y declaramos los cubos máximos en una constante.
require "utils"
local maxCubeColors<const> = {
blue = 14,
green = 13,
red = 12
}
local function getInput()
local input = readFile("02input.txt")
return splitString(input, lineDelimiter)
end
Ahora la idea sería estructurar cada línea dividiendo en pequeños strings, primero dividir la línea por “:” esto daría dos elementos, la primera contendría el ID y la segunda el Juego. Luego al Juego lo podemos dividir por “;” lo que daría un array de Set o subconjunto, luego a cada Set lo podemos dividir por “,” y obtener otro array por cada cubo, por último dividir por “%s” (espacio) y obtener el color del cubo y el número.
Decidí hacer todo eso en la misma iteración mientras resuelvo el ejercicio.
local function answer1()
local lines = getInput()
local game = ""
local gameID = 0
local sets = {}
local cubes = {}
local cube = {}
local cubeNumber = 0
local cubeColor = ""
local isSetVerified = true
local result = 0
for _, line in ipairs(lines) do
game = splitString(line, colonDelimiter) -- Divide el string por ;
gameID = tonumber(string.sub(game[1], 5, -1)) -- Extrae el ID del juego
sets = splitString(game[2], semiColonDelimiter) -- Divide el juego en subconjuntos
for _, set in ipairs(sets) do -- por cada subconjunto de juego, verificamos que sea correcto
isSetVerified = true -- en cada iteración restablecemos la condición a true
cubes = splitString(set, commaDelimiter)
for _, cubeCount in ipairs(cubes) do
cube = splitString(cubeCount, spaceDelimiter) -- dividimos el string por "%s" (caracter espacio)
cubeNumber = tonumber(cube[1])
cubeColor = cube[2]
if cubeNumber > maxCubeColors[cubeColor] then
isSetVerified = false
-- si el número de un cubo es inválido, no se necesita verificar mas
break
end
end
if not isSetVerified then
-- no es necesario iterar mas si un cubo es inválido
break
end
end
if isSetVerified then
-- Por último si no hay poda y el isSetVerified se mantiene verdadero, entonces suma el ID
result = result + gameID
end
end
return result
end
Parte 2
En la parte 2 te cambia las condiciones, ahora te pide determinar la mínima cantidad de cubos necesarios para que un juego sea posible, aquí se puede dar lugar a una confusión, en este caso, la mínima cantidad de cubos necesarios es la máxima cantidad de cubos de cada juego, por lo que solo hay que buscar cada cubo inicializando el valor en 0, y solo aplicar una función max(), es decir, quedarse siempre con el máximo valor de cada cubo.
local function answer2()
local lines = getInput()
local game = ""
local sets = {}
local cubes = {}
local cube = {}
local cubeNumber = 0
local cubeColor = ""
local minCube = {
blue = 0,
red = 0,
green = 0
}
local result = 0
for _, line in ipairs(lines) do
game = splitString(line, colonDelimiter)
sets = splitString(game[2], semiColonDelimiter)
minCube.blue = 0
minCube.red = 0
minCube.green = 0
for _, set in ipairs(sets) do
cubes = splitString(set, commaDelimiter)
for _, cubeCount in ipairs(cubes) do
cube = splitString(cubeCount, spaceDelimiter)
cubeNumber = tonumber(cube[1])
cubeColor = cube[2]
if cubeNumber > minCube[cubeColor] then
minCube[cubeColor] = cubeNumber
end
end
end
result = result + minCube.blue * minCube.red * minCube.green
end
return result
end
Con esto ya se puede obtener la solución de ambas partes
print("Parte 1:", answer1())
print("Parte 2:", answer2())
Puede encontrar mi código completo aquí: Github.