Eén van de dingen die ik leuk vind aan Advent of Code is de kans om dingen uit te proberen.

Omdat ik weer wat meer met Python bezig ben leek het me dan ook wel aardig om de puzzels van dag 2 in Python op te lossen.

Advent of Code 2023 dag 2: de opdracht Link to heading

We spelen een spelletje met een elf, waarin de elf kubussen uit een zakje trekt. Het zijn rode, groene, en blauwe kubussen.

Je invoer ziet er bijvoorbeeld zo uit:

Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue
Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red
Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red
Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green

Elke regel beschrijft een spel, en elk spel bestaat uit verschillende ronden.

Advent of Code 2023 dag 2, ster 1 Link to heading

Voor de eerste ster nemen we aan dat er 12 rode, 13 groene, en 14 blauwe kubussen zijn.

De vraag, gebaseerd op onze input, is of de voorgestelde spellen wel mogelijk waren.

Game 3 was dus niet mogelijk geweest — je kunt geen 20 rode kubussen pakken als er maar 12 zijn.

We gaan kijken welke spellen echt mogelijk waren, en die IDs bij elkaar op te tellen. De som daarvan is het antwoord.

(In bovenstaand voorbeeld zijn 1, 2, en 5 mogelijk, en is het antwoord dus 1 + 2 + 5 = 8.)

Ik ben uit gegaan van simpele Python code waarin we de tekstregels steeds verder opsplitsen, en dan inspecteren.

#!/usr/bin/env python3
max_limits = {"red": 12, "green": 13, "blue": 14}

def valid_round(round):
    pairs = round.split(',')
    for pair in pairs:
        number, color = pair.strip().split()
        if int(number) > max_limits[color]:
            return False

    return True

def valid_game(details):
    rounds = details.split(';')
    for round in rounds:
        if not valid_round(round):
            return False

    return True

total_score = 0
with open("test", "r") as file:
    for line in file:
        game_number_part, details_part = line.strip().split(":", 1)
        game_number = game_number_part.split()[1]

        if(valid_game(details_part)):
            total_score += int(game_number)

print(total_score)

Advent of Code 2023 dag 2, ster 2 Link to heading

Voor het tweede deel van de dag draaien we het om. We gaan er vanuit dat elk spel mogelijk was, en we gewoon niet weten hoeveel kubussen er waren.

Wel kunnen we natuurlijk weten hoeveel kubussen er in ieder geval waren van elke kleur.

Om spel 3 nog maar een keer te nemen: het zullen dus minimaal 20 rode kubussen zijn.

Wanneer we voor een spel weten hoeveel er minimaal is van iedere kleur nemen we het product daarvan (rood * blauw * groen), en dat tellen we op bij de totaalscore.

Net als we gisteren array_reduce gebruikte in PHP, gebruiken we hier nu de reduce-functie van Python.

Verder is dit vrij simpel: we gaan er van uit dat er van elke kleur minimaal één aanwezig is1, en werken het minimum gewoon elke ronde bij.

Als het minimum van deze ronde hoger is dan wat we tot nu als maximum voor dit spellen hebben staan, gebruiken we dat. Anders laten we het zoals het is.

#!/usr/bin/env python3
from functools import reduce

total_cubes_required = 0
with open("input", "r") as file:
    for line in file:
        required_cubes_per_color = {"red": 1, "green": 1, "blue": 1}

        game_number_part, details_part = line.strip().split(":", 1)
        game_number = game_number_part.split()[1]

        rounds = details_part.split(';')
        for round in rounds:
            pairs = round.split(',')
            for pair in pairs:
                number, color = pair.strip().split()
                required_cubes_per_color[color] = max(required_cubes_per_color[color], int(number))

        cubes_required_for_round = reduce(lambda x, y: x * y, required_cubes_per_color.values())
        total_cubes_required += cubes_required_for_round

print(total_cubes_required)

Dag 2 was ook nog goed te doen, zoals meestal wel het geval is.

En hoewel ik nooit op de Advent of Code leaderboard terecht zal komen was ik voor mezelf prima tevreden met de tijd die ik nodig had.


  1. En zo niet, heeft dat geen invloed op het resultaat, omdat we gewoon vermenigvuldigen met één. ↩︎