Advent of code

 11 décembre 2022 

  Monkey in the Middle : Suivre les échanges de singes avec calcul de facteur «worry»
Monkey 0:
   
Starting items: 63, 57
   
Operation: new = old * 11
   
Test: divisible by 7
   
            
  1. code.py
f = open("input.txt", 'r')
lines = [line[:-1] for line in f.readlines()]
lines.append("")  # chaque singe a bien une ligne vide à la fin

NB_LINES_PER_MONKEY = 7
ROUNDS_NUMBER = {1:20, 2:10000}
NOMS = ['Kiki', 'Mojojo', 'King Kong', 'Abu', 'Donkey Kong', 'Marcel', 'Curious George', 'Cheetah']  # plus rigolo que de les numéroter
DO_OPERATEUR = {'*':lambda x,y:x*y, '+':lambda x,y:x+y}

# ### Un peu de triche au départ pour aller plus vite
# def fonctions(i):
#     return [lambda x:x*11, lambda x:x+1, lambda x:x*7, lambda x:x+3, lambda x:x+6,lambda x:x+5, lambda x:x*x, lambda x:x+7][i]

def fonction(operande1, operateur, operande2):
    if operande1 != 'old':
        print("Oui mais là non.")
        exit(1)
    if operande2 == 'old':
        return lambda x: DO_OPERATEUR[operateur](x, x)
    else:
        return lambda x: DO_OPERATEUR[operateur](x, int(operande2))


### Décodage des données simiesques
monkeys = []
startingItems = {}  # pour réinit entre les deux parties
MODULO_COMMUN = 1
for baseLineIndex in range(0, len(lines), NB_LINES_PER_MONKEY):
    monkeyLines = lines[baseLineIndex:baseLineIndex + NB_LINES_PER_MONKEY]
    items = (monkeyLines[1]+",") .split() [2:]      # rajouter une virgule en fin de ligne pour uniformiser les nombres
    items = list(map(lambda x:int(x[:-1]), items))
    operation = fonction(*monkeyLines[2].split()[3:])
    moduleDeTest       = int(monkeyLines[3].split()[3])
    MODULO_COMMUN *= moduleDeTest
    monkeyIndexIfTrue  = int(monkeyLines[4].split()[5])
    monkeyIndexIfFalse = int(monkeyLines[5].split()[5])
    nom = NOMS.pop(0)
    startingItems[nom] = items
    monkeys.append({'nom': nom,
                    'items': items,
                    'moduleDeTest': moduleDeTest,
                    'operation': operation,
                    'monkeyIndexIfTrue': monkeyIndexIfTrue,
                    'monkeyIndexIfFalse': monkeyIndexIfFalse,
                    'activite': 0
                    })


### C'est le moment de faire le singe
for numeroPartie in [1,2]:
    for monkey in monkeys:
        monkey['items'] = startingItems[monkey['nom']][:]     # Juste pour ici qu'on a besoin des noms, mais un tableau simple suffit sinon
        monkey['activite'] = 0

    for round in range(ROUNDS_NUMBER[numeroPartie]):
        for monkey in monkeys:
            for it in monkey['items']:
                monkey['activite'] += 1
                w = monkey['operation'](it) % MODULO_COMMUN     # truc mathématique malin comme un singe pour éviter les nombres gigantesques
                if numeroPartie == 1:
                    w = w // 3
                if w % monkey['moduleDeTest'] == 0:
                    nextMonkey = monkey['monkeyIndexIfTrue']
                else:
                    nextMonkey = monkey['monkeyIndexIfFalse']
                monkeys[nextMonkey]['items'].append(w)
            monkey['items'] = []

    activites = [monkey['activite'] for monkey in monkeys]
    activites.sort(reverse=True)
    print("Réponse partie", numeroPartie, activites[0]*activites[1])