O terceiro dia do Advent of Code foi ontem 03/12/2024! Se você caiu aqui hoje pela primeira vez, não deixe de ler os posts sobre o Dia 1 e o Dia 2!

Classifiquei o terceiro problema como fácil (parte 1) e médio (parte 2).

Dicas#

  • Você pode utilizar expressões regulares para detectar mul e extrair os números.
  • Na segunda parte, você pode utilizar uma máquina de estados simples para ativar ou desativar as multiplicações.
  • Lembre-se de re.compile e re.findall.

Quanto de Python você precisa saber?#

Os capítulos se referem ao meu livro Introdução à Programação com Python.

  • Expressões regulares e máquinas de estado - Capítulo 12

Resposta#

A listagem do módulo auxiliares.arquivos você encontra no Dia 1.

import re
from auxiliares.arquivos import le_arquivo_sem_linhas_em_branco

ENTRADA_TESTE = (
    "xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))"
)
REGEX_NUMERO = r"mul(\((\d+),(\d+)\))"
REGEX_DONT = r"(don't\(\))"
REGEX_DO = r"(do\(\))"

rex = re.compile(REGEX_NUMERO)

rex_parte2 = re.compile(rf"({REGEX_DONT}|{REGEX_DO}|({REGEX_NUMERO}))")

print(rf"({REGEX_DONT}|{REGEX_DO}|({REGEX_NUMERO}))")


def calcula_soma_de_multiplicações(entradas: list[str]) -> int:
    m = 0
    for entrada in entradas:
        for _, o1, o2 in rex.findall(entrada):
            m += int(o1) * int(o2)
    return m


def calcula_soma_de_multiplicações_parte2(entradas: list[str]) -> int:
    m = 0
    estado = 1  # multiplicações ativas
    for entrada in entradas:
        for achado in rex_parte2.findall(entrada):
            if achado[0].startswith("don't"):
                estado = 0  # multiplicações desativadas
            elif achado[0].startswith("do"):
                estado = 1  # multiplicações ativas
            elif achado[0].startswith("mul"):
                if estado:
                    (*_, o1, o2) = achado
                    m += int(o1) * int(o2)
    return m


m = calcula_soma_de_multiplicações([ENTRADA_TESTE])
print(m)
assert m == 161

ENTRADA_PROBLEMA = le_arquivo_sem_linhas_em_branco("03/input.txt").splitlines()
m = calcula_soma_de_multiplicações(ENTRADA_PROBLEMA)
print(m)
assert m == 184122457

# Parte 2

ENTRADA_TESTE_2 = (
    r"xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))"
)
m = calcula_soma_de_multiplicações_parte2([ENTRADA_TESTE_2])
print(m)
assert m == 48

m = calcula_soma_de_multiplicações_parte2(ENTRADA_PROBLEMA)
print(m)
assert m == 107862689