# A detailed explanation of the following code will be added in the future.
import itertools
import numpy as np
import pandas as pd

import os
LETTERS = {
    1: '🎅',  # father christmas
    2: '🤶',  # mother christmas
    3: '🦌',  # reindeer
    4: '🧝',  # elf
    5: '🎄',  # christmas tree
    6: '🎁',  # gift
    7: '🎀',  # ribbon
    8: '🌟',  # star
}
INV_LETTERS = {v: k for k, v in LETTERS.items()}
def find_strings_perms(strings, verbose=False):
    all_perms = set(itertools.permutations(range(1, 8), 7))
    perms = []
    for s in strings:
        perms.append([])
        for i in range(len(s)-6):
            p = tuple(s[i:i+7])
            if p in all_perms:
                perms[-1].append(p)
    if verbose:
        lens = [len(_) for _ in  perms]
        print(f'There are {lens} permutations in strings, {sum(lens)} in total.')
        lens = [len(set(_)) for _ in  perms]
        print(f'There are {lens} unique permutations in strings, {sum(lens)} in total.')
    return perms

all_perms = set(itertools.permutations(range(1, 8), 7))
mandatory_perms = set((1, 2) +  _ for _ in itertools.permutations(range(3, 8), 5))
def routn(x):
    a = x[0]
    b = x[1]
    c = x[2]
    d = x[3]
    e = x[4]
    tmp_st = '🎅🤶'+a+b+c+d+e+'🤶🎅'+a+b+c+d+e+'🤶'+a+'🎅'+b+c+d+e+'🤶'+a+b+'🎅'+c+d+e+'🤶'+a+b+c+'🎅'+d+e+'🤶'+a+b+c+d+'🎅'+e+'🤶'+a+b+c+d
    return tmp_st
len(routn('🦌🧝🎄🎁🎀'))
def sol_0_1(x):
    a = x[0]
    b = x[1]
    c = x[2]
    d = x[3]
    e = x[4]
    string = '🎅🤶'+a+b+e+c+d + '🎅🤶'+a+b+e+d+c + '🎅🤶'+a+b+d+e+c + '🎅🤶'+a+b+d+c+e
    string = string +'🎅🤶'+a+b+c+e+d
    string = string + routn(a+c+b+e+d) + routn(a+c+d+b+e) + routn(a+c+e+d+b)
    string = string + '🎅🤶'+a+c+b+d+e + routn(x) + '🎅🤶'+a+c+d+e+b + '🎅🤶'+a+c+e+b+d    
    return string
len(sol_0_1('🦌🧝🎄🎁🎀'))
def sol_0_2(x):
    a = x[0]
    b = x[1]
    c = x[2]
    d = x[3]
    e = x[4]
    string = '🎅🤶'+a+d+c+e+b + '🎅🤶'+a+d+c+b+e + '🎅🤶'+a+d+b+c+e + '🎅🤶'+a+d+b+e+c
    string = string + '🎅🤶'+a+d+e+c+b
    string = string + routn(a+e+d+c+b)+routn(a+e+b+d+c)+routn(a+e+c+b+d)
    string = string + '🎅🤶'+a+e+d+b+c + routn(a+d+e+b+c) + '🎅🤶'+a+e+b+c+d + '🎅🤶'+a+e+c+d+b
    return string
def sol_1_1(x):
    a = x[0]
    b = x[1]
    c = x[2]
    d = x[3]
    e = x[4]
    string = '🎅🤶'+a+c+e+d+b + '🎅🤶'+a+c+d+e+b + '🎅🤶'+a+c+d+b+e + '🎅🤶'+a+c+b+d+e + '🎅🤶'+a+c+b+e+d
    string = string + routn(a+b+c+e+d)+routn(a+b+d+c+e)+routn(a+b+e+d+c)+routn(a+c+e+b+d)
    string = string + '🎅🤶'+a+b+c+d+e + '🎅🤶'+a+b+d+e+c + '🎅🤶'+a+b+e+c+d
    return string
def sol_1_2(x):
    a = x[0]
    b = x[1]
    c = x[2]
    d = x[3]
    e = x[4]
    string = '🎅🤶'+a+e+b+d+c + '🎅🤶'+a+e+c+d+b + '🎅🤶'+a+e+c+b+d 
    string = string + routn(a+e+b+c+d)
    string = string + '🎅🤶'+a+e+d+b+c + '🎅🤶'+a+e+d+c+b
    string = string + routn(a+d+e+c+b) + routn(a+d+b+e+c) + routn(a+d+c+b+e)
    string = string + '🎅🤶'+a+d+b+c+e + '🎅🤶'+a+d+c+e+b + '🎅🤶'+a+d+e+b+c
    return string
def sol_2_1(x):
    a = x[0]
    b = x[1]
    c = x[2]
    d = x[3]
    e = x[4]
    string = '🎅🤶'+a+b+c+d+e + '🎅🤶'+a+b+c+e+d + '🎅🤶'+a+b+d+c+e
    string = string + routn(a+c+b+d+e) + routn(a+b+e+c+d) + routn(a+b+d+e+c)
    string = string + '🎅🤶'+a+c+e+b+d + '🎅🤶'+a+c+e+d+b
    string = string + routn(a+c+d+e+b)
    string = string + '🎅🤶'+a+c+b+e+d + '🎅🤶'+a+c+d+b+e + '🎅🤶'+a+b+e+d+c
    return string
def sol_2_2(x):
    a = x[0]
    b = x[1]
    c = x[2]
    d = x[3]
    e = x[4]
    string = '🎅🤶'+a+e+d+c+b
    string = string + routn(a+e+c+d+b)
    string = string + '🎅🤶'+a+e+b+c+d + '🎅🤶'+a+e+b+d+c + '🎅🤶'+a+d+e+b+c + '🎅🤶'+a+d+e+c+b
    string = string + routn(a+d+c+e+b) + routn(a+d+b+c+e) + routn(a+e+d+b+c)
    string = string + '🎅🤶'+a+d+b+e+c + '🎅🤶'+a+d+c+b+e + '🎅🤶'+a+e+c+b+d
    return string
# LETTERS = {
#     1: '🎅',  # father christmas
#     2: '🤶',  # mother christmas
#     3: '🦌',  # reindeer
#     4: '🧝',  # elf
#     5: '🎄',  # christmas tree
#     6: '🎁',  # gift
#     7: '🎀',  # ribbon
#     8: '🌟',  # star
# }
sol_0 = ''
sol_1 = ''
sol_2 = ''
for i in ['🦌🧝🎄🎁🎀', '🧝🦌🎄🎁🎀', '🎄🦌🧝🎁🎀', '🎁🦌🧝🎄🎀', '🎀🦌🧝🎄🎁']:
    sol_0 += sol_0_1(i) + sol_0_2(i)
    sol_1 += sol_1_1(i) + sol_1_2(i)
    sol_2 += sol_2_1(i) + sol_2_2(i)
len(sol_0)
test = pd.DataFrame([sol_0,sol_1,sol_2], columns = ['schedule'])
test_strings = [[INV_LETTERS[c] for c in s] for s in test.schedule]
test_strings_perms = [set(_) for _ in find_strings_perms(test_strings)]
for i, s in enumerate(test_strings_perms):
    if mandatory_perms - s:
        print(f'String #{i} is missing {mandatory_perms - s}.')
if all_perms - set.union(*test_strings_perms):
    print(f'Strings are missing {all_perms - set.union(*strings_perms)}.')
sub = pd.DataFrame()
sub['schedule'] = test
sub.to_csv('submission_2440.csv',index=False)
"""
# w/ wildcard
"""
def check_if_good(a):
    # Check if the submission is valid
    global wildcard
    global start
    global other

    # If all the combinations beginning with 🎅🤶 are in the three submissions
    for permu in start['Permutation'].tolist():
        x=0
        if permu in a[0]:
            x+=1
            if permu in a[1]:
                x+=1
                if permu in a[2]:
                    continue
        # For wildcards
        permus_for_wild = wildcard[wildcard['Permutation']==permu].index.values
        in_string = False
        for p in permus_for_wild:
            if wildcard.at[p, 'Factor'] in a[0]: in_string = True
            if wildcard.at[p, 'Factor'] in a[1]: in_string = True
            if wildcard.at[p, 'Factor'] in a[2]: in_string = True
        if in_string: continue
        print("Not all 🎅🤶, missing:", permu, "; string:", x)
        return False

    # If all the combinations are in the submissions
    for permu in other['Permutation'].tolist():
        if permu in a[0]: continue
        if permu in a[1]: continue
        if permu in a[2]: continue

        # For wildcards
        permus_for_wild = wildcard[wildcard['Permutation']==permu].index.values
        in_string = False
        for p in permus_for_wild:
            if wildcard.at[p, 'Factor'] in a[0]: in_string = True
            if wildcard.at[p, 'Factor'] in a[1]: in_string = True
            if wildcard.at[p, 'Factor'] in a[2]: in_string = True
        if not in_string:
            print("Not all the combinaison, missing:", permu)
            return False

    # If there are 2 stars or less
    if a[0].count('🌟') > 2:
        print("Too many stars in string: 0")
        return False
    if a[1].count('🌟') > 2:
        print("Too many stars in string: 1")
        return False
    if a[2].count('🌟') > 2:
        print("Too many stars in string: 2")
        return False
    return True
permus = pd.read_csv("../input/santa-2021/permutations.csv") # Import of permutations
wildcard = pd.read_csv("../input/santa-2021/wildcards.csv") # Import of wildcard permutations

