Advent of Code 2023 Day 19: Aplenty
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 emtrue
valor-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: