Day 13: Knights of the Dinner Table

Day 13.1


In [60]:
import csv
from collections import defaultdict

def parse_happiness(input_file):
    happiness = defaultdict(lambda: defaultdict(int))
    with open(input_file, 'rt') as f_input:
        csv_reader = csv.reader(f_input, delimiter=' ')
        for l in csv_reader:
            happiness[l[0]][l[-1].rstrip('.')] = ((l[2] == 'gain') - (l[2] == 'lose')) * int(l[3])
    return happiness

In [61]:
from functools import reduce

def pair_score(a, b, happiness):
    return happiness[a][b] + happiness[b][a]

def total_score(l, happiness):
    total = 0
    n = len(l)
    for i, name in enumerate(l):
        total += pair_score(l[i], l[(i+1) % n], happiness)
    return total

In [64]:
import itertools

def optimal_gain(input_file):
    happiness = parse_happiness(input_file)
    attendees = list(happiness.keys())
    max_score = 0
    for p in itertools.permutations(attendees[1:]):
        score = total_score([attendees[0]] + list(p), happiness)
        if max_score < score: max_score = score
    return max_score

Test


In [65]:
optimal_gain('inputs/input13.test1.txt')


Out[65]:
330

Solution


In [66]:
optimal_gain('inputs/input13.txt')


Out[66]:
709

Day 13.2

Add a neutral self.


In [71]:
from copy import copy

def add_neutral_self(happiness):
    new_happiness = copy(happiness)
    attendees = list(new_happiness)
    for k in attendees:
        new_happiness[k]['Self'] = 0
        new_happiness['Self'][k] = 0
    return new_happiness

def optimal_gain(input_file):
    happiness = add_neutral_self(parse_happiness(input_file))
    attendees = list(happiness.keys())
    max_score = 0
    for p in itertools.permutations(attendees[1:]):
        score = total_score([attendees[0]] + list(p), happiness)
        if max_score < score: max_score = score
    return max_score

In [72]:
optimal_gain('inputs/input13.txt')


Out[72]:
668