Advent of Code 2023 Day 19: Aplenty
December 19, 2023 • 3 minutes reading time

Foto de Capa gerada por IA
Os Elfos da Gear Island agradecem sua ajuda e agora você está indo na direção de onde as peças faltante das máquinas estão sendo produzidas. Chegando lá é possível ver que todas as peças já formam uma montanha enorme e precisam ser catalogadas.
Os Elfos ali no entanto já possuem um sistema para isso baseado em 4 fatores: x, m, a e s (os nomes geram esse acrônimo xmas)
Contexto específico
Seu input é composto pelo conjunto de regras e pelas peças que precisam ser avaliadas, separadas por uma linha em branco. As regras sequem o seguinte formato
<nome-da-regra>{<validação-1>:<valor-1>,...,<validação-n>:<valor-n>,<valor-final>}
nome-da-regraé o nome em questão da regravalidação-né a validação ser feita com algum dos parâmetrosvalor-né o valor de retorno caso a validação resulte emtruevalor-finalé o valor de retorno caso nenhuma validação resulte emtrue
É importante mencionar que as validações são sequenciais na ordem que aparecem e que os valores valor-n e valor-final podem ser tanto um nome de uma outra regra ou um dos valores A (aceito) ou R (recusado).
As peças estão descritas como parâmetros das mesmas no seguinte formato
{x=<valor>,m=<valor>,a=<valor>,s=<valor>}
onde os valores são valores numéricos inteiros e positivos.
Todas as validações começam pela regra in e se separam nas seguintes até parar em um valor R ou A.
Seu desafio é encontrar o número de peças que terminam como A (aceita) e somar o valor de todos os parâmetros, de todas as peças aceitas.
Resolução Parte 1
Caso queira resolver antes de ler a respeito de minha solução, esse é o momento!
Para esse desafio decidi que iria montar um mapa (Map()) de validações e uma lista de peças. Na sequência, faria uma iteração sobre a lista de peças passando por cada um dos itens do mapa de validação iniciando pela validação in até encontrar os valores R ou A.
Optei por criar uma High-order Function (HOF) para cada validação que chamei de workflow. A função auxiliar responsável por quebrar um texto em um workflow ficou da seguinte forma
const fillWorkflow = (workflow) => {
const [_fullMatch, name, allConditions, finalResult] = workflow.match(
/(\w+){(.+:\w+)+,(\w+)}/
)
// functions with checks to be iterable
const conditionsChecks = allConditions.split(',').map((condition) => {
const [_fullMatch2, category, check, value, resultingWorkflow] =
condition.match(/(\w)(<|>)(\d+):(\w+)/)
return workflowFn({
category,
check,
value: Number(value),
resultingWorkflow,
})
})
WORKFLOWS.set(name, { conditionsChecks, finalResult })
}e a HOF auxiliar workflowFn() teve sua implementação como segue
const workflowFn =
({ category, check, value, resultingWorkflow }) =>
(singlePart) => {
if (check === GREATER_THAN) {
return singlePart[category] > value ? resultingWorkflow : null
}
// LOWER_THAN
return singlePart[category] < value ? resultingWorkflow : null
}Para validar o workflow optei por retornar o valor null para o caso da validação ser falsa e dessa forma seguir com as próximas validações da linha presentes no workflow até atingir o valor final.
No fim, as validações funcionam como cláusulas if sequenciais e a cláusula else apenas retorna no fim o valor final da linha
Ao passar todas as peças pelas validações e filtrar apenas as que são aprovadas encontramos a solução para o desafio somando todos os valores de parâmetros das peças. Na sequência é liberada a segunda parte do desafio: Descobrir todas as possíveis peças aprovadas, considerando que cada parâmetro é um valor inteiro positivo entre 1 e 4000.
Nota: Ainda estou resolvendo a segunda parte desse desafio!
Referências
O código final esta disponível no repositório do GitHub. Esses são alguns links que podem te auxiliar a compreender melhor o código e cada detalhe que mencionei ou esqueci de comentar a respeito de minha solução:
Métodos Array:
Métodos String: