Advent of Code 2023 Day 19: Aplenty

Cover Photo

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 regra
  • validação-n é a validação ser feita com algum dos parâmetros
  • valor-n é o valor de retorno caso a validação resulte em true
  • valor-final é o valor de retorno caso nenhuma validação resulte em true

É 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: