컴퓨터 & 코딩/Python

[Python] Advent of Code 2022 - Day 11

구로그 2022. 12. 15. 03:07
728x90

원숭이가 갖고 있는 아이템들이 문제에 제시된 조건에 맞게 다른 수로 바뀐 후 다른 원숭이에게 넘겨주는 과정을 반복한다.

각 원숭이마다 총 몇 개의 아이템들이 거쳐갔는지 계산하고 그 중 가장 큰 횟수 두 개를 곱해주면 되는 문제였다. 

import math

file = open("input/day11.txt", "r")
data = file.read().splitlines()

monkeys_list = []
temp = []

count = 0

# 1
for line in data:
    if line == "":
        monkeys_list.append(temp)
        temp = []
    elif line != "":
        temp.append(line.strip())
monkeys_list.append(temp)

monkeys_dict = {}

# 2
for i in range(len(monkeys_list)):
    key = monkeys_list[i][0][:-1]
    monkeys_dict[key] = {}
    for j in range(1, 6):
        monkeys_dict[key][monkeys_list[i][j].split(
            ":")[0]] = monkeys_list[i][j].split(":")[1].strip()
    monkeys_dict[key]["Starting items"] = monkeys_dict[key]["Starting items"].split(
        ", ")
    monkeys_dict[key]["Operation"] = monkeys_dict[key]["Operation"][10:].split(
        " ")
    monkeys_dict[key]["Test"] = int(monkeys_dict[key]["Test"].split(" ")[-1])
    for y in monkeys_dict[key]["If true"]:
        if y.isdigit():
            monkeys_dict[key]["If true"] = int(y)
    for z in monkeys_dict[key]["If false"]:
        if z.isdigit():
            monkeys_dict[key]["If false"] = int(z)


round = 0
inspect_list = [0, 0, 0, 0, 0, 0, 0, 0]

# 3
while round < 20:
    round += 1
    for a in range(len(monkeys_list)):
        delete = []
        inspected = 0
        monkey = monkeys_dict[f"Monkey {a}"]
        true_monkey = int(monkey["If true"])
        false_monkey = int(monkey["If false"])
        for b in range(len(monkey["Starting items"])):
            inspected += 1
            old_worry_level = int(monkey["Starting items"][b])
            delete.append(old_worry_level)
            new_worry_level = 0
            if monkey["Operation"][1] != "old":
                if monkey["Operation"][0] == "*":
                    new_worry_level = old_worry_level * \
                        int(monkey["Operation"][1])
                elif monkey["Operation"][0] == "+":
                    new_worry_level = old_worry_level + \
                        int(monkey["Operation"][1])
            elif monkey["Operation"][1] == "old":
                new_worry_level = old_worry_level * old_worry_level
            new_worry_level = new_worry_level//3
            if new_worry_level % monkey["Test"] == 0:
                monkeys_dict[f"Monkey {true_monkey}"]["Starting items"].append(
                    str(new_worry_level))
            elif new_worry_level % monkey["Test"] != 0:
                monkeys_dict[f"Monkey {false_monkey}"]["Starting items"].append(
                    str(new_worry_level))
        for item in delete:
            monkey["Starting items"].remove(str(item))
        inspect_list[a] += inspected


print(inspect_list)

 

# 1 앞서 인풋 데이터를 한 줄 씩 읽어온 걸 받아와 빈줄, 빈칸을 지워내는 과정을 거친다. 그리고 정보들을 원숭이들마다 하나의 리스트로 만들어낸다. 

# 2 이후 원숭이 정보가 담긴 리스트를 딕셔너리로 만든다. 나중에 계산하기 쉽도록 필요없는 글자는 없애주고 숫자만 남긴다. 

# 3 이제 문제에서 제시된 대로 총 20라운드를 돌린다. (1 turn은 원숭이가 자기가 갖고 있는 아이템을 차례대로 다른 원숭이에게 넘겨주는 것. 1 round는 첫 번째 원숭이부터 마지막 원숭이까지 turn이 한 번씩 돈 것)

라운드를 돌리는 것은 while로 해주고, 원숭이를 돌리는 것은 첫 번째 for문, 그 속에 turn을 돌리는 두 번째 for문을 넣어준다.

원래 아이템의 값은 old_worry_level 변수에 넣어주고 차례대로 조건문을 돌면서 new_worry_level을 계산한 후 그 값을 해당하는 원숭이에게 넘겨준다.

넘겨주면서 본인의 리스트에서는 그 아이템이 없어져야 하기 때문에 remove()함수를 이용해 넘겨진 값(의 원래 값)을 없애주었다.

 

결과값은, 각 원숭이가 본인 차례일 때 아이템을 하나씩 보낼 때마다 미리 설정해놓은 inspect_list의 해당 인덱스값을 늘려주는 방식으로 구하였다. 

 


 

이렇게 과정을 정리해놓으니까 매우 단순한데 

중간에 뭘 잘못 적는 바람에 계속 삽질하느라고 시간이 꽤나 오래걸렸다.

역시, 한 번에 잘 적는 일은 없다는 걸 다시 한 번 깨달았다. 

 

반응형