text_plain_output_2.png text_plain_output_1.png
from numba import jit

import math

import numpy as np # linear algebra

import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)

gift_pref = pd.read_csv('../input/child_wishlist_v2.csv', header=None).drop(0, 1).values
child_pref = pd.read_csv('../input/gift_goodkids_v2.csv', header=None).drop(0, 1).values
random_sub = pd.read_csv('../input/sample_submission_random_v2.csv').values.tolist()

n_children = 1000000
n_gift_type = 1000
n_gift_quantity = 1000
n_gift_pref = 100
n_child_pref = 1000
twins = math.ceil(0.04 * n_children / 2.0) * 2
triplets = math.ceil(0.005 * n_children / 3.0) * 3
ratio_gift_happiness = 2
ratio_child_happiness = 2

@jit(nopython=True)
def gcd(x, y):
    """ return greatest common divisor for two integers """
    while y != 0:
        x, y = (y, x % y)
    return x
@jit(nopython=True)
def lcm(a, b):
    """Compute the lowest common multiple of a and b"""
    return a * b // gcd(a, b)
@jit(nopython=True)
def anh(pred, child_pref, gift_pref):
    n_children = 1000000
    n_gift_type = 1000
    n_gift_quantity = 1000
    n_gift_pref = 100
    n_child_pref = 1000
    twins = math.ceil(0.04 * n_children / 2.0) * 2
    triplets = math.ceil(0.005 * n_children / 3.0) * 3
    ratio_gift_happiness = 2
    ratio_child_happiness = 2
    tmp_dict = np.zeros(n_gift_quantity, dtype=np.uint16)
    for i in np.arange(len(pred)):
        tmp_dict[pred[i][1]] += 1
    for count in np.arange(n_gift_quantity):
        assert count <= n_gift_quantity
    for t1 in np.arange(0, triplets, 3):
        triplet1 = pred[t1]
        triplet2 = pred[t1 + 1]
        triplet3 = pred[t1 + 2]
        assert triplet1[1] == triplet2[1] and triplet2[1] == triplet3[1]
    for t1 in np.arange(triplets, triplets + twins, 2):
        twin1 = pred[t1]
        twin2 = pred[t1 + 1]
        assert twin1[1] == twin2[1]
    max_child_happiness = n_gift_pref * ratio_child_happiness
    max_gift_happiness = n_child_pref * ratio_gift_happiness
    total_child_happiness = 0
    total_gift_happiness = np.zeros(n_gift_type)
    for i in np.arange(len(pred)):
        row = pred[i]
        child_id = row[0]
        gift_id = row[1]
        assert child_id < n_children
        assert gift_id < n_gift_type
        assert child_id >= 0
        assert gift_id >= 0
        if np.sum(gift_pref[child_id] == gift_id):
            child_happiness = (n_gift_pref - np.where(gift_pref[child_id] == gift_id)[0]) * ratio_child_happiness
            tmp_child_happiness = child_happiness[0]
        else:
            tmp_child_happiness = -1
        if np.sum(child_pref[gift_id] == child_id):
            gift_happiness = (n_child_pref - np.where(child_pref[gift_id] == child_id)[0]) * ratio_gift_happiness
            tmp_gift_happiness = gift_happiness[0]
        else:
            tmp_gift_happiness = -1
        total_child_happiness += tmp_child_happiness
        total_gift_happiness[gift_id] += tmp_gift_happiness
    denominator1 = n_children * max_child_happiness
    denominator2 = n_gift_quantity * max_gift_happiness * n_gift_type
    common_denom = lcm(denominator1, denominator2)
    multiplier = common_denom / denominator1
    return float(math.pow(total_child_happiness * multiplier, 3) + math.pow(np.sum(total_gift_happiness), 3)) / float(math.pow(common_denom, 3))

anh(np.array(random_sub), child_pref, gift_pref)