start = permus[permus.Permutation.str[:2] =='🎅🤶'] # DataFrame of permutations starting with 🎅🤶
other = permus[permus.Permutation.str[:2] !='🎅🤶'].reset_index(drop=True) # DataFrame of all other permutations
"""
# 2430
"""
sol_0_wc2 = sol_0[:244-7]+sol_0[244*3-7:244*3]+sol_0[244-7:244*2-21-47]+sol_0[244*7-7:244*7]\
+sol_0[244*2-21-47:244*3-14]+sol_0[244*3:244*4-14-47+2]\
+'🎄'+sol_0[244*4-14-47+2:244*4-14-6]+'🌟'+sol_0[244*4-14-5:244*4-14]+'🎄'\
+sol_0[244*4-14:244*5-14]+sol_0[244*6-14:244*6-7]+sol_0[244*5-7:244*6-14-47+2]\
+'🧝'+sol_0[244*6-14-47+2:244*6-14-6]+'🌟'+sol_0[244*6-14-5:244*6-14]+'🧝'\
+sol_0[244*6-7:244*7-7]+sol_0[244*7:]
len(sol_0_wc2)
sol_1_wc2 = sol_1[:244-21-47+2]+'🎁'+sol_1[244-21-47+2:244-21-6]+'🌟'+sol_1[244-21-5:244-21]+'🎁'\
+sol_1[244-21:244*2-7]+sol_1[244*2:244*4-7]+sol_1[244*2-7:244*2]+sol_1[244*4-7:244*5-21-47+2]\
+'🎁'+sol_1[244*5-21-47+2:244*5-21-6]+'🌟'+sol_1[244*5-21-5:244*5-21]+'🎁'\
+sol_1[244*5-21:244*5-7]+sol_1[244*10-21:244*10-14]\
+sol_1[244*5-7:244*6-7]+sol_1[244*8-7:244*8]+sol_1[244*6-7:244*7-14]+sol_1[244*7-7:244*8-14]+\
sol_1[244*8:244*10-21]+sol_1[244*10-14:]
len(sol_1_wc2)
sol_2_wc2 = sol_2[:244*2-21-47+2]+'🎄'+sol_2[244*2-21-47+2:244*2-21-6]+'🌟'+sol_2[244*2-21-5:244*2-21]+'🎄'\
+sol_2[244*2-21:244*4+21+47+2]\
+'🎁'+sol_2[244*4+21+47+2:244*4+21+47*2-6]+'🌟'+sol_2[244*4+21+47*2-5:244*4+21+47*2]+'🎁'\
+sol_2[244*4+21+47*2:244*5-7]+sol_2[244*5:244*8-21]+sol_2[244*8-14:]
len(sol_2_wc2)
sample = [sol_0_wc2,sol_1_wc2,sol_2_wc2]
check_if_good(sample)
sol_2430 = pd.DataFrame(sample, columns = ['schedule'])
sub = pd.DataFrame()
sub['schedule'] = sol_2430
sub.to_csv('submission_2430.csv',index=False)
"""
# 2428
"""
sol_0_2428 = sol_0[:28]+sol_0[230-47:230-6]+'🌟'+sol_0[230-5:230-1]+sol_0[230-6]+sol_0[230-8]+\
sol_0[35:230-47]+sol_0[230:2*244-21-47-6]+'🌟'+sol_0[2*244-21-47-5:2*244-21-47-1]+sol_0[2*244-21-47-6]+sol_0[2*244-21-47-8]+\
sol_0[2*244-21-47:2*244-7]+sol_0[244*2:]
len(sol_0_2428)
sol_1_2428 = sol_1[:82-6]+'🌟'+sol_1[82-5:82-1]+sol_1[82-6]+sol_1[82-8]+sol_1[7*244-21:7*244-14]+\
sol_1[82:82+47*2-6]+'🌟'+sol_1[82+47*2-5:82+47*2-1]+sol_1[82+47*2-6]+sol_1[82+47*2-8]+\
sol_1[82+47*2:244-21]+sol_1[244-14:244-7]+sol_1[244:7*244-21]+sol_1[7*244-14:]
len(sol_1_2428)
sol_2_2428=sol_2[:115-6]+'🌟'+sol_2[115-5:115-1]+sol_2[115-6]+sol_2[115-8]+\
sol_2[115:244-7]+sol_2[244:244+54-6]+'🌟'+sol_2[244+54-5:244+54-1]+sol_2[244+54-6]+sol_2[244+54-8]+\
sol_2[244+54:244*2-7]+sol_2[244*2:]
len(sol_2_2428)
sample = [sol_0_2428,sol_1_2428,sol_2_2428]
check_if_good(sample)
sol_2428 = pd.DataFrame(sample, columns = ['schedule'])
sub = pd.DataFrame()
sub['schedule'] = sol_2428
sub.to_csv('submission_2428.csv',index=False)