Setup


In [1]:
import sys
import os

import re
import collections
import itertools
import math
import copy

import bcolz
import pickle

import numpy as np
import pandas as pd
import gc
import random
import smart_open
import h5py
import csv

import tensorflow as tf
import gensim
import string

import datetime as dt
from tqdm import tqdm_notebook as tqdm

import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
plt.style.use('seaborn-poster')
import seaborn as sns

random_state_number = 967898


/home/bicepjai/Programs/anaconda3/envs/interviews/lib/python3.6/importlib/_bootstrap.py:219: RuntimeWarning: compiletime version 3.5 of module 'tensorflow.python.framework.fast_tensor_util' does not match runtime version 3.6
  return f(*args, **kwds)

Code

Day 13: Packet Scanners


In [163]:
! cat day13_input.txt


0: 4
1: 2
2: 3
4: 4
6: 6
8: 5
10: 6
12: 6
14: 6
16: 8
18: 8
20: 9
22: 12
24: 8
26: 8
28: 8
30: 12
32: 12
34: 8
36: 12
38: 10
40: 12
42: 12
44: 10
46: 12
48: 14
50: 12
52: 14
54: 14
56: 12
58: 14
60: 12
62: 14
64: 18
66: 14
68: 14
72: 14
76: 14
82: 14
86: 14
88: 18
90: 14
92: 17

In [3]:
input_data = {}
with open("day13_input.txt") as f:
    for line in f.read().strip().split("\n"):
        k,v = (p for p in line.split(":"))
        input_data[int(k)] = int(v)
len(input_data)


Out[3]:
43

part 1

Brute Force Solution where we are updating all the scanners as per the time step


In [208]:
def update_scanner_depths(scanner_pos,scanner_depths):
    for d in scanner_depths:
        scanner_pos[d][0] += scanner_pos[d][1]
        if (scanner_pos[d][0] == scanner_depths[d]-1 or scanner_pos[d][0] == 0):
            scanner_pos[d][1] *= -1

def scanner_severity_bf(scanner_depths):
    """
    given scanner depths find serverity
    """
    # dict holding the current depth and the inc/dec flag
    # once it reached bottom or top flag multiplies by -1, thus rotating
    scanner_pos = {k:[0,1] for k in scanner_depths.keys()}

    # since we always get caught first
    caughts = []

    # going thru each pico second thru each scanner
    # if scanner find us in place, we are not caught
    # cur_pos is same as current time
    total_time_range = max(scanner_depths.keys()) + 1
    for cur_time in range(total_time_range):        
        # when the cur_pos that indicates the
        # scanner caught us, its index will be top one i.e, 0
        if cur_time in scanner_depths.keys() and scanner_pos[cur_time][0] == 0:
            caughts += [(cur_time, scanner_depths[cur_time])]
            
        # update scanner depths
        update_scanner_depths(scanner_pos,scanner_depths)
        

    return sum([a*b for a,b in caughts])

one could notice that we are interested only in the 0th position not others, lets say the depth is 3. the channel would be tracking as

depth 3

time 0 1 2 3 4 5 6 7 8 9

position 0 1 2 1 0 1 2 1 0 1

one could notice the 0s are always occuring at timesteps that are multiple of 4. can we generalize this pattern

depth: 2

time 0 1 2 3 4 5 6 7 8 9

position 0 1 0 1 0 1 0 1 0 1

depth: 4

time 0 1 2 3 4 5 6 7 8 9

position 0 1 2 3 2 1 0 1 2 3

its (depth - 1)*2


In [209]:
def scanner_severity(scanner_depths):
    severity = 0
    # here sc_id is also time
    for sc_id_time, depth in scanner_depths.items():
        if sc_id_time % ((depth - 1)*2) == 0:
            severity += (sc_id_time * depth)
    return severity

In [212]:
sample_depths = {0:3, 1:2, 4:4, 6:4}
assert scanner_severity(sample_depths) == 24

In [213]:
scanner_severity(input_data)


Out[213]:
1316

part 2


In [215]:
def escaped_scanners_bf(scanner_depths):

    caught = True
    delay_time = 0
    while caught:
        
        # dict holding the current depth and the inc/dec flag
        # once it reached bottom or top flag multiplies by -1, thus rotating
        scanner_pos = {k:[0,1] for k in scanner_depths.keys()}
        caught = False
        
        # run for the delayed time
        for i in range(delay_time):
            update_scanner_depths(scanner_pos,scanner_depths)
        
        # go thru the scanners now
        total_time_range = max(scanner_depths.keys()) + 1
        for cur_time in range(total_time_range):        
            # when the cur_pos that indicates the
            # scanner caught us, its index will be top one i.e, 0
            # print("---b4  ",cur_time+10,scanner_pos)
            if cur_time in scanner_depths.keys() and scanner_pos[cur_time][0] == 0:
                # print("---caught---",cur_time,scanner_pos[cur_time])
                caught = True
                delay_time += 1
                break    
            # update scanner depths
            update_scanner_depths(scanner_pos,scanner_depths)
            # print("---aftr",cur_time+10,scanner_pos)
            
        # successfully ran thru without getting caught
        # print("=====================",delay_time)
        if not caught:
            break
        
    return delay_time

In [232]:
def escaped_scanners(scanner_depths):
    delay_time = 0
    caught = True
    while caught:
        caught = False
        for sc_id_time,depth in scanner_depths.items():
            if (sc_id_time + delay_time) % ((depth-1)*2) == 0:
                caught = True
                delay_time += 1
                break
        if not caught:
            break
    return delay_time

In [233]:
assert escaped_scanners_bf(sample_depths) == 10
assert escaped_scanners(sample_depths) == 10

In [234]:
escaped_scanners(input_data)


Out[234]:
3840052

In [243]:
(1,1,"u")[:2]


Out[243]:
(1, 1)

Day 14: Disk Defragmentation


In [112]:
input_data = 'ffayrhll'
sample_data = 'flqrgnkx'

part 1


In [114]:
bit_map = {
    0:0, 1:1, 2:1, 3:2,
    4:1, 5:2, 6:2, 7:3,
    8:1, 9:2, 10:2, 11:3,
    12:2, 13:3, 14:3, 15:4
}

def count_bits(hex_string):
    nof1s = 0
    # print("----",hex_string)
    for hex_ch in hex_string:
        nof1s += bit_map[int(hex_ch, 16)]
    return nof1s

In [121]:
def square_fragment_bits(data):
    fragment_bits = []
    for i in range(0,128):
        hash_str = data + "-" + str(i)
        fragment_bits += [knot_hash(hash_str)]
    return fragment_bits

def number_of_square_fragments(data):
    nofsquares = 0
    for hash_str in square_fragment_bits(data):
        nofsquares += sum(bin(int(ch, 16))[2:].count('1') for ch in hash_str)
    return nofsquares

In [122]:
number_of_square_fragments(sample_data) == 8108


Out[122]:
True

In [123]:
number_of_square_fragments(input_data)


Out[123]:
8190

part 2


In [263]:
def mark_regions(data, r, c, region):
    if r > 127 or r < 0 or c > 127 or c < 0:
        return
    
    if data[r][c] == 1:
        # mark
        data[r][c] = region

        # recurse near by squares
        mark_regions(data, r+1, c, region)
        mark_regions(data, r-1, c, region)
        mark_regions(data, r, c-1, region)
        mark_regions(data, r, c+1, region)

def count_regions(data):
    fragment_bits = square_fragment_bits(data)
    
    bit_strings = []
    # lets make 128 x 128 bit strings
    for hash_str in fragment_bits:
        bit_string = bin(int(hash_str, 16))[2:]
        bit_string = "".join(['0']*(128-len(bit_string))) + bit_string
        bit_strings += [list(map(int,bit_string))]
        
    # go thru each square
    regions = 2
    for r in range(0,128):
        for c in range(0,128):
            if bit_strings[r][c] == 1:
                mark_regions(bit_strings, r, c, regions)
                regions += 1
    return regions - 2

In [264]:
sys.getrecursionlimit()


Out[264]:
2000

In [265]:
count_regions(sample_data) == 1242


1242
Out[265]:
True

In [266]:
count_regions(input_data)


1134
Out[266]:
1134

Day 15: Dueling Generators

input_data

Generator A starts with 512

Generator B starts with 191


In [3]:
gen_A_input = 512
gen_B_input = 191

gen_A_sample = 65
gen_B_sample = 8921

part 1


In [26]:
def generatorA(input_value):
    current_value = input_value
    while True:
        current_value = (16807*current_value) % 2147483647
        yield current_value

def generatorB(input_value):
    current_value = input_value
    while True:
        current_value = (48271*current_value) % 2147483647
        yield current_value
    
def num_matches(gena_input, genb_input, rounds=int(4e7)):
    matches = 0
    gena_output = generatorA(gena_input)
    genb_output = generatorB(genb_input)
    bits16 = 0xFFFF
    for i in range(rounds):
        if next(gena_output)&bits16 == next(genb_output)&bits16:
            matches += 1
    return matches

In [28]:
num_matches(gen_A_sample, gen_B_sample, rounds=5) == 1
num_matches(gen_A_sample, gen_B_sample, rounds=int(4e7)) == 588


Out[28]:
True

In [29]:
num_matches(gen_A_input, gen_B_input, rounds=int(4e7))


Out[29]:
567

part 2


In [30]:
def generatorA(input_value):
    current_value = input_value
    while True:
        current_value = (16807*current_value) % 2147483647
        if current_value % 4 == 0:
            yield current_value

def generatorB(input_value):
    current_value = input_value
    while True:
        current_value = (48271*current_value) % 2147483647
        if current_value % 8 == 0:
            yield current_value

In [32]:
num_matches(gen_A_sample, gen_B_sample, rounds=int(5e6)) == 309


Out[32]:
True

In [33]:
num_matches(gen_A_input, gen_B_input, rounds=int(5e6))


Out[33]:
323

Day 16: Permutation Promenade


In [35]:
! cat day16_input.txt


x8/10,s15,x5/0,pd/a,x14/7,pg/l,s4,x0/12,s12,x2/1,s3,x11/6,pa/j,x9/2,pc/f,x8/12,s10,x3/1,s10,x13/15,pd/g,x6/11,s2,x12/14,s1,x7/5,s4,x10/11,pl/c,x12/1,s7,x3/8,s8,po/k,x1/14,s15,x11/7,pg/c,x2/12,pp/a,x3/1,s5,x13/8,s8,x12/7,s4,x4/6,s13,pf/h,x13/15,s1,x11/12,pc/l,x10/5,s12,x9/14,s2,x10/8,s13,x4/0,s6,x1/9,s7,pk/o,x2/4,pb/l,x15/0,s4,x7/13,ph/e,x10/12,s7,x7/0,s11,x15/5,s9,x1/3,s9,x0/4,s9,x11/3,pf/g,x14/5,pj/p,s13,x9/7,s7,x2/10,s15,x1/9,pd/o,x13/6,s4,x9/12,s15,x10/2,pp/n,x11/6,pm/a,s4,x13/7,s8,x15/2,s6,x5/12,s14,x4/2,s10,x0/13,s9,x9/5,s7,x11/7,pn/f,x5/6,pe/c,x3/2,s14,x6/11,s3,x3/15,s14,x6/14,s3,x4/12,s2,x14/15,s7,x13/5,pg/p,x15/6,s13,x3/10,s4,x14/11,po/l,x9/15,s14,x11/1,s1,x13/5,pa/e,x7/2,pb/i,x12/8,s2,ph/k,x5/2,pf/l,x7/9,s2,x2/4,s4,x15/1,s15,x2/9,s14,x0/1,s9,x10/2,s9,pn/p,x15/11,s5,x0/7,s12,x15/14,s4,pf/l,x3/1,s15,x11/8,pj/a,x9/3,pn/c,x0/7,pk/b,x15/13,pp/e,x4/8,s12,x0/9,pg/l,x14/15,s4,x5/13,pj/k,x10/2,s7,x8/5,pp/f,x12/7,po/b,x14/13,s5,x3/8,s1,x6/1,s10,x13/7,s9,x10/12,s13,x6/13,s12,x9/14,s5,x11/13,pf/n,x4/15,s15,x2/0,s1,x9/10,s7,x1/14,pl/i,x15/8,s10,pk/n,x3/4,s11,x10/13,s10,x14/2,s9,pj/d,x12/11,s3,x0/9,s14,pe/n,s10,x15/2,s4,x11/14,s2,x7/6,s6,x3/5,s4,x7/12,s9,x15/2,ph/l,x1/12,s3,po/b,x15/4,s3,x3/6,s2,x8/2,s3,x3/5,pa/n,x7/9,s11,x13/4,pd/e,x11/1,pj/h,x15/3,pm/d,s7,x5/0,s9,x4/9,s12,x11/5,s9,x3/12,pn/a,x5/15,s9,x6/7,s6,x1/13,pl/o,x15/6,s12,x7/5,s10,x15/9,pb/c,x1/14,pd/a,s3,x15/7,s10,pb/i,x2/11,s9,x15/4,pl/j,x8/12,s9,x9/1,s2,pd/g,x6/8,s3,x2/9,s7,x8/13,s9,x11/5,s15,x1/9,s6,x4/5,s9,pl/h,x7/11,s7,x15/14,s1,x6/0,s5,x1/12,pf/d,s2,x5/4,s7,x12/11,s3,x8/4,s6,x12/13,po/a,x15/1,s6,x0/4,pe/n,s15,x3/10,s5,x4/8,pm/d,x15/0,s10,x12/2,s5,x6/0,s11,ph/b,x13/11,s15,x7/1,pg/m,x9/0,pn/o,x4/1,s12,x14/6,pp/d,s13,x0/1,s7,x3/4,s2,x8/12,s13,x1/3,pk/f,x6/8,pa/g,x0/5,po/h,x10/3,s5,pp/i,x9/14,pa/j,x15/1,s2,x7/0,s13,x10/13,s5,x9/3,s14,x1/2,po/n,x3/6,pl/p,s13,x10/5,s4,x4/15,pn/i,x2/3,s7,x5/7,pa/o,x3/9,pc/j,x12/0,pn/i,x15/8,s5,pl/j,s5,x10/5,s10,x9/11,pi/d,x10/15,s8,x0/12,s4,x10/15,pk/b,x0/13,pj/f,x6/3,s2,pc/h,x4/2,pl/f,x9/11,s15,x5/7,s3,x4/8,pa/k,s15,x10/13,s9,x4/5,pi/m,x0/2,pn/o,s12,x13/14,s6,x2/5,pl/d,x0/10,s10,x9/14,pi/b,s14,x3/6,s13,x1/14,s13,x8/7,pm/d,x13/10,s13,ph/o,x4/8,s3,x7/14,pe/f,x15/8,s11,x5/7,s5,pj/a,x1/10,pd/n,x11/9,pb/f,x0/15,pl/i,x12/4,ph/j,s13,x1/5,s1,x7/14,po/f,x9/5,s7,x1/15,pk/a,x7/9,s3,x13/3,pd/f,x11/2,s5,x12/4,s12,x10/14,pc/a,x8/15,s10,x6/5,pl/o,x1/4,s14,x6/11,s3,x7/10,s3,x15/3,s3,x4/14,s14,x9/8,pa/b,x7/5,s7,x4/3,pk/g,x6/13,s3,x1/15,s5,x8/9,s10,x3/7,pc/b,x11/5,pk/a,x2/13,s13,x5/4,pd/o,x10/3,s10,x4/7,s3,x13/0,pm/e,x14/8,s2,pk/l,x5/6,s10,x4/7,pb/n,x15/11,s3,x4/12,s11,x14/0,s2,x3/12,pi/h,x5/15,pb/c,x10/8,pm/i,x15/13,s11,x9/11,pb/k,x12/5,pp/h,s4,x15/14,pf/d,x9/5,s1,x8/10,pk/b,s14,x6/5,s7,x10/15,s5,x6/5,s10,x0/3,s13,x11/14,s11,x15/7,s8,x12/8,s14,x11/0,s6,x13/7,pp/l,x14/3,s3,x8/10,s7,x3/11,s10,x10/1,pb/d,x7/11,pi/o,x15/0,s13,x8/2,pn/a,s2,x15/1,s7,x12/6,pd/h,s5,x14/8,pb/n,x3/10,s6,x11/9,pc/f,x6/8,pb/g,x3/15,s5,x14/6,pj/n,x3/15,s7,x10/7,po/c,x11/15,s15,x4/3,pf/d,x0/2,ph/g,x7/15,s14,x5/13,s8,x4/1,s11,x13/15,s13,x14/9,pj/i,x12/3,pd/b,x11/10,pl/c,s2,pn/b,x12/7,pa/p,x15/11,pl/b,x2/12,s7,x8/15,po/a,x5/12,pl/k,x0/7,s2,x1/9,s9,x13/11,s10,x5/2,s9,x1/13,pp/j,x4/10,s1,x7/9,pk/b,x12/2,s7,x11/14,s7,x9/6,s6,x13/1,pc/h,x12/3,s6,x9/10,s12,pl/j,x4/7,s13,x13/1,ph/i,x2/7,s6,x3/0,s9,x2/11,s7,x0/1,pd/p,s1,x5/14,pk/f,s6,x6/9,s4,x11/13,pb/m,x8/15,s1,x0/6,pk/o,x15/2,pb/g,x3/4,s8,x13/14,s4,pi/j,x4/5,pf/g,x10/12,pe/l,x0/7,pk/j,x2/5,s7,x13/14,pl/g,s2,x10/1,pd/k,x6/4,s14,x7/1,s13,x9/6,s1,x14/4,s6,x5/2,s13,x0/4,s3,po/m,s6,x12/15,pc/e,x8/9,pj/a,x4/14,s10,x2/11,s14,x13/14,s4,pm/f,x11/12,s8,pl/k,s13,x6/7,s13,pi/e,x4/9,s13,x1/0,s6,x14/9,s9,x11/12,s3,x7/13,pl/p,s1,x10/0,s1,x7/4,s10,x14/13,s4,x0/2,pf/b,x15/7,s1,pg/a,x13/9,pd/p,x12/5,s13,x6/1,s3,pf/k,x5/13,s13,pd/a,s11,x1/11,pe/b,x6/5,s12,x4/10,s14,x1/14,ph/a,x5/10,s10,x6/2,s7,x4/0,pk/f,x7/2,pn/m,x15/8,pd/p,x9/2,s4,x15/5,pg/m,x6/1,s10,x0/14,s14,x15/1,po/d,x13/11,s15,x5/9,s10,x11/8,s2,x5/13,s2,x3/10,pj/l,s4,x6/2,s14,pf/b,x14/4,pi/j,s15,x0/1,pb/d,x6/5,s4,pi/g,s6,x2/3,pf/a,x1/13,s3,x4/0,pj/k,x15/1,s8,x5/12,pm/l,x7/11,s11,x2/14,s4,x15/4,s11,x11/0,s13,x6/2,s2,x8/13,pd/a,x6/11,s4,x1/5,pk/g,x3/0,pp/d,x13/10,s13,x3/15,pc/o,x9/5,pd/n,x12/11,pf/g,x1/14,s8,x2/8,s10,x10/13,s12,x14/0,s8,x15/4,s6,x0/5,pk/e,x6/9,s7,x3/2,s5,x10/14,po/f,x5/2,pk/g,x13/12,s6,x6/10,pp/j,x14/12,pb/g,x10/6,s8,x1/11,pi/a,x9/0,s12,x4/12,pj/e,s2,x7/1,s4,x6/5,pb/f,x14/2,pd/e,x1/11,pk/p,x2/13,pf/m,x3/11,pd/a,x5/7,s1,x11/0,pk/m,x12/13,ph/c,x5/2,po/d,x12/15,s3,x3/5,s15,x15/7,s15,x4/2,s2,x0/7,pl/i,x9/11,s13,x1/10,s15,x14/4,s2,pe/b,s2,x1/5,s2,x10/11,pm/j,x5/13,pi/l,x7/11,pn/k,x9/6,pl/m,x15/11,s1,x4/9,s12,x10/7,s8,x6/14,pj/p,x9/0,s8,x2/11,s13,x4/3,s1,x9/0,s14,x5/4,s12,x10/1,s4,pg/n,x7/5,s10,x8/13,s1,x9/14,pp/b,x12/2,s5,x4/0,s5,x2/10,ph/e,x13/4,s6,x1/8,s10,x3/10,s10,pf/p,x7/1,pc/h,x8/0,pl/f,x13/5,pb/m,x4/3,ph/d,x6/1,pa/f,x2/0,s10,x15/1,s4,x9/3,pk/j,x6/12,s10,x3/14,s5,x0/12,s14,pl/b,x8/13,po/f,x0/4,s10,x5/3,pd/p,x2/7,pi/o,x5/15,pe/b,x3/0,s5,x13/15,s9,x10/12,s2,x6/11,s13,x15/3,ph/g,x9/12,pd/e,x1/3,pn/h,x5/14,s11,x10/2,s5,pj/o,x5/15,s2,x1/3,s2,x10/15,pc/e,s13,x7/6,s12,pk/p,x8/15,s5,x1/14,pi/h,x8/5,s15,x7/10,s8,x11/4,pd/a,x9/3,s13,pl/c,x15/4,pe/n,x8/10,s9,x9/7,s14,x11/4,s14,x6/5,s4,x13/12,pi/a,x5/3,s5,pe/d,x12/14,s15,x2/3,pj/m,s2,x7/0,s3,x8/12,pi/b,x3/9,s8,x13/2,ph/n,x6/12,s3,x10/4,pb/a,s2,x5/6,po/f,s13,x9/8,s12,x11/2,s14,x10/1,pp/b,x3/9,pl/c,x1/15,s2,x0/12,s13,x3/15,s14,x4/10,po/e,x9/15,s9,x4/11,s3,x8/3,s7,pm/i,x1/0,ph/n,x14/3,s8,x2/0,s3,x7/13,pc/p,x14/11,s13,pb/f,x7/10,pc/m,x12/11,pj/b,x1/8,s7,x12/9,s3,x3/10,pi/c,x0/7,s4,x10/15,s8,pk/g,s6,x9/0,pb/o,x4/15,pe/c,x5/12,pd/m,x6/2,pp/h,x3/7,s8,x5/1,pi/f,x0/12,s3,x2/6,pm/k,x11/9,s5,x8/4,s14,x2/11,pl/j,x6/7,s15,x13/12,pn/b,x11/2,pe/h,x6/5,s5,x15/2,s6,x13/5,s7,x12/15,s11,x4/5,pp/b,s2,x15/11,s1,pm/k,s3,x2/4,pl/j,x11/14,pa/p,s8,x5/8,pf/i,x9/7,pj/h,x11/4,s5,x7/9,s15,pc/e,x0/15,pp/j,s14,po/g,x7/13,pa/c,x0/4,pi/k,x3/7,s13,x10/8,pd/e,x5/14,s10,x7/1,s14,x9/14,s1,x5/1,ph/o,x8/2,s14,x9/13,pc/n,x10/3,s14,x12/0,pi/g,x9/4,s14,x2/8,pb/o,x10/12,s13,x6/7,s11,x9/11,pl/e,x13/4,s15,x6/14,pc/b,x8/2,s15,x12/9,s9,x2/0,s4,x8/11,pl/h,x1/12,s2,x0/14,pp/c,s12,x4/10,s1,x5/11,s6,x1/12,s12,x6/7,s9,x4/1,pe/d,x12/0,s1,x9/10,s2,x7/2,ph/p,x9/5,s4,x11/13,s6,x5/4,po/l,x10/1,s5,x8/14,s2,x7/11,pf/j,x1/5,s8,x7/12,s7,x2/9,s12,x0/11,pn/i,s12,x6/13,s3,x2/14,s2,x15/6,pl/g,s9,x14/1,s7,x13/4,s12,x7/6,s5,x5/2,pf/k,x7/4,s15,x9/6,s3,x0/13,s8,x15/4,ph/m,x2/5,s15,x11/10,s3,x14/1,s7,x10/5,s6,po/f,x1/7,s13,x15/3,s13,x12/13,pi/g,x9/7,pf/b,x5/2,ph/n,x11/8,pf/d,x5/9,s7,x13/2,s2,x3/10,pl/k,x6/14,pm/a,x7/9,s6,x15/2,s9,x7/1,s2,x8/0,s1,x1/7,ph/d,x14/5,pj/e,x1/8,po/c,x5/11,pn/i,x14/4,s2,x11/9,s15,pp/d,x1/7,s2,pf/g,x2/10,ph/n,x6/15,s5,x3/14,s10,x11/2,pj/f,x1/12,pg/d,x7/2,s5,x11/5,s14,pl/j,x7/10,s10,x15/8,s5,x7/12,pd/h,x5/14,pk/j,x3/12,po/f,s2,x4/13,pn/c,x5/6,pb/k,s2,x8/1,pf/n,s10,x5/9,s4,x2/7,s11,x15/1,s3,x10/2,s9,x1/7,s6,x2/12,s2,x3/5,ph/b,x0/7,s3,x12/6,s13,x14/4,pl/n,x1/10,pp/m,x2/0,pl/c,x5/14,s6,x0/8,s4,x13/9,s4,x7/12,pm/h,x10/11,pd/a,x1/2,pi/k,x11/3,s12,x2/7,pj/l,x11/1,s14,pm/i,x2/6,pf/n,x13/10,pi/a,x9/2,s9,x10/1,s12,x5/7,pe/n,x1/14,s8,x0/11,s3,x8/4,s15,x15/1,pf/g,x13/2,s6,x7/4,pk/p,x5/2,s6,pf/e,x12/9,s12,x14/11,s5,x5/2,s14,x7/10,po/n,x4/6,s6,x12/14,pk/j,x6/15,s8,x3/12,s10,x10/5,s12,x12/6,s6,x7/1,s13,x2/13,s9,x11/7,s2,x8/9,s5,x6/13,pe/p,x0/2,s9,x13/10,s3,x14/0,s2,x9/3,s10,x7/15,pn/g,x4/14,pf/d,x15/11,pj/g,x12/13,pc/i,x14/0,pa/o,x8/7,pj/i,x3/0,pl/n,x6/5,s14,x7/15,pc/j,x13/0,s12,x14/10,s2,pi/k,x2/9,pf/e,s4,x15/7,s9,x4/10,s11,x9/11,s13,x0/4,s14,pp/l,x6/8,pb/m,x13/5,s6,x4/11,pd/l,x8/12,s11,x10/4,pg/m,x12/0,s14,pn/h,x9/2,s12,x1/0,pk/c,x3/8,s9,x6/10,pe/d,x0/15,s2,x3/5,s11,x15/6,s8,x3/10,pg/l,x11/1,pm/d,x7/13,s4,x6/10,pg/h,x1/5,pd/e,x7/12,pj/n,s12,x4/15,ph/c,x5/7,pi/j,x4/9,pb/e,x14/6,pl/i,x4/9,pc/o,x15/1,s7,x10/7,s1,x14/5,s14,x10/12,s12,x0/6,ph/l,x4/14,s6,x13/0,pi/k,x14/3,s7,x11/9,pl/b,s11,x3/13,pe/n,x2/5,pf/m,x15/8,s8,pp/n,x5/14,s15,x7/2,s14,x4/14,s13,x7/1,pl/o,x8/4,pd/e,x13/5,pn/b,x6/4,s2,x15/9,s7,x6/12,pl/d,x11/13,s14,x7/0,pm/j,x1/9,s4,x2/12,pk/n,x7/11,s15,pd/h,x8/0,s11,pe/o,x10/11,pc/b,s2,pg/l,x5/0,ph/c,x4/15,s15,x5/2,s1,x0/9,s1,x8/2,pm/o,x10/6,pj/e,x12/4,s11,x1/3,pa/c,x5/14,s3,pi/d,x10/11,pm/o,x4/12,s11,x8/1,s9,x2/11,s2,x12/6,s14,x13/8,s13,pi/j,x15/6,s9,pp/b,s10,pm/k,x10/9,s12,x2/12,s5,x8/1,s1,x5/11,pp/l,x8/9,s3,x11/6,s12,x9/0,s4,x8/13,s13,x3/0,s12,x6/7,s12,pn/d,x10/1,pe/m,x4/12,s9,x7/2,s3,x4/8,pg/p,x6/7,s13,x15/4,pb/m,x12/3,s10,x5/10,s12,x6/7,pj/f,x14/8,s10,x2/3,s7,x9/12,s10,x11/1,s5,x13/7,pg/a,s11,x8/4,pm/l,x6/0,s15,x14/8,pg/b,x11/15,pn/h,x0/5,s7,pa/e,x6/14,s5,x1/2,s2,x14/15,s3,x4/13,s12,x12/9,s11,x1/13,pd/b,x10/5,pg/f,x7/12,pp/i,x2/14,s2,x10/9,pk/n,x11/3,pg/d,x5/4,s4,x13/7,s11,x14/0,s4,x5/1,s8,x2/4,s12,x11/12,s4,x4/1,s14,x10/12,s7,x6/8,s12,x1/13,s7,x5/0,s4,x1/8,s7,x7/3,s14,x1/4,pc/k,s7,x11/13,s3,x2/3,pj/g,x15/8,pf/e,s13,x3/4,ph/g,x12/15,pn/a,x11/5,pf/h,x6/7,s12,x2/9,s6,x6/3,pd/m,s11,x4/8,s7,pl/h,s13,x9/15,s6,pm/b,x7/3,s1,x15/8,pj/o,x2/4,s3,x15/11,pl/e,x4/6,s8,x2/5,pi/j,s15,x7/15,s6,x4/13,s15,pc/f,x8/14,s13,x4/3,s5,x15/8,s7,x7/2,s5,x6/4,s7,x2/13,s4,x7/11,s1,x13/12,s6,pi/k,x6/15,s3,x3/2,pf/j,s13,x15/11,pm/g,s15,pp/b,x2/12,s2,x0/8,ph/f,x9/3,pe/d,x1/2,pf/n,x5/10,s3,x6/12,s2,x3/10,pm/k,x11/15,s1,x9/12,s5,pp/b,s3,x8/3,pl/n,x4/2,pi/o,x8/11,pf/k,x6/4,pa/j,x8/5,pc/h,s12,x3/1,s2,x7/14,s10,x0/4,pb/e,x9/5,po/c,x3/7,s8,x6/5,pk/g,x9/7,s15,x11/0,s3,x1/12,pb/o,x11/6,s7,x15/8,s3,x6/11,s15,x13/10,pk/a,x2/8,s13,x15/3,pi/c,x13/1,s11,x10/8,pg/m,x1/4,pj/c,x2/8,s13,x12/0,s3,x15/5,s3,x3/10,pf/a,x7/8,s7,x12/13,s8,x10/2,s1,x12/14,s2,x8/6,s2,x13/12,s13,x11/14,pj/m,x5/8,s5,x4/6,pd/f,x12/11,pj/p,x4/2,pf/c,x5/14,s11,x7/6,pj/i,x12/13,s11,x3/5,pm/o,x13/7,s4,x14/9,s10,x4/13,pf/e,x9/10,pn/c,x0/6,s3,x1/2,pi/p,x6/14,pa/k,x5/10,pl/h,s4,x11/13,pn/k,x9/7,s4,x11/4,s8,x14/9,ph/l,x2/0,s7,x11/4,pi/c,s2,x3/2,pm/g,x6/15,s8,x12/3,s6,x0/7,s15,x1/2,s12,x9/13,pa/c,x4/1,pp/l,x12/7,s14,x2/14,s11,x4/1,s6,pm/f,x12/13,s9,x9/8,pa/j,x11/3,pk/e,s15,pp/o,x6/7,pg/e,x8/13,s7,pm/n,x10/15,s4,x7/5,s6,x10/13,pb/o,x5/0,pk/m,x4/8,pj/l,x6/12,s4,x5/9,s7,x11/3,s7,x5/9,s7,x8/3,s13,x4/2,s1,x7/8,pm/n,x3/14,s15,x13/15,s13,x8/2,s7,x4/11,s15,x5/2,s4,x14/9,pd/c,s2,x13/11,pf/e,s13,x8/2,s11,x10/6,pi/m,x11/13,pa/h,x9/12,pk/p,x6/0,pn/l,x4/12,s12,x7/2,pc/a,x13/5,ph/n,x15/7,pb/k,x13/11,s2,pp/m,x3/1,pn/f,x10/7,s3,x12/3,s14,x7/15,pg/o,x2/8,s12,x11/6,pk/f,s2,x4/2,pb/g,x13/5,s12,x11/6,s2,x3/9,s1,ph/k,x11/14,s6,x15/10,po/m,x3/7,s3,x9/5,s15,x13/1,ph/l,x4/0,pi/j,x10/9,s13,x0/3,pm/a,x14/9,s7,x11/0,s8,x14/2,s1,x4/6,pi/j,s12,x3/9,ph/b,x0/7,pg/n,x2/1,s6,x5/15,s7,x12/9,pk/b,x8/7,pa/i,x6/10,pg/j,x3/5,pk/i,x10/15,pc/d,x6/13,pk/i,s5,x2/9,pl/e,x15/14,s7,x13/1,s13,x15/12,s11,x7/1,s6,pc/g,x3/10,pd/p,x9/7,pb/k,x14/4,pf/c,x0/11,s6,x1/5,s6,x2/9,pn/e,s9,x15/6,po/i,x7/5,s10,x0/11,pc/k,x10/13,ph/l,x1/0,s13,x10/12,s9,x3/11,pf/o,x1/14,pj/h,x4/15,s1,x6/1,s4,x3/4,s2,x10/8,pd/n,x9/13,pk/a,s4,x6/12,s8,x1/0,s10,x15/5,pc/d,x8/10,pn/i,s4,x1/2,pc/h,s6,pe/m,x8/12,s5,x0/2,pi/j,s6,x8/1,s10,x9/2,s9,x11/15,s12,x9/5,pg/e,x1/12,s10,x14/3,pk/i,x9/8,s8,x1/14,pm/e,x9/3,s8,x8/15,s10,x7/14,pf/j,s9,x13/2,s9,x0/10,s13,x8/7,s6,x12/0,s5,x5/4,pl/b,x1/12,s15,x2/0,pc/o,x5/4,s12,x7/15,pj/p,x3/9,s12,x4/12,s3,x2/5,s13,x6/13,s14,x12/3,pg/l,x5/10,s7,x8/3,pp/m,x15/12,s2,x4/9,s2,x15/2,pa/i,x0/14,s6,x9/4,s2,x10/1,s2,x11/8,s6,x0/6,s5,x13/9,pd/k,x10/1,s2,x4/2,s15,x14/15,pg/p,x11/4,ph/b,x6/1,s12,x7/13,s1,x5/6,pg/k,x1/3,pn/e,x7/12,pl/a,x1/14,s10,x2/15,s10,x12/11,s5,x15/9,s4,x5/14,s9,x15/11,pj/h,x7/1,pd/a,x11/8,s5,x10/6,s7,ph/b,x5/11,s9,x6/13,s15,x11/10,pe/k,x2/13,s1,x6/14,pl/b,x8/3,po/k,x2/13,s7,x5/15,pn/c,x10/8,s5,x3/4,pf/a,x5/13,pj/c,x4/3,pa/n,s1,x8/13,s5,x10/4,ph/m,x14/8,pc/l,x11/12,pi/d,x0/8,s5,x1/11,s2,pm/j,x8/10,s12,x12/1,pn/p,x7/5,s12,x12/15,s6,x14/4,s4,x3/0,s14,po/a,x8/6,s10,pb/m,x12/7,s9,x5/8,pj/p,s15,x3/13,pd/g,x2/11,pn/m,x4/1,pj/g,x12/9,pp/i,x11/5,s1,x6/3,s13,x11/9,po/d,x13/1,ph/n,x2/0,po/d,x11/4,s3,x2/14,pa/h,x13/0,s2,x9/3,po/g,s13,x12/4,s15,x15/1,pl/b,x0/7,pm/a,x10/1,po/i,x12/2,s10,x9/13,pa/b,x5/0,pg/j,x15/1,s14,x8/9,s3,x6/7,s15,x11/4,s9,x15/5,s15,x7/11,s10,x5/13,pi/k,x10/2,pm/a,s9,x4/15,pe/b,x11/9,s6,x14/4,s7,x5/2,s15,x0/9,pf/p,s4,x1/6,s5,x0/4,s12,x11/10,s4,x3/15,pi/n,s4,x8/7,s4,x5/0,pp/f,x1/12,s1,x5/7,pm/a,x8/14,s9,x3/10,s7,x13/15,pg/i,x1/9,po/h,x12/4,pc/k,x11/0,s2,x10/2,s15,x4/6,pp/h,x2/11,s7,x5/1,pn/k,x11/15,pl/o,x2/1,pm/a,x0/9,s10,pj/h,x2/1,pi/m,x5/11,s5,x13/0,pe/j,x5/1,s14,x3/9,s2,x12/6,s13,x0/4,s15,x13/7,s11,x12/0,s6,x5/10,pd/a,x9/12,pi/l,x1/7,s7,x13/14,s9,x8/11,s6,x7/5,s4,pn/h,s15,x8/12,pg/i,s1,x10/9,s13,x1/7,s3,x11/6,pa/o,x4/5,s4,pg/m,x14/0,ph/p,s8,x7/6,s7,x8/2,s14,x14/10,pf/c,x4/8,s12,x6/0,s12,x3/9,pb/a,x7/15,s14,x14/2,s1,x1/4,pf/e,x13/10,pk/h,x7/3,s2,x1/8,s5,x6/11,s6,x14/7,pc/d,x0/9,pk/n,x15/8,pi/e,x10/14,pl/j,x15/8,s12,x9/13,pi/f,x0/11,s10,x15/6,s13,pd/k,s2,x0/7,s4,x8/3,pm/i,x15/2,s15,pd/e,s5,x13/14,s6,x15/10,pa/j,x2/12,pp/m,x0/8,s13,x6/4,s3,x15/11,pg/n,x10/8,pj/h,x0/4,s3,x5/8,s9,x1/7,s15,x12/13,pg/n,x14/15,s8,x2/1,s5,x10/12,s15,x4/14,pb/d,x7/10,s13,x15/11,s7,x1/5,s10,x3/15,s2,x2/14,s6,pj/l,x13/10,pk/a,x3/15,s7,x0/8,pl/f,x14/6,s7,x15/4,s10,x0/8,pi/n,s1,x4/9,s12,x8/12,s6,x15/1,s6,x13/12,ph/p,s2,x11/14,pa/c,x7/10,s7,x9/12,s12,x8/4,s15,x2/6,s3,x15/14,s15,x13/0,pp/o,x7/4,pj/g,x9/13,pc/f,x7/10,pm/b,s5,x4/14,s3,x11/9,pl/e,x10/2,s10,x7/8,s8,x5/14,s13,x15/1,pf/n,x2/12,s4,ph/k,x8/13,pc/a,x7/12,s2,x0/4,s8,pd/l,x5/2,s13,x3/10,pa/o,x2/0,s6,x5/13,pc/f,x8/14,s13,x3/12,pn/m,s2,x0/13,s12,x15/11,pl/h,x9/4,pn/o,x5/13,s15,pb/j,x9/7,s7,x14/8,s2,x5/6,pg/l,x13/7,s3,x11/8,s9,x7/14,pn/i,x8/5,s13,x1/15,pg/m,x2/0,s2,x3/6,s7,x5/15,pl/n,s15,ph/e,x14/1,po/k,x3/2,pl/p,x0/4,pi/h,x10/1,pf/b,x15/9,pm/k,x12/2,s9,x1/7,s4,x13/15,pl/h,x14/12,pf/a,x5/10,s1,x1/11,s10,x3/4,s14,x5/11,s7,x9/6,ph/i,x0/10,pl/p,x15/3,s11,pe/n,x0/5,pj/i,x4/3,s15,x15/11,s5,ph/e,x4/12,s13,x6/14,s12,x1/12,s4,x6/13,s14,pg/n,x2/5,s6,x1/11,s1,x5/3,s8,x2/15,s14,pe/l,s10,x13/0,pp/o,x10/5,pe/a,x15/2,pg/h,x5/1,s9,x10/7,s9,x5/3,pb/o,x13/12,s5,pn/k,x4/1,s13,po/l,x11/8,pd/f,x6/4,s11,x8/15,pp/o,x1/10,s1,x14/12,s1,x9/8,pa/f,x14/13,s11,x6/5,pc/i,s6,x12/13,s5,x0/9,pa/d,s12,x14/1,s5,x7/6,pf/j,x15/11,s3,x10/13,s6,x11/2,pe/k,x8/6,s3,pf/l,x3/13,pb/c,s8,x8/9,pm/i,x1/14,s10,x2/9,s9,x1/15,s2,x0/10,s11,x2/15,s9,x14/12,pj/c,x9/1,s6,x11/12,pe/a,s13,po/h,x13/10,s12,x14/5,s7,x13/0,pk/e,x5/3,s7,x10/15,s2,x2/0,s4,x4/12,s2,x8/0,pa/g,x2/5,s7,x11/1,pp/j,x5/14,pn/g,x1/12,s12,x15/7,pa/p,x11/1,pj/d,x2/14,pa/h,x9/6,pj/p,x3/10,ph/o,s14,x8/12,s13,pi/c,x1/6,s6,x8/15,pb/p,x10/6,s9,x8/5,s7,pa/c,s15,x9/0,s2,x12/15,pg/n,x14/8,pe/l,x13/4,s8,x2/10,s6,x11/0,s3,x6/12,pm/f,x2/4,s15,x0/5,s11,x15/7,s9,x14/8,pc/n,x4/11,s4,x15/0,pm/p,x10/6,s3,x7/3,s5,x1/15,pn/l,x0/6,s12,x2/10,pe/o,s6,x12/8,s12,pj/d,x14/9,s14,x11/0,po/i,x8/13,pd/e,x14/2,pc/p,x12/1,ph/j,x11/13,s7,x8/12,s12,x2/3,s11,x14/11,s11,pk/e,x13/1,ph/p,x10/4,pd/j,s12,x1/7,s9,x10/15,s4,x12/4,ph/i,x1/14,s8,x2/4,s3,x9/5,s5,x0/12,s13,x13/10,pa/k,x4/0,pd/b,x3/9,pa/i,x0/13,pp/m,x2/12,s1,x8/0,pg/j,x3/14,s13,x2/6,s10,x10/13,pd/i,x15/4,po/m,x10/13,s9,x7/11,ph/n,s1,x15/3,pk/i,x1/9,s10,x2/4,s13,x11/5,pj/p,x2/9,s9,x0/10,s15,x9/1,s15,x13/5,s3,x15/11,s11,x9/6,s1,x3/8,pf/e,x5/2,pn/c,x12/3,s4,x9/13,po/i,x3/14,pc/e,x15/7,pk/j,s15,x0/12,s7,pe/a,x6/10,pm/j,x9/1,s14,x2/8,pc/g,x9/5,pd/j,s14,x10/14,s12,x5/7,po/f,x8/10,s9,x14/6,s4,x15/4,s10,x6/9,s2,x7/10,s2,x4/8,pb/e,x14/9,pn/f,x5/7,s10,pa/p,x9/12,s8,x7/15,pg/e,x5/6,pm/f,x0/11,pd/e,x8/13,pn/p,x6/11,s8,x7/9,s3,x13/8,pk/j,s4,x7/5,s13,x8/3,pd/c,x7/5,pm/i,s12,x13/12,s15,x9/8,s14,x6/5,s10,x1/12,s1,x13/7,s4,x4/1,pg/n,s15,x8/15,pi/l,x14/10,pd/h,x6/1,pk/c,s3,x11/14,po/h,x6/1,pd/m,x13/9,pj/b,x14/8,pe/h,x3/1,po/d,x15/9,ph/f,x11/8,pk/n,x6/3,s7,x14/7,pp/c,x3/5,s3,x4/7,pm/n,x2/11,s15,x12/4,s12,x15/3,s15,pp/a,x9/4,s5,pn/h,x13/8,s12,x1/0,s13,x6/5,pg/p,x1/13,s6,pm/f,x11/15,s2,x2/12,s10,x11/9,pp/i,x15/6,pl/a,x7/10,s1,x4/3,s3,x5/12,s7,x4/11,s11,x14/5,s9,pd/p,x10/13,pk/j,s3,pd/e,s1,x2/15,pc/j,x1/12,s8,x13/11,pg/b,x9/0,po/p,x1/11,s3,x6/15,s8,ph/l,x10/3,s2,pg/e,s3,x4/8,pa/d,x15/14,s15,x12/11,s1,x8/15,s7,x6/5,pb/p,x0/10,s6,x15/14,pa/d,x9/2,pi/e,x11/14,s6,x5/12,s15,x1/15,s15,x3/9,pa/b,x11/8,pc/l,x4/2,s8,x10/13,s1,x12/6,po/m,x9/7,s14,x14/2,s14,x4/8,pk/a,x5/2,s8,x12/3,s15,x5/1,pe/n,x6/10,pd/j,x14/7,s8,x15/12,po/p,x3/8,s13,x0/1,s3,x5/13,pf/m,s13,x14/1,pl/i,s11,x10/5,pp/c,s4,x1/12,s14,x3/15,pk/g,x10/13,pc/a,x6/8,pe/k,x0/12,s11,x15/1,s7,x11/13,s10,x3/5,s3,x8/2,s10,x1/9,s6,x3/6,s12,x9/1,s14,x2/6,pn/h,x10/7,pe/g,x0/12,pf/i,x2/9,s14,x15/5,s13,x12/9,s2,x2/4,pd/e,x13/1,pj/i,x0/6,s2,x2/9,pk/p,x11/8,s12,x9/0,s13,x1/7,s12,pg/m,x9/6,s6,x13/10,pn/k,x3/15,pg/f,x14/5,s15,x2/10,pc/h,x14/15,pj/p,x0/10,s15,x3/4,pc/o,s9,x8/15,pa/b,x2/11,s4,x8/12,s1,x3/2,po/k,x0/5,s15,x2/7,pc/p,x15/13,pe/n,x0/10,s13,pj/d,x11/1,s7,pl/k,s12,x13/15,pp/j,x2/14,s2,x0/10,pf/b,x11/4,s5,x7/0,s14,x6/1,s6,x14/10,s6,x0/11,s7,pl/a,x14/10,po/f,x3/1,pc/j,x5/10,pp/g,x15/0,pd/i,x5/14,pa/c,x11/2,s8,x6/14,s3,x11/9,s6,x10/3,s1,x2/13,s15,x14/11,s4,x0/13,pg/n,s8,x7/3,s12,pp/j,x5/15,pg/d,x4/10,s12,x15/12,s14,x2/8,pc/a,x1/4,s1,x7/5,s3,pe/h,x14/2,pj/d,x4/5,pn/b,s12,x1/12,s9,x4/15,s3,x3/5,s10,x9/8,pm/p,x3/4,pa/e,s12,x15/9,s15,x14/5,pj/f,x12/8,s7,pn/e,x3/5,s10,x9/6,pm/b,x4/10,s2,x3/2,s15,x1/0,s11,x5/9,s13,x15/7,s11,po/g,s8,x10/4,s14,x15/13,s12,x5/10,s4,x14/1,s3,x2/13,s10,x15/9,s9,x13/6,s10,x14/15,pf/d,x11/9,s3,x1/7,pi/g,x15/11,s7,x0/1,pm/h,x3/8,s8,x7/10,pd/k,x8/14,pe/m,x13/11,pi/f,x4/6,pa/b,x15/10,pp/c,x0/8,s4,x12/3,s15,x4/5,s2,x9/7,pb/h,x1/12,s3,x5/15,s10,x3/10,pp/i,x4/15,pn/j,x13/5,s6,x3/15,s6,x0/9,s5,x7/1,pl/k,x12/15,s15,x13/6,s5,x9/12,s12,pe/a,s3,x10/2,s8,x4/15,s15,x7/6,s2,x2/15,po/g,x10/4,s12,x3/13,s8,x1/0,s15,x2/4,pl/e,x12/15,s9,x7/8,pb/m,x5/13,s1,x8/2,s9,x13/3,s1,x7/0,pi/a,s5,x14/8,s2,x2/13,ph/e,s1,x9/8,pj/k,x3/6,s1,x14/10,pa/f,x2/15,s14,x1/11,pk/i,x2/9,s6,x8/0,ph/d,x4/14,s3,x2/10,s4,x12/0,pg/b,x9/15,s11,pk/i,x5/3,s4,x7/6,pl/p,x2/0,s3,x11/14,s8,x12/8,pf/k,x11/7,s14,x9/4,s4,x14/15,pa/h,x1/3,pn/f,s12,x2/13,s8,x7/14,pk/m,x0/2,pl/j,x11/3,s15,x8/6,s8,x12/0,s5,x8/10,pm/h,s7,x3/11,s15,x1/13,s10,x5/8,s3,x7/6,s15,x5/4,pg/o,x11/7,pi/l,x12/0,s7,x4/14,pj/d,x8/13,pg/b,x7/0,pm/d,x9/8,pk/i,x3/5,pn/d,x2/12,s5,po/h,x5/4,pm/k,x15/2,s2,x9/11,s1,x3/15,s8,x2/8,pn/j,x1/10,pl/g,x0/13,pj/o,x11/5,s7,x0/13,s8,x7/1,pg/e,x9/11,s12,x0/8,pn/h,x10/3,s1,x8/1,s5,x6/11,s10,x7/9,pf/k,s15,x1/0,pg/e,x3/7,s3,x13/4,s11,x10/12,s11,pa/i,s14,x1/8,s12,x0/14,pk/d,x7/2,pn/p,x11/4,s12,x6/2,pd/a,x11/15,po/f,x6/0,s14,x7/10,pk/p,s15,x13/15,s6,x4/8,s13,x14/10,s13,x4/2,s7,pd/g,x6/1,s4,x7/2,s2,x0/1,pc/h,x12/2,pf/n,x11/15,s5,pa/p,x8/9,s14,x4/10,pi/o,x5/6,s10,x14/1,s8,x12/4,s8,pg/c,x10/2,s11,x13/6,s12,x2/14,s13,x12/1,s6,x4/13,po/p,x1/5,pe/a,x7/9,s5,x8/2,s3,x11/7,s8,x6/5,pj/g,x15/8,pl/d,x6/0,pn/f,x13/2,pa/m,x4/11,ph/p,x15/9,pj/i,x2/6,pg/f,x7/11,s5,x10/1,pa/l,s11,x13/2,s3,ph/g,x14/15,pe/a,s12,x9/4,s7,x14/10,s3,x9/7,pi/l,x6/0,pk/f,x2/1,s6,x0/14,s9,x13/4,pa/i,x9/8,pk/l,x6/1,s1,x7/3,s11,x1/2,s4,x6/7,pe/p,x3/10,pk/j,x6/9,s9,x7/5,pc/f,x6/13,pp/h,x12/3,s9,x7/14,pi/k,x5/10,s13,x2/15,s6,x3/10,pp/n,x1/9,s3,x2/10,s14,x8/12,s12,x0/6,s6,x10/4,s1,x5/3,s12,x10/0,s13,x11/7,pj/c,x12/4,pb/a,x1/2,s10,x10/11,s13,x4/9,po/l,x1/0,s9,pn/m,x3/4,s7,x12/5,pk/p,x0/2,s15,x10/3,s13,x11/7,pa/d,s3,x12/0,s11,x14/6,s14,pm/i,s9,x0/7,pk/b,s10,x4/2,s10,x6/9,s12,x5/7,s6,x10/15,pc/l,x2/0,pg/f,s5,pp/l,x10/7,s11,x6/15,s9,x4/0,pg/d,x5/3,pm/i,x2/7,s15,x4/1,pk/j,x11/8,po/p,s11,x0/6,s3,x15/13,s6,x7/8,pf/k,s5,x1/15,s6,x5/6,s1,pj/p,s5,x13/9,s14,x5/3,s5,x12/2,pm/l,x14/15,pd/j,x6/9,pg/i,x7/5,s1,x11/12,ph/k,x1/9,s3,x6/14,s9,x4/7,pn/a,x14/13,s7,x0/4,pd/l,x2/7,pa/i,x3/11,s8,x0/13,s2,x5/6,pj/k,x13/7,s4,x11/9,s10,x7/5,s14,x6/10,s4,x8/11,s2,x5/13,pg/m,x8/10,s6,x5/7,s12,x9/15,pp/d,x12/4,s2,x0/6,pl/o,x4/11,pg/i,x8/13,s11,x1/9,s5,x3/5,s5,x11/4,s6,x12/6,pc/h,x14/11,pe/n,x8/12,s11,x4/3,s4,x14/8,pp/b,s7,x1/2,pk/g,x4/13,s9,x11/9,s14,x15/0,pp/b,x5/14,s6,x1/7,pg/n,s10,x12/3,pi/a,x15/10,pj/p,x2/1,s1,x0/13,s15,pc/g,x1/14,s3,x11/5,pp/l,x15/9,s2,x10/0,s9,pi/a,x6/8,s15,pb/e,s6,x14/10,pm/k,x5/12,pd/l,x14/3,s5,x13/10,s8,x15/14,s7,x10/9,s2,x3/1,s7,x9/12,pn/b,x5/13,s6,pf/m,x0/11,pl/j,x14/7,pk/g,x12/13,pm/f,s15,x3/1,s11,x14/6,pd/k,x5/13,pm/a,x0/14,pn/l,x7/4,pf/b,s11,pl/g,x3/5,s10,x8/12,s8,x4/13,s8,x7/6,po/f,x8/13,s1,x1/2,s12,x3/4,pa/e,x6/2,s1,x15/5,s14,x2/1,pb/f,x10/5,pl/p,x12/15,pe/o,x8/9,s10,x2/6,pj/m,s6,x1/8,s13,pe/l,x13/12,s12,x10/14,s13,x11/15,s3,x12/6,pb/a,x0/5,s9,x14/12,s3,x2/0,po/l,x15/3,s15,x10/14,pj/d,x4/5,s4,x7/14,pp/l,x4/8,ph/n,s7,pa/m,x3/2,s13,x5/13,s2,x12/0,s7,x3/7,s2,x6/12,pl/n,x3/7,pp/c,x15/5,s15,x11/13,s5,x0/7,s8,x4/11,pm/f,s15,x5/2,pi/e,x8/7,po/a,x10/3,pl/d,x11/8,s13,pn/k,x15/14,s5,pa/b,s9,x9/1,pg/l,x12/13,s3,x0/14,s15,pi/f,x3/7,pk/h,x10/12,pn/j,x0/7,s13,x12/4,s4,x6/8,s8,x9/11,s9,x0/7,s7,x12/3,po/l,s10,x7/11,s7,pi/j,x5/8,s8,x11/13,s7,x5/8,pp/b,s11,x9/11,s3,x15/5,pa/j,x0/10,s9,x7/8,s15,x9/11,s14,x7/13,pc/k,x12/15,s4,x5/3,s9,x6/9,s14,x15/1,pj/m,x9/8,s10,x14/5,s10,x10/13,s3,x12/9,s9,x1/0,pa/f,x3/10,pn/g,x4/1,pc/e,s4,x2/6,s7,x10/4,pj/k,x5/13,s6,x2/1,s15,x11/8,pn/o,x2/10,s13,x4/11,pf/c,x7/3,pm/n,x8/10,pc/e,s14,x0/7,pn/p,s5,x15/10,pe/j,x12/8,s8,x1/3,s7,x0/4,s7,x10/6,ph/a,x3/13,s7,x9/4,s9,x7/3,pb/k,s14,x2/11,s2,x0/5,s6,x8/14,s5,x4/15,pp/g,x1/3,s7,x10/5,pd/n,x7/4,s10,x15/11,pe/i,s6,x3/5,s3,x1/9,pn/p,x3/11,pg/c,x5/8,pf/b,s10,pl/k,x6/2,pa/i,x13/7,pn/m,s15,x10/0,s15,x3/13,pl/o,x5/14,s10,x6/7,s5,x14/4,s2,x6/13,s10,x3/0,s15,x9/7,pp/g,x2/8,pj/a,x3/6,pl/b,x9/5,pa/j,x14/3,s11,x2/5,pp/l,x14/9,s4,x13/10,s15,x6/5,s10,x13/10,s9,x6/8,pj/f,x14/15,s9,x10/0,pm/c,x13/14,pd/p,x4/1,s14,x6/12,s7,x11/9,s10,x7/0,s1,x13/3,s4,x0/7,s13,pf/b,x12/2,pd/l,x11/8,s13,x7/0,pm/o,x12/4,pe/l,x6/0,s8,x5/4,pm/n,x6/2,s3,x0/10,pi/a,x2/5,pj/p,x13/8,s11,x4/3,po/m,x6/5,s5,x3/13,pk/i,x6/8,s10,x5/11,s2,x10/4,s15,x11/2,s9,x7/6,s8,x5/10,pm/g,x11/15,pk/b,s7,x4/5,s6,x14/7,po/a,x1/11,pj/h,x14/13,pl/a,x2/4,pi/e,s6,x13/11,pa/m,x1/5,s13,x11/8,s15,x4/0,pl/o,x1/3,s14,x4/10,s2,x13/1,s1,x14/12,s12,x9/1,s12,x2/8,s2,x7/9,pm/b,x4/13,s4,x6/11,s13,x3/8,s13,x5/9,pd/k,x6/0,s15,x3/10,pi/c,x7/11,s6,x14/5,s15,x9/7,s11,x14/13,s14,x1/4,s6,x2/12,pn/b,s10,x9/15,pc/o,s11,x5/8,ph/m,x15/10,pg/a,x4/1,pd/e,s14,x14/9,s14,x13/8,ph/j,x9/2,pd/o,x0/3,pl/e,x4/9,s4,x12/1,s6,x10/7,s8,pj/f,x3/13,pb/l,x2/7,pg/a,x11/0,s10,x14/5,pn/c,x13/9,s10,x14/6,pg/k,x0/3,pl/b,x7/14,s13,x13/11,pg/o,s2,x1/2,s7,x8/13,pd/h,x12/4,pg/f,x8/13,ph/o,x5/15,pg/p,x0/10,s6,x4/6,s3,x1/0,s4,x13/8,s7,x5/0,s11,x15/4,pa/n,x7/14,s10,x10/13,pg/l,x8/1,s2,x6/10,ph/n,s13,x14/8,s12,x9/13,s6,x10/1,pk/d,s6,x14/11,pa/i,x5/9,s2,x1/6,s14,x2/8,po/c,x5/4,pi/m,x7/11,s11,x2/13,s3,pd/o,x1/9,s5,x0/8,ph/n,x7/6,pk/i,x11/3,s10,pp/o,x15/0,s8,x14/10,s2,x5/7,s6,x14/0,pj/e,x9/12,s7,x3/13,s7,x11/1,s8,x10/3,pl/k,x4/1,s12,x12/14,pj/c,x0/7,pf/e,x4/6,s7,x12/7,pm/h,x14/1,pb/p,x2/11,pc/i,x6/3,s6,x0/13,s12,x7/2,pb/l,x1/14,s5,x11/5,s11,x4/10,pn/c,x15/1,s2,x6/12,s8,x13/7,pk/j,s8,x3/11,s4,x8/1,s6,x13/7,pi/d,s8,x8/11,s15,pk/c,x2/14,ph/a,x9/13,s14,x2/7,pl/e,x5/8,pj/c,s3,x7/6,s14,x2/11,pk/p,x12/15,po/i,x11/2,s1,x10/14,pl/c,x7/1,s9,x9/2,s13,x11/14,pe/m,x8/2,s13,x3/12,s14,x13/2,pn/o,s7,x1/11,s13,pc/e,x3/14,pb/n,x13/5,ph/k,x2/8,s2,x1/10,s5,x11/8,s8,x7/6,pm/g,x0/2,s9,x5/3,s3,x2/0,s2,x9/1,pn/k,x10/14,pl/o,x11/7,s10,x3/0,s11,x15/6,s13,x12/10,pa/j,x2/9,pn/b,x7/4,s14,x2/11,pi/a,x8/4,s14,x6/14,s12,x9/3,pk/b,x14/4,s13,x1/12,pn/e,x10/8,s10,x11/5,s14,x6/7,s3,x15/14,pm/i,x12/0,pl/g,x6/13,pi/n,s14,pf/g,x7/11,pk/a,x8/15,s9,pj/n,x1/10,s12,x14/6,s7,pf/p,x0/10,s12,x11/1,s7,x15/6,s11,x13/3,s12,pb/c,x1/5,s1,x6/9,s4,x11/1,pf/j,s11,x10/7,pi/b,s14,x9/13,s12,x15/6,s11,x4/5,s5,x10/14,s9,x0/15,pd/e,x8/5,s7,x9/14,pf/c,x0/10,pm/e,x11/15,ph/i,x1/5,s13,x3/0,pg/a,x1/8,s1,x11/12,pj/h,x14/15,pd/b,x13/2,pe/m,x0/11,s11,x8/3,s4,x13/6,pn/f,x7/12,s3,x2/11,s13,x8/15,s7,x6/9,s5,x12/7,pa/i,x1/9,s9,x11/13,pp/f,x3/1,po/j,x10/4,s8,x13/9,pi/k,x11/5,pm/p,s3,x7/14,pg/j,x5/10,pe/d,x7/14,po/g,x5/8,s1,pe/f,s10,pl/d,x12/3,s1,x11/8,s12,x12/5,s9,x14/1,pg/h,x3/5,s5,x14/11,s7,pf/b,x7/4,s7,x15/0,s12,x14/13,pn/d,x10/4,pk/h,x11/14,s11,x13/15,s11,x6/4,s4,x11/3,s14,x0/1,s11,x6/7,pj/a,x0/4,s4,x10/2,pf/c,s5,x6/13,pm/a,x4/8,s7,x1/6,s6,x13/0,s4,x6/14,s8,x9/0,s1,x1/8,s4,pk/g,x9/6,s12,x15/13,pd/j,x2/7,pp/c,x0/9,pe/a,x15/11,pb/l,x3/13,s8,x8/0,s13,x11/2,pn/h,x10/9,pb/l,x1/11,s1,x14/2,pg/i,s13,x12/3,s4,x9/13,s12,x11/15,s3,x3/6,pa/l,x11/9,pf/g,x2/6,pi/k,x3/4,po/m,x1/6,s10,x9/13,s3,x0/1,pb/l,x12/10,pm/e,x14/0,s3,x4/6,pk/n,x10/5,pa/d,x0/2,s14,pe/f,s12,x13/11,pm/k,s12,x9/14,s8,x12/13,s3,x15/2,s13,x0/3,s1,x13/4,s3,x1/14,s7,x6/8,s3,x11/2,pg/p,x12/4,pe/f,x14/8,s14,x13/1,s4,x11/15,s4,x13/7,s15,pl/o,x10/12,pm/n,x4/5,s8,x13/14,pe/g,x10/1,s5,x7/12,s11,x4/3,s11,x7/0,pf/k,x14/13,pe/a,x9/10,pl/n,x11/6,pk/p,x2/7,s2,pe/a,x11/4,pi/j,x9/1,s6,x4/6,s3,x10/0,pl/p,x5/8,s9,x1/13,pk/o,x12/3,s9,x2/6,pi/l,x5/1,s10,x2/11,pk/a,x6/14,s14,x8/4,pc/f,x10/13,s8,x15/5,pd/o,x7/0,pe/a,x8/1,pi/p,x14/0,pj/l,x1/2,pc/a,x9/3,s3,x2/8,po/j,x12/3,s1,x7/13,s11,x0/8,s7,x3/13,s3,x14/2,pf/h,x1/4,pa/k,x5/0,pf/h,x4/6,s7,x2/14,s9,x9/8,pe/a,x3/12,pk/i,x0/4,pn/a,x7/8,po/h,x10/12,s9,pf/d,x7/15,pl/e,x2/1,pd/c,x15/13,pi/h,s6,x0/1,s7,x3/8,s12,x2/15,pg/d,x1/8,s2,x6/11,pc/a,x3/10,s2,x5/8,s15,pp/i,x11/2,s10,x0/5,s7,x14/4,s8,x8/13,ph/j,x9/5,pm/l,x11/13,s15,x1/5,pa/i,s10,x8/6,s7,x4/3,s14,x15/7,s8,x13/5,s1,x9/1,s9,x11/7,pj/e,x15/9,ph/c,x1/11,pd/f,x2/12,ph/k,x11/6,pm/n,x1/3,s1,x15/14,s3,x4/8,s1,x11/6,s4,x7/14,s7,x0/11,pa/b,x1/14,pc/n,x7/8,s12,x13/0,s6,x12/15,pm/h,s3,x7/1,pj/k,x0/11,s4,pi/g,x9/10,pp/l,x14/3,s1,x11/8,pa/f,x14/1,pb/m,x5/10,pd/h,x2/6,pl/e,x15/14,s10,x2/0,s7,x10/5,s11,x6/4,s2,x10/9,pf/a,x4/5,po/n,x11/7,pf/m,s5,x4/2,s7,x11/10,pa/p,x7/13,s13,x9/6,pe/i,x10/2,s15,x5/9,s13,x10/2,s9,x12/6,po/n,x1/2,s3,x10/6,pp/i,x2/14,s15,x4/8,pd/g,x14/11,s14,x8/3,pk/n,x7/1,s15,x2/10,s9,x15/7,s12,x8/12,pe/a,x7/15,pd/h,s9,x13/9,s14,x8/11,s9,x2/4,pb/e,x1/15,ph/f,x6/8,s14,x4/3,pb/p,s6,x9/12,s4,x3/1,s13,x10/5,s2,x9/6,s3,x14/7,s6,x6/5,s5,x3/8,s8,x10/15,pa/g,x1/8,s15,x11/15,s4,x2/0,s15,x14/15,pi/n,s6,x1/2,s11,pk/c,x7/0,s4,x14/6,s5,x7/1,po/a,x15/2,s15,x7/4,pk/g,x0/11,s4,x10/9,s14,x7/0,pd/i,x9/14,s3,pj/o,x1/12,s11,x5/3,s10,x9/11,s9,x2/12,pk/m,x8/7,s7,x6/13,s14,x5/4,s14,x12/2,s13,x9/5,ph/g,x14/12,s5,x1/3,pn/i,s2,x13/7,pg/p,x9/3,s2,x2/13,s11,x3/1,pa/f,x6/8,s8,x12/2,pb/m,x5/4,s2,x8/11,pf/d,x7/15,po/k,x2/5,ph/i,x9/0,pb/k,x13/15,s2,x9/8,ph/n,x4/5,pp/b,x15/11,pf/e,x6/4,s12,x11/15,s11,x1/7,s14,x2/3,s7,ph/o,x9/4,s8,x7/6,s9,x4/11,pa/f,x9/10,pj/g,x2/0,s14,pb/l,s10,x15/11,s5,x3/6,s3,x9/1,pa/d,x12/4,pi/h,s14,x9/3,pa/n,x2/12,pp/e,x14/4,s13,x12/10,s4,x3/5,s14,x7/0,pm/c,x4/2,pe/f,s5,x10/7,s2,x5/3,s8,pl/i,x0/4,pg/c,x13/10,s11,x1/12,s9,x7/3,s5,po/f,x1/12,pa/h,x9/0,s11,x6/10,s15,x7/5,s13,x11/4,pg/i,x13/7,s3,x3/15,pn/m,x11/2,s6,x15/10,pb/k,x1/4,s10,x10/6,s10,x15/3,pm/h,x0/12,s14,x5/10,s3,x7/8,pk/f,x11/10,pi/e,x8/13,s9,x2/12,s12,x14/3,s15,x9/8,s7,x5/11,s1,x9/15,pg/m,x11/0,s15,x14/7,s14,x2/12,s12,x9/6,s13,pb/f,s1,x7/13,s13,x12/3,pm/k,s4,pp/a,x1/10,s12,x11/2,pn/o,x6/7,s11,x11/5,s15,x12/9,s15,x3/10,s1,x7/6,pk/p,x14/12,pm/n,x0/5,pl/c,s7,x14/12,pa/n,x10/15,s14,x4/12,s12,x6/1,s14,x8/12,pp/b,x0/7,pl/g,x5/8,pb/o,x14/7,s2,x3/4,s2,x14/1,s7,x4/8,s3,x1/10,s5,x3/4,pe/a,x13/14,s13,x3/9,s13,x10/2,s14,x13/0,pl/n,x9/15,pj/e,x5/13,po/d,x15/3,s13,x5/13,pi/g,x10/3,ph/f,x8/11,s13,x1/6,s1,x0/12,pg/d,s6,x10/8,pf/k,x5/7,pa/j,x2/0,pm/o,x5/13,s5,x15/11,s5,x4/6,s5,x10/12,s2,pn/f,x13/4,s13,x9/3,pc/d,x2/10,s1,pk/i,x9/1,s9,x10/12,s15,x5/4,pg/o,x9/6,pc/h,x11/14,pb/n,x5/3,s15,x4/13,s10,x10/8,s11,x7/5,s13,x12/10,pe/j,x6/8,pm/k,x11/10,s15,x15/6,s12,x11/2,s1,x6/9,s10,x2/5,s10,x15/4,s3,x3/8,s10,x14/12,s5,x10/8,ph/f,x9/3,s3,x10/13,s7,x8/14,pc/a,x6/0,s15,x12/11,s14,x9/4,pb/i,x5/15,s13,x6/9,s12,x3/12,s1,x7/1,s13,x11/13,s6,x14/12,pp/d,x2/11,s6,x14/15,s1,x7/6,s4,x3/1,s10,x4/14,pb/j,x9/15,s12,x10/13,s1,x4/15,s6,x7/12,s1,x9/0,pp/k,x8/14,s15,x10/0,pc/a,x14/13,s13,x0/6,pe/n,x7/13,s5,x1/5,s15,x12/2,pi/l,x1/10,pd/k,x14/11,pe/g,x6/4,s12,x12/5,pm/f,x0/15,pn/c,x4/13,pm/i,x10/2,pp/n,x7/14,s13,x13/15,s6,x12/3,s9,x10/0,pf/d,x6/2,po/i,x1/7,s10,x3/11,s12,x1/0,s15,x3/9,s6,x7/1,pd/a,s7,x11/5,s1,x12/1,pn/b,x13/7,pa/g,x3/0,pp/n,x15/8,po/h,x7/5,s5,x9/10,s8,x4/15,s11,x8/13,s6,pj/f,x0/4,pk/a,x12/6,s6,x4/0,pp/m,s9,x2/1,pb/h,x9/7,pa/e,x4/8,s9,x3/10,s14,x14/9,s12,x8/1,pb/h,x15/10,s1,x12/13,s13,x9/5,s10,x4/7,s1,x10/2,s3,x4/6,s11,x9/2,po/f,s14,x13/3,s4,x7/6,s12,x13/3,s2,x10/5,s8,x12/3,pb/h,x10/4,s5,x5/7,s2,x3/9,pi/e,x8/0,s2,x3/4,s13,pg/b,x6/7,pn/k,x8/10,pm/e,x0/15,s3,x6/3,pb/l,x4/2,pm/h,x11/13,s5,x12/3,pp/f,x15/0,s6,x2/4,s11,x12/1,s3,pg/h,x13/10,s7,x8/14,pd/j,x0/3,pe/i,x7/15,pk/d,x5/9,pj/h,x14/6,s4,x5/1,pc/a,s10,x12/6,s2,x7/8,pb/m,x12/1,s4,x9/6,pc/j,x1/8,pg/b,x3/10,pm/l,x11/8,s8,x2/4,s14,x9/1,s12,x8/7,pd/p,x13/1,s13,x4/8,pg/c,x10/2,s14,x6/4,s3,x13/2,s7,x14/7,s10,x6/5,s8,x3/8,s5,x9/0,pe/p,x15/8,ph/c,x12/7,pm/d,x13/1,ph/c,x10/3,pm/p,x7/13,s3,ph/l,x3/15,pp/c,x0/1,pl/k,x6/10,s2,x3/9,pf/h,x6/14,s15,x10/1,pl/d,x15/12,pf/p,x14/0,s1,x3/13,s13,pj/b,x4/0,s8,x8/1,s13,x11/15,pd/m,x12/0,s6,x15/1,s2,x11/9,s13,x6/0,s15,x13/10,s6,x3/2,s4,x10/14,s12,x1/4,pf/g,x5/11,po/m,x14/12,s15,x11/2,s5,x9/15,s8,x13/11,pf/c,x9/7,pe/d,x1/15,pi/m,x4/6,s15,x2/13,s10,pk/c,x4/12,pm/b,x13/11,s5,x4/0,s3,x1/12,s12,x3/4,pk/e,x11/2,s4,x6/4,pa/c,s2,x7/14,pk/o,x4/5,pa/c,x1/7,s6,x12/2,s12,x10/15,po/n,x5/8,pm/j,x15/2,s4,x5/7,s7,x12/2,pa/p,x7/0,pf/i,x2/4,s1,x0/13,s11,pd/n,x11/1,ph/l,x13/3,s6,pm/f,x8/12,pe/c,x7/5,pi/h,x4/11,s5,x14/9,s15,pm/k,x15/3,pe/i,x2/8,s11,pc/k,x15/11,s5,x2/13,pf/p,s6,x1/9,pj/l,s2,x6/0,pn/p,x1/5,s10,x6/2,s12,x9/12,ph/b,x6/1,pk/m,x12/9,s12,x5/15,pf/b,x3/0,pc/h,x4/13,pj/n,x8/1,s1,x7/9,s5,x14/2,s3,x15/5,s3,x3/12,s2,x11/5,s11,x1/6,po/k,s7,x12/9,s4,x10/11,pe/h,x2/4,s3,x7/14,s10,x10/8,pa/p,x3/11,pg/i,x14/10,pd/e,s6,x13/4,s5,x9/10,pm/h,x14/13,s1,x15/11,s3,x2/5,s12,x7/15,pe/o,x13/6,pi/g,x9/10,pb/p,x0/5,s5,x10/8,s1,x15/5,s6,pd/j,x6/0,pf/i,x8/14,pl/h,x10/0,pp/a,x13/11,pd/m,x15/12,s12,x10/9,s12,x4/2,s3,x12/6,s8,x0/5,pn/g,s11,x8/4,pc/d,x15/10,s10,x14/1,pe/g,x15/4,s15,x5/7,s7,x15/2,s14,x1/5,pa/h,x3/0,s9,x10/14,pg/m,x0/9,s10,x5/11,pf/c,x12/4,s14,x15/13,pj/h,x0/2,s2,x6/10,s14,x5/13,pl/n,s6,x14/0,s2,x9/12,pb/d,x13/8,pi/m,x10/14,pn/g,x8/7,pm/c,x1/3,s11,pn/k,x6/10,pl/g,x13/4,s3,x15/3,s1,x5/7,s5,pd/k,x10/14,s7,x15/1,s13,x0/8,pn/b,x15/12,s5,x11/9,s8,x3/2,s6,x13/9,s4,x11/14,pa/j,x2/5,pg/h,x13/3,s11,x7/10,pj/e,x4/0,s14,x5/15,s14,x4/6,s11,x15/8,pd/p,x12/4,pc/g,x13/15,s14,x2/1,s8,x11/10,pn/h,x12/2,pa/o,x4/8,s10,x14/7,s2,x4/6,pd/f,x14/10,s14,x5/8,s3,ph/o,x10/9,pd/e,x15/6,pl/a,x1/13,s1,x9/15,pn/h,x1/6,pg/j,s4,x13/8,pb/a,x2/15,s3,x14/12,s12,x11/1,s10,x13/14,s1,x0/11,s12,x15/12,pc/d,s12,x0/4,pg/a,x15/10,ph/n,x0/14,s4,x8/13,po/m,x12/10,pf/a,x0/5,s1,x11/9,s2,x7/6,s4,x12/11,s14,x14/9,s15,x3/6,pn/i,x13/4,s2,x2/3,pe/c,s4,x13/11,s13,x12/5,po/b,x15/2,pn/k,s11,x5/6,pf/l,x11/7,s8,x9/13,s3,x6/1,s3,x5/9,pe/b,x4/3,pg/c,x10/13,pl/h,s11,x1/14,s12,x8/11,s3,x3/5,s13,x1/10,pi/m,x7/0,pf/b,x10/15,s10,x9/3,s4,x7/8,pg/l,s10,pa/f,x6/11,s8,x13/10,pg/p,x3/6,ph/c,x14/0,pe/a,x15/13,s7,x6/9,s10,x5/1,pm/n,x15/13,s5,pe/i,x5/2,s11,x15/3,pd/m,x13/5,s2,x8/4,s12,x0/10,s3,x7/3,s14,x5/12,s10,pf/n,x3/10,s6,x15/0,s15,x3/8,s4,pa/i,x1/0,s5,x5/4,s15,x8/13,s7,x6/1,pj/k,x15/7,ph/l,x0/10,s14,x9/11,pk/g,x8/1,s14,x9/2,s4,x0/5,pf/c,x2/3,s1,x11/8,pa/l,x2/7,po/j,x13/10,s9,x0/3,pi/d,x2/6,po/c,x0/4,pa/k,s13,x9/14,pp/h,x3/15,s7,x7/14,s12,x2/3,s6,pa/n,x0/7,s1,x13/3,pf/g,x5/9,s1,x7/13,pi/k,s13,x4/10,s7,pb/f,x15/1,pa/o,x11/13,s15,x3/6,s12,x12/13,pn/p,x3/9,s7,x12/8,pg/e,x0/1,pk/o,x10/4,s1,x7/1,s2,x3/11,pn/l,x6/0,pj/i,s13,x10/7,s3,x2/13,po/n,x9/7,s15,x1/2,pk/f,x11/10,s1,x8/12,s10,x4/7,s2,x15/10,pa/m,x11/9,ph/p,s13,pa/g,s13,x4/15,s13,x8/11,pf/j,x13/15,s4,x12/2,s6,x9/7,pb/p,s11,x2/10,s7,x9/11,pn/i,s5,x5/14,pb/f,x7/0,ph/p,x1/9,s10,x7/12,pj/a,s13,x15/10,pl/h,x5/14,s9,x3/2,s14,x4/8,pm/f,x0/1,s2,x5/6,s13,x3/7,s12,x12/13,pk/a,x11/0,pi/b,x15/3,pc/o,x8/0,s4,x3/13,pm/a,s6,x14/2,pn/e,x11/8,s5,x5/4,s4,x6/7,s6,x11/8,s13,x6/2,s6,x15/14,s15,x2/4,s13,x11/7,po/p,x6/1,s9,x15/13,s10,x4/0,s3,x12/2,pk/m,x6/13,s3,x3/7,s12,x2/0,s14,x10/15,s5,x9/0,s12,pd/f,x13/3,s15,x14/6,s3,x15/0,s3,x1/7,s4,x4/8,s7,x10/12,pj/e,x9/13,s3,x4/0,pa/p,x10/3,pg/o,x7/14,pf/b,x13/6,pm/i,x8/12,s14,x2/14,pj/f,x10/13,s10,x0/8,s15,x2/7,s8,x9/1,s6,x8/3,pn/l,x13/1,s10,x8/3,pd/j,x14/0,pe/h,x2/7,pp/l,x15/9,s12,x7/0,pf/j,x14/9,s14,x12/11,pk/b,x2/5,s9,x0/10,s3,x5/9,s15,x4/0,pj/f,x12/14,pm/e,x0/2,ph/o,x15/6,pd/k,x9/4,pe/n,x5/2,ph/j,x1/13,s7,x15/9,s1,x5/3,pa/c,x7/4,pn/k,x1/5,s3,ph/e,x2/13,pi/p,x1/8,pc/n,x7/6,s10,x3/4,s8,x1/9,s11,x5/0,s8,x1/13,pl/b,x5/0,s13,x4/14,pe/g,x10/8,s5,x0/15,s1,x11/7,s14,x5/9,pm/p,x14/15,pn/a,x0/8,pm/l,x4/12,ph/i,x0/8,s4,x3/9,pg/o,s5,x10/8,s1,x7/2,s7,ph/m,x1/0,pf/b,s5,x8/5,s13,x13/15,s4,x3/7,s6,x9/15,s3,x13/10,s14,x1/12,s8,x15/9,s15,x10/6,pc/i,x7/5,s12,x1/10,s3,x12/4,po/g,x8/3,s6,x0/4,s6,x3/1,s2,x4/7,s1,x2/3,pj/f,x15/8,pm/i,x11/10,pc/k,s4,x13/3,pa/g,s15,x6/14,s10,x2/13,pi/e,x11/9,pg/n,x14/8,pf/e,x15/1,s14,x2/3,pi/d,x15/12,pp/n,x3/6,pl/e,x1/11,pg/p,x7/5,pk/i,x8/10,s9,pc/o,x12/9,s10,x5/14,pe/l,x7/4,s11,x11/15,s2,x10/14,pk/h,x7/11,s10,x15/5,pp/a,x6/8,s12,x7/1,pn/d,x5/3,s3,pa/h,x6/13,s11,x3/15,s11,x0/4,s3,pg/l,x11/10,s6,x13/5,s13,x6/4,pb/k,x14/1,pi/l,s15,x6/0,pp/k,x4/14,s15,x10/2,s3,pj/a,x8/0,pn/c,x15/12,s10,x7/4,s14,x6/0,s10,x4/9,pf/j,s14,x8/11,pk/c,s5,x6/7,pn/p,x0/12,s3,x7/10,s11,x15/11,s11,pc/o,x7/0,pa/m,x3/8,s9,x10/13,s4,pc/b,x1/8,ph/g,x0/11,s12,x13/4,s7,x0/15,pa/f,x9/13,s9,x5/7,pb/h,x4/13,s5,x8/15,s4,x1/14,pi/a,x12/5,s13,x8/2,s12,x13/12,s2,x6/14,pc/e,x13/4,pk/b,s1,x14/15,pd/f,x12/5,s7,x10/4,pe/a,x14/13,s13,x5/6,s15,x1/9,s7,x3/8,s7,x11/1,s15,x9/5,s14,x12/7,pg/i,x3/1,s9,x13/4,pl/f,x2/5,s7,x14/3,pk/c,x8/10,pi/d,x3/1,pk/j,x2/8,pm/e,x0/4,pd/l,x12/13,s1,x14/3,pa/i,x13/7,pn/m,x12/15,s13,x8/14,po/c,x6/0,s13,x5/7,s2,x3/11,s4,x8/14,pb/p,x9/7,pn/m,x2/13,po/p,x3/14,s3,x2/6,pi/f,x13/8,pn/g,x10/6,s1,x15/7,s6,x1/4,s10,x14/9,pc/h,x6/15,po/e,x0/1,pf/c,x6/2,pm/l,x11/3,s14,x6/2,s5,x11/12,pn/g,s15,x4/10,pm/l,x14/15,s10,x10/2,pa/p,x7/9,s10,pc/k,x2/8,pb/l,s15,x3/12,s15,pn/a,s14,x0/8,pd/p,x6/11,s15,x7/9,s5,x4/2,po/b,s14,x3/14,s11,x2/5,s9,x3/0,s9,x1/15,s9,x0/9,s15,x6/11,s12,x3/10,pf/l,s12,x1/9,s2,x14/2,s13,x15/6,pg/o,x14/10,s12,x9/8,s5,x2/14,s11,x11/1,s10,x0/3,s9,x11/10,pc/i,x5/12,s13,x7/1,s12,x5/15,pl/h,x12/1,s7,x6/4,pn/g,x15/10,pj/e,x12/0,s7,x13/9,s5,x11/7,ph/n,x0/3,s2,x7/10,pk/o,x1/4,s5,x9/11,pe/l,x0/2,s8,x13/4,pb/p,x0/7,s8,x10/8,s12,x4/9,pj/o,x1/8,s1,x11/2,s3,x0/4,s8,x7/12,s6,x0/11,s9,x13/12,pp/g,x6/10,s1,x7/0,s7,pk/f,x5/8,pa/c,x14/0,pe/f,x11/15,s1,x6/2,pp/j,x0/13,s15,x14/11,s13,x10/1,s5,x13/9,s3,ph/a,x10/4,s9,x8/7,s6,x10/0,s11,x3/14,s4,x6/5,pi/j,x11/2,pp/l,x8/4,s10,x15/2,pn/m,x8/6,pk/h,x4/1,pp/e,x9/13,s3,x0/6,s15,x3/12,s9,x7/8,pm/b,x9/14,pc/g,x8/2,s3,x6/5,s3,x14/12,s1,x3/9,s7,x4/6,pa/h,x13/10,s4,pk/o,x14/6,s7,x8/11,s4,x9/13,s7,x3/12,s2,x15/0,s15,x1/5,s15,x15/7,pm/h,s10,x11/10,s5,pf/d,x4/8,pc/a,x7/12,s14,x5/4,pj/f,x12/13,s12,x2/4,pl/d,x10/11,s8,x2/14,s2,x0/12,pi/f,x3/10,s12,x1/9,s15,x14/8,pp/h,s14,x15/3,s2,pi/e,x0/1,pn/c,x5/11,s13,x9/8,s14,x6/12,pg/j,x0/9,s9,x10/2,s8,x3/8,s13,x12/14,pb/e,x7/5,s13,x4/9,s4,x14/6,s4,x0/9,s9,x4/3,s1,x11/5,s10,x10/9,pm/p,x4/6,po/f,x5/9,s6,x6/13,s14,x15/12,s8,x6/0,pi/g,x15/10,pc/o,x12/3,pp/a,x9/8,po/n,x14/0,s14,x2/11,s5,x3/7,s4,x1/8,ph/j,x13/3,s14,x14/12,s13,x13/10,s7,pe/c,x0/6,pg/l,x3/12,po/b,x15/10,pf/k,x6/11,s6,x4/12,s7,pp/l,x11/13,s3,pb/h,x14/1,s6,x15/13,s4,x0/10,pn/e,x7/6,pd/f,s1,x15/10,s10,x7/5,s6,pi/h,x6/11,s5,x8/15,pd/b,x14/0,s10,x7/9,po/p,x4/3,s4,x2/0,s6,x14/9,pl/j,x10/12,po/p,x2/7,pi/c,x6/12,s9,x2/5,s9,x14/10,pe/d,x7/6,pa/k,x1/12,s12,x2/3,ph/f,x15/13,s3,x8/12,s15,x9/10,s4,x13/6,pl/i,x9/3,s9,x4/15,s8,x13/14,s9,x15/9,s9,x13/1,s7,x3/0,s11,x4/9,pg/n,x7/8,pf/h,s5,x5/13,pa/p,s10,x6/9,pg/d,x7/11,pc/a,x5/0,s13,x13/7,pp/f,x1/8,s12,x4/15,s2,pk/m,x1/2,pe/l,x11/6,pc/h,x15/5,s13,x2/10,s14,x14/4,pe/a,x9/15,s12,x8/0,s13,x10/2,s10,x1/14,s3,pf/l,x11/0,s7,x12/7,pd/k,x11/14,s7,x12/0,pi/n,x7/9,s5,x6/8,s5,x7/9,pb/e,x5/11,s8,x8/6,s2,x13/4,pn/h,x5/3,pi/o,s13,x0/2,s6,x7/9,s8,x3/4,pg/n,x2/5,po/f,x10/13,s12,x1/9,s2,x14/0,pm/a,x9/11,pn/o,x0/1,s7,x14/11,pf/e,x0/2,s7,x7/9,s7,x11/5,s12,x12/14,s8,x15/5,pm/k,x1/8,pn/p,x7/2,s10,x8/13,s11,x2/12,pf/m,x10/8,s3,x11/1,pl/a,s7,x0/2,s2,x7/13,ph/d,x8/10,pg/l,x3/14,s3,x2/11,s10,x14/6,s9,x4/12,s14,x1/6,s5,x10/7,pa/m,x13/1,s7,x6/15,pe/d,x7/14,s7,x3/8,s10,x6/13,pn/f,x11/1,pd/l,x6/7,s1,pm/n,s12,x2/10,s8,x4/14,s4,pc/o,x7/6,s10,x1/2,pb/j,x0/5,pk/a,x10/7,pm/n,x2/1,pl/p,x7/15,s14,x10/14,s12,x1/12,s8,x8/4,s8,x0/14,s13,x5/2,s5,pc/f,x14/15,s13,x11/6,pm/a,x8/10,pp/o,x3/2,pm/f,x15/9,s7,x14/7,s2,x15/0,s6,x14/11,pl/h,x8/2,pb/o,x4/1,s1,x15/6,s1,x9/4,s6,x11/2,s5,x6/5,s6,x10/9,pa/e,x1/12,s13,x10/7,s12,x12/11,po/j,s7,x9/8,s5,x11/5,ph/p,x13/3,s8,pm/g,x7/0,s2,x9/6,pa/l,x14/12,s15,x5/8,pm/f,s2,x9/11,pb/e,x2/5,pn/p,x15/10,s10,x7/3,s15,x0/1,s15,x11/2,s10,x0/8,s6,x1/2,ph/e,s11,x7/12,s1,x13/11,s3,x9/15,s5,x0/13,s14,x5/7,pk/n,x10/13,s5,x12/15,pm/g,x5/11,s8,x15/10,s4,x5/12,pe/d,x0/15,pa/b,x6/14,pc/j,x11/0,pp/b,x6/14,pn/d,x12/7,s1,x10/9,pf/m,x1/15,s14,x11/5,s15,x15/13,s2,x14/5,s11,x13/9,pi/c,x7/8,s13,x4/3,s10,x13/10,s7,x0/15,s9,x1/14,s8,x4/13,s10,x8/2,s10,x3/14,pn/d,x9/6,ph/m,x13/4,pj/i,x12/15,s1,x14/8,pf/d,x2/12,s8,x4/1,pc/o,x10/8,s14,x6/1,pm/a,x14/8,s10,x11/5,s10,x12/15,s13,pc/j,x11/2,s9,x9/7,s14,pk/p,x11/15,s3,x2/8,s6,x1/3,s8,pj/a,x8/12,s8,x11/1,pi/n,x3/6,s9,x10/15,pf/b,x7/1,pe/a,x4/0,s2,x6/14,pc/p,x1/2,s3,x13/0,s7,x1/8,s10,x5/7,pf/e,x14/4,pc/g,x1/10,s11,po/p,x9/2,pd/e,x0/7,s9,x10/4,s15,x3/5,s3,x1/4,pm/k,x10/3,pl/n,x4/1,s2,x3/13,pi/b,x2/8,s7,po/p,x6/15,pb/d,s12,x10/4,s6,x7/15,pe/o,s2,x5/12,s10,x7/0,pa/i,s7,x14/13,s13,x4/5,pj/l,x12/14,s4,x1/2,pg/k,x3/11,pc/p,x4/13,pj/g,x12/11,s10,x8/14,s1,x10/3,s4,x6/2,s7,x11/12,s14,x15/8,pp/b,x3/0,s4,x8/15,s2,x11/10,pk/n,x3/15,s6,x11/9,pb/o,s13,x0/2,pl/e,s10,x4/14,pa/c,x5/1,s3,x15/8,pb/i,x12/2,pp/o,x14/6,pg/m,x15/10,pp/j,x5/12,s11,x4/0,s4,x11/14,s5,x12/2,pf/a,x14/11,s5,x15/1,s13,x13/14,pi/k,s10,x15/8,s14,x4/3,pp/n,x2/10,s7,x12/3,s7,pk/g,s9,x10/4,s6,x9/13,pb/i,x6/12,po/m,x8/15,s2,pp/h,x7/13,s2,x5/6,s8,pn/g,x13/14,pi/h,x5/3,pa/f,x14/10,s13,x12/15,s15,x13/0,po/p,x14/6,s7,x9/4,pn/k,s1,x1/6,pi/p,x9/14,s7,x2/7,s9,ph/g,s12,x10/5,pf/d,x9/6,pg/b,s14,x1/15,pf/e,x4/0,s13,x5/9,s13,x0/4,pi/n,x9/7,pl/o,x14/3,pk/j,x10/12,s1,x0/3,s12,x2/7,pm/a,s14,x8/11,s1,x3/4,po/n,x11/6,pe/j,x5/12,pm/h,x0/10,s3,x3/12,s5,x10/2,s3,x12/11,pp/a,x15/13,s5,pf/j,x5/8,s6,x9/4,s3,pn/h,x13/12,s2,x3/6,s11,x15/10,pa/b,s6,x14/1,s4,x8/15,pp/g,x0/11,po/d,x8/6,s7,x3/9,pa/b,x8/14,s15,x6/0,s3,x8/11,s9,x3/6,s5,x9/14,pf/j,x2/12,pi/e,x8/15,s11,x7/10,s12,x8/15,s7,x0/13,pa/c,x1/5,po/l,x15/12,pn/p,x1/5,s10,x7/10,s13,x5/0,s11,x13/3,s13,pf/h,s3,x4/1,s7,x11/5,s11,x10/14,pe/a,x2/11,s2,x14/0,s13,x10/12,pb/f,x7/9,s12,x4/8,s13,x2/13,s12,x9/1,s4,pp/a,x5/11,s6,x2/8,pe/d,x6/14,s2,x1/2,pg/i,s12,x12/8,s14,x7/6,pp/f,x3/2,po/j,x13/15,pb/h,x2/10,pi/j,s12,x8/7,s9,x0/12,s13,x3/4,pa/m,x13/0,s6,x5/3,s13,x14/4,ph/b,s6,x13/12,s7,x15/1,s14,x10/6,s11,x15/0,pn/i,x2/11,s15,x5/12,s15,x7/9,pf/a,x10/15,pl/i,x2/0,pm/k,x1/11,pp/j,x8/4,pb/l,x7/12,s6,x5/0,s7,x11/12,pj/k,x10/13,s1,x11/14,s6,x15/12,s2,x9/13,s3,x1/15,s1,x10/12,pg/a,s1,x6/15,s7,pc/i,x10/12,pb/o,x4/9,s13,x0/5,s4,x7/6,s12,x4/14,pn/c,x12/8,s5,x15/4,pg/f,x12/11,s12,x1/0,pn/h,x14/9,s5,x5/6,pl/i,x9/0,s9,x5/7,s6,x13/15,pm/b,x11/8,po/k,x3/15,s6,x2/4,s13,pp/l,x14/1,pb/e,x9/3,s4,x0/15,s5,x5/12,s6,x9/13,pg/f,x2/1,s3,x4/13,po/l,x2/6,s10,x4/9,s7,x14/10,pk/f,x12/6,s7,x15/5,s9,x7/0,s12,x1/6,s13,x12/7,pc/n,x5/1,ph/f,x13/7,s6,x4/14,s2,x6/3,pm/e,x8/14,s11,x10/1,pi/c,x4/0,pf/p,x5/15,s3,x13/6,s7,x5/1,s10,x15/2,pg/e,x8/14,s3,x4/7,pb/h,x5/6,s4,x12/9,pi/j,x15/4,s14,x14/9,pd/e,x4/13,s1,pk/h,x10/14,s10,pf/i,x1/15,pc/a,x8/7,ph/e,x6/1,pg/a,x15/5,s3,x4/0,s5,x9/3,pm/b,s12,x2/7,s5,x14/0,pi/e,x3/6,s6,x9/5,s6,x2/13,s8,x12/14,s2,x13/3,s8,x8/1,pj/l,x15/6,pb/a,x11/5,s2,pd/p,s15,x6/10,s8,x3/0,ph/k,x14/8,pj/b,s7,pm/l,x11/12,pi/h,x3/7,s9,x12/8,pj/n,x3/9,pa/p,x6/13,pn/g,x8/14,s13,x0/15,pj/p,x4/2,pb/d,x1/13,s4,x6/9,pk/p,s7,pe/l,x11/4,ph/k,x15/6,pc/p,x11/14,s13,x7/2,pe/l,x5/8,s3,x0/9,s6,x11/8,s12,x15/4,s5,x7/2,pc/n,x0/13,s1,pe/d,x3/1,ph/p,x15/14,s10,x12/10,s13,x1/9,s14,x4/2,s11,x12/14,s13,x3/5,s13,x4/10,s2,pb/m,x7/6,pe/f,x2/11,pj/c,s11,x12/9,s13,pm/a,x14/5,pi/c,x13/4,pf/e,x0/15,s5,x10/4,pn/p,x1/0,pi/f,x10/6,pg/m,s9,x3/0,pc/k,x7/9,pb/l,x1/10,s15,pc/m,x5/4,pn/l,x7/1,pf/h,x2/10,s15,pm/a,x12/8,s11,x15/2,pb/e,x8/10,po/g,x7/2,pd/e,x5/4,s4,x1/10,pn/p,x5/15,s12,x6/14,s3,x1/15,pj/e,x11/9,pi/b,s14,x3/12,pd/k,s5,x4/10,s9,x5/1,s7,pe/h,x4/15,s14,x11/3,s11,x1/6,s14,x0/11,pa/p,x8/3,s13,x13/7,s8,x10/2,s14,x14/13,s7,x9/6,s12,x0/7,s10,x15/12,s12,x1/5,s3,x3/9,s13,pc/e,x10/5,s11,x2/0,po/k,x4/11,s13,x8/7,pp/e,x2/11,s9,x3/4,s11,x13/9,po/c,x4/0,s3,x7/8,pa/p,x1/12,s12,x5/4,pd/f,s7,x2/15,pn/g,x13/8,pm/k,x10/4,s3,x14/2,pn/a,x13/4,po/k,x6/1,pe/l,x8/4,pn/p,x13/3,pm/o,x11/14,pa/k,x4/6,pl/j,x13/0,pk/o,x2/4,s6,x14/5,s6,x7/4,s11,x6/12,s15,x10/0,s3,x3/5,pm/j,s8,x1/7,s5,x9/13,ph/d,x10/6,s13,x5/7,pa/j,s10,x8/3,pd/g,x0/7,pm/b,x8/12,s15,x13/6,s2,x14/12,pp/i,x4/3,s2,x15/2,s11,x5/6,s12,x11/9,s6,x1/4,s1,pa/k,x3/2,ph/i,x13/7,s6,x5/3,pf/b,x12/15,s9,x8/5,s9,x11/2,s6,x9/6,s11,x15/10,s13,x5/1,s14,x6/2,pi/c,x14/9,s15,x13/10,s6,x4/0,ph/n,x6/7,s3,x10/2,po/a,s5,x1/9,pg/d,s15,x7/11,s12,pf/j,x6/13,pd/c,s12,x4/3,s3,x15/14,po/l,x5/9,pf/e,x15/14,s11,pk/a,s2,x13/12,pf/e,x14/10,pd/m,x7/2,s15,x12/15,s13,x5/8,pk/b,x6/9,pg/j,x8/14,pd/p,s11,x9/10,s13,x4/11,s5,x14/2,pk/i,x4/6,s6,x10/1,pd/h,x6/14,s9,x10/4,s11,x12/5,s15,x7/3,s10,pb/k,x12/15,pm/a,x11/7,pc/h,x9/8,s7,x1/7,s13,x13/9,s8,x12/8,s7,x4/11,s3,x7/12,s8,x8/1,s9,x7/2,pl/n,x15/12,s5,x14/0,po/g,x2/11,s6,x15/5,s6,x13/1,pb/j,x6/10,s3,x5/8,pf/m,x12/6,pa/l,x10/9,s11,x1/13,s11,x12/15,pb/e,x11/13,pd/o,x9/8,pp/a,x0/7,pc/o,x10/1,s13,x3/14,pk/m,x6/1,s6,x13/3,pn/o,x1/0,pm/j,s1,x6/13,s9,x0/1,s6,x10/9,s14,x8/7,s9,x0/4,pk/p,x5/1,s2,x3/2,pe/g,x0/1,pj/d,x4/9,s2,x2/7,s10,x8/5,pm/k,x4/0,pc/a,x9/6,pe/o,x10/7,s1,x6/8,s10,x2/9,pg/p,x7/0,pa/c,x9/10,s1,x1/12,pp/h,x9/10,pk/f,x5/12,s12,x13/7,s5,x5/6,s4,x3/15,s13,x8/4,s3,x13/9,pa/c,x3/7,pi/j,s5,pg/k,x13/11,s4,x15/1,s2,x11/9,s6,x7/8,s10,x9/3,pl/d,s4,x14/12,s10,x10/1,s8,x11/9,pj/o,x2/14,pf/a,x6/5,pp/h,x8/9,pf/o,x2/3,s11,x12/4,pe/b,x3/7,pf/i,s5,ph/j,x11/1,pn/f,x5/12,pp/j,x1/0,s4,x10/7,pc/d,x6/2,s8,x11/7,s9,x3/4,pk/f,x14/15,s3,pi/l,x8/7,s2,x6/1,pj/h,x3/15,s2,x11/12,po/g,x8/9,pb/m,x1/6,s8,x12/7,s14,pn/e,s5,x5/9,s7,pm/d,s4,x0/6,pc/l,s12,x14/4,pj/f,x1/2,s12,x0/11,s6,x14/7,s7,po/p,x4/12,s7,x6/11,s8,x10/1,s12,x14/9,s2,x6/5,s5,pa/c,x8/10,pp/f,x6/3,pd/e,x9/15,s4,x10/13,pn/p,x12/8,pi/b,x10/14,pe/n,x1/5,s11,x0/7,s14,pg/m,x3/11,s15,x9/7,s3,x14/1,s1,x0/2,s2,x13/3,pp/j,x6/11,s8,x14/9,s5,x10/7,pm/f,x1/2,pg/o,x4/8,s5,x9/1,s5,x2/3,s12,x13/15,pe/h,s13,x10/12,s11,x9/1,s7,x14/6,s3,x8/12,pn/p,x3/9,s11,ph/f,x2/6,s8,x9/4,s13,x10/14,s10,x4/11,pm/c,x1/9,s12,x0/4,pn/g,x5/3,s9,x4/2,s3,pp/d,x6/12,s12,pk/c,x2/0,pl/e,x12/7,s6,x9/5,s6,x13/3,pg/h,s13,x4/8,s13,x10/0,s4,x8/2,po/a,x12/3,s8,x13/8,s11,x0/14,pm/h,x7/12,pp/j,x1/4,s5,pd/l,x15/5,s12,x7/11,s11,x9/3,po/j,x0/12,s8,x9/10,pg/h,x5/11,po/n,x6/4,s12,x8/15,s2,x10/11,pd/b,x0/6,s12,x10/8,pp/g,x2/12,pf/e,x5/0,s12,x3/7,pi/n,x8/11,pd/g,x7/2,pf/l,x4/11,s10,x2/12,pk/a,x14/0,s8,x6/11,pm/c,x3/2,pp/b,x6/14,pm/a,s12,pd/n,x10/7,pp/g,x0/14,s10,x7/12,s12,x13/15,s9,pf/h,x2/10,pg/i,x9/11,pc/e,x15/8,ph/d,x11/3,s1,x4/2,s9,x3/1,pf/p,s2,x4/13,s11,x14/12,pb/g,x15/3,s14,x11/8,s6,x0/6,s3,x1/7,s15,x9/6,s12,x13/12,s14,x3/8,s10,x14/11,ph/j,x12/13,s14,x5/2,s4,x13/11,s4,x7/1,s8,x14/15,pa/f,s6,x2/6,s10,pl/e,s10,x12/10,pk/g,x1/15,s12,x3/11,s5,x8/6,pa/o,x1/13,pl/e,x6/11,s4,x10/8,pn/g,x3/15,s11,x8/4,pp/j,s1,x9/13,s11,x15/5,s1,x1/3,s7,x2/13,pa/g,s2,x7/10,ph/o,s6,x9/11,pk/f,x15/13,s2,x6/8,s5,x9/11,pp/b,s15,x12/13,pf/h,x8/10,s14,x4/14,s5,x7/11,s2,x6/8,po/j,x2/0,s15,x4/6,pc/d,x5/10,pl/p,x3/13,s13,x6/10,pf/n,x13/5,s4,x11/7,pd/a,x15/4,s5,x0/14,s3,ph/o,x4/15,s1,x0/14,s2,x1/13,pp/b,s3,x2/9,pn/o,x11/7,pe/d,x2/10,s6,x4/6,pa/b,x1/14,s2,x0/10,pi/m,x12/3,s12,x8/2,pp/d,s8,pj/b,x7/10,pe/g,x11/8,pd/a,x4/10,s5,x1/5,po/f,x13/0,pi/m,s15,x1/10,s8,x9/2,s15,x12/5,s12,x9/13,pf/k,x0/12,s10,x8/9,pj/a,x4/1,s15,x15/0,po/c,x4/1,s11,x10/15,pi/j,x0/13,pb/g,x10/5,pn/p,x1/11,ph/a,x7/8,pc/k,x14/15,s2,x7/2,pl/p,x12/3,pc/n,x1/8,pp/m,s1,pj/l,x13/2,pp/o,x0/3,s5,x4/10,s8,x11/9,s10,x4/12,s2,x2/3,s15,x9/6,pi/k,x1/0,s3,x12/15,s3,x3/4,pe/g,x15/8,s8,x3/2,s10,x5/12,s8,x8/9,pk/l,s11,x13/4,pg/m,x12/0,s1,pp/a,x15/2,pg/c,x4/8,s4,x13/5,s12,x2/14,pn/k,x6/0,po/l,x11/10,s3,x5/3,pf/a,x0/7,s9,x14/15,s15,x1/13,s7,x11/14,pl/c,x13/5,s6,x11/3,s12,x14/9,pi/o,x11/10,s3,x15/7,pf/n,x10/13,pd/p,s8,pj/m,x5/3,pa/b,x0/13,s7,x2/3,pd/j,x13/0,s1,x7/5,ph/k,x12/9,pl/g,x14/11,s9,x4/8,s5,x13/10,pa/f,s13,x6/9,s11,x3/11,pj/m,x0/15,pa/f,x1/12,s1,x11/14,pp/j,x4/5,pd/n,x7/15,pj/k,x11/10,s1,x13/4,ph/b,x9/7,s12,x14/11,pj/i,x5/12,s15,x2/14,pg/n,s4,x12/1,pj/d,x10/6,s9,x13/12,s9,x1/11,s1,x12/7,pg/a,x14/1,pp/f,x4/12,s1,x15/13,pg/j,x6/4,s8,x7/11,pf/p,x0/9,ph/c,x5/1,s1,x9/8,pm/b,x14/5,s11,x10/4,s12,x15/13,s9,x6/12,s2,pf/a,x5/9,pn/c,x15/10,pb/e,s5,x4/11,ph/o,x13/3,s1,x12/1,s15,x7/0,s3,x3/1,pk/f,x13/6,s10,pi/p,x1/5,s4,x14/0,po/b,x8/2,s15,x5/13,s14,x7/10,s9,x12/11,pm/n,x7/14,pd/o,x11/5,s1,x13/10,s15,x12/11,pn/e,s5,x2/3,s13,x15/1,s5,x14/7,s10,x2/15,s7,x4/3,s2,pc/d,x11/8,pp/e,x10/9,s4,x4/7,pg/n,x12/3,pf/e,x2/7,pa/h,s4,pm/n,x11/4,s15,ph/g,x10/12,pd/f,s9,pg/m,x14/13,pl/a,x3/5,s11,x11/14,pm/c,x2/13,s12,x8/5,s14,x10/15,pp/d,x7/5,s10,x6/13,s4,x1/4,pi/l,x0/6,s1,x2/10,pc/b,x8/1,pj/l,s3,x9/11,s6,pi/g,x5/2,s13,x1/9,pl/f,x7/11,s15,pe/m,x2/15,po/j,x14/5,s3,x9/3,s15,x13/2,s1,x12/4,s5,x7/8,s2,x6/1,s13,x11/7,s1,x5/0,s2,ph/k,s8,x12/1,s13,x7/5,pl/p,x0/11,pj/o,x3/14,pd/a,x6/4,s11,x14/12,s1,x15/7,pj/m,x13/1,pe/h,x8/11,s7,x2/1,s1,x7/5,pi/f,s2,x10/14,s7,x13/9,pj/k,x6/5,s8,x8/3,pp/m,x7/14,pk/g,x0/2,ph/p,x10/12,pi/e,x3/14,pg/f,x8/15,s12,x11/1,s9,x14/3,s7,x13/7,s14,x15/4,pm/e,x12/2,s3,x15/6,pp/o,x2/4,pi/n,x1/5,pl/e,x12/7,s2,x9/0,s4,x8/1,pm/i,x12/3,po/l,x14/2,pi/j,x10/5,s2,x2/14,s3,x1/12,s11,x8/15,pg/o,x7/14,s4,x2/8,s6,x0/11,s5,x12/2,pk/h,x9/1,pb/a,x7/5,s14,x10/15,po/h,s14,x7/3,s13,x0/14,s15,pj/f,x3/2,pc/m,x6/11,s11,x14/4,s12,x5/6,s7,x8/10,s9,x14/11,s4,x4/12,s10,x8/3,s9,pd/o,x13/2,s5,x9/11,s7,x4/2,s3,x8/12,s3,x1/6,s7,x15/2,s15,x5/7,s5,x12/6,pb/g,x9/10,s13,x2/12,pk/l,x15/9,ph/g,x6/13,pn/c,x2/5,s6,x1/14,pg/k,s1,x13/0,pi/c,x3/1,s1,x14/11,pj/n,x4/2,s3,x3/1,s11,x4/9,s13,x12/8,s5,x6/7,s12,x10/15,pl/e,s10,pa/g,x5/0,s8,x6/9,pf/i,x15/8,s12,x12/14,po/m,x11/15,s11,x8/9,s6,x6/15,pl/j,x7/1,pe/a,x12/2,pp/o,s9,pf/k,x5/3,s5,x12/4,s11,x2/9,pl/o,x6/8,pi/p,x14/13,s6,x11/4,s9,x15/9,s11,x10/7,s5,x14/12,ph/g,x8/13,s10,x2/7,pl/k,x0/14,pj/g,x1/7,pn/f,s13,x9/2,pl/p,x6/0,s13,x2/4,s8,x3/12,s1,x1/4,s13,x10/5,pg/b,x12/1,pc/m,x2/9,s5,x3/5,s8,x13/11,s1,x4/14,s9,pd/o,x8/2,s3,x5/13,s8,x8/11,s11,pg/e,x2/12,pk/b,x14/6,pl/a,x4/11,pc/b,s13,x14/6,pg/l,x11/5,pc/n,x1/13,s14,x2/4,s9,x14/3,pj/o,x2/4,pi/n,s6,x10/1,s3,pk/e,x14/3,s9,x2/15,s3,x7/0,s1,x12/1,s4,x13/14,s13,x2/1,s15,x9/6,s1,x3/8,s4,x5/1,s10,x10/4,s10,x0/11,pp/j,s5,x15/9,pi/o,x12/13,pe/g,x3/6,s4,x1/13,pb/f,x9/10,pc/m,x14/15,s7,x11/7,s2,x8/5,pd/n,x13/7,s13,x6/11,pl/c,x15/1,s13,x3/12,pi/o,x7/15,s10,x13/4,pe/j,x10/6,s11,x15/11,s8,x8/0,s12,pp/c,s13,x1/14,pb/e,x13/10,s9,x7/11,pk/i,x0/2,pb/a,x4/8,s5,x9/12,s2,x13/7,s12,x6/3,s8,x12/1,s7,x9/2,po/l,x11/8,s12,x15/3,s12,pj/e,x4/10,po/f,x11/8,s3,x6/14,s4,pl/b,x5/11,pe/p,x12/0,s13,x9/3,s1,x8/2,s1,x10/14,s4,x5/7,pd/j,x0/10,s2,x1/15,pe/m,x2/10,s4,x14/1,s2,x12/6,pk/a,x11/1,s12,x10/8,pn/h,x0/11,s3,x4/10,po/i,x12/9,s4,x8/10,pl/e,x0/14,pa/i,x8/3,pc/p,s8,x9/0,pn/m,x15/1,ph/d,x2/3,s10,pg/p,x13/8,s15,x3/10,ph/k,x1/11,pj/e,x13/12,s1,x2/4,s11,x12/5,s10,x0/3,pp/h,x5/1,pc/l,s9,x9/2,s11,x3/1,s5,x15/6,s1,x2/5,s12,x14/12,s9,pk/i,x6/0,s15,x14/10,pp/g,x9/12,pa/e,x4/11,s13,pi/l,x9/1,pb/o,x10/6,s3,x4/0,s4,x2/15,pi/d,s14,x4/3,pc/l,x13/15,s4,x12/7,s14,x15/1,pp/e,s14,x12/13,pd/k,x3/7,pe/g,x9/6,s15,x11/1,pl/c,x7/2,pa/i,x15/10,pg/n,x0/3,s10,x8/1,s8,x0/4,s2,x8/6,pd/b,x3/14,pk/g,s7,x8/4,pn/h,x15/1,s5,pc/k,x12/7,s2,x14/9,pb/g,s8,x1/0,s7,x9/5,pl/h,s1,x12/14,s11,x5/2,s11,x10/12,s8,pi/f,x7/14,pp/k,x5/10,pl/a,s7,x11/7,s9,x4/13,pg/i,s1,x14/1,s13,x12/2,s9,x11/8,s11,x3/9,s10,x5/6,s11,x1/15,s13,x11/4,s4,pe/o,x8/13,s9,x12/7,pm/l,x13/8,pj/d,x0/2,pb/f,x12/5,s7,x1/6,s7,pi/h,x9/12,pg/j,s9,x2/13,s1,x7/9,s10,pa/e,x14/0,pf/m,x15/3,s4,po/i,x7/6,s2,x5/15,s14,x1/10,s14,x13/3,pb/a,x11/12,ph/i,x15/14,s15,x7/6,s10,x15/1,s12,x4/7,pe/g,s13,x2/13,s13,x1/5,s4,x8/2,pp/b,x4/10,po/n,x11/7,pi/l,x15/0,pg/c,x8/6,pf/k,x13/4,s3,x9/7,s15,x15/5,s6,x10/0,s8,x2/9,ph/n,x3/7,s2,x14/13,pb/m,x0/9,pi/c,x15/2,pd/f,x0/8,pi/e,x3/11,pm/g,x12/9,pn/k,x13/5,s13,x4/11,pg/a,x7/6,pf/k,x9/13,po/l,x3/0,s1,x10/12,s7,x11/1,pe/b,x14/15,s9,x1/11,s15,x14/15,s15,pg/o,x11/3,pe/h,x2/0,pk/n,x10/13,pp/f,x7/15,s10,x5/13,pk/h,x15/6,s1,x10/11,s12,x9/4,s14,x12/6,s8,pm/p,x0/3,s4,x12/15,pg/l,x13/11,pi/j,x14/3,pc/m,s5,x5/10,s11,x15/14,s15,x7/1,s4,x3/2,pi/j,x13/11,pp/o,x6/5,s11,x4/11,s14,x13/8,s1,x7/15,s10,x6/8,s3,x15/7,s11,pb/a,x9/4,pp/n,x5/6,pe/c,s10,x9/13,s14,x2/0,pf/j,x15/3,s12,x8/7,s12,x10/3,s9,x9/7,s1,x4/10,pp/b,x5/14,s9,pl/h,x3/15,pd/k,x12/10,s2,x1/9,pl/p,x8/5,s14,x2/3,pk/a,x8/13,s11,x12/10,s4,x3/4,s13,x12/5,s12,x8/10,ph/d,x5/15,s14,x8/6,s12,x9/14,s15,x4/0,pb/c,s13,x13/12,s4,x0/11,s14,x15/8,ph/k,x2/4,s6,pi/b,x1/7,pc/o,x12/4,pg/a,x15/3,s9,x2/14,pi/j,x9/6,s10,x2/8,s4,x6/3,s15,x12/5,s2,x3/13,s12,x4/8,s12,x9/3,s11,x6/8,pb/c,x13/5,pp/o,x9/8,pa/g,x12/7,s8,x2/0,pi/d,s5,x10/5,pj/b,x7/8,pp/c,x2/13,s8,x4/9,s1

In [44]:
input_data = None
with open('day16_input.txt') as f:
    input_data = list(map(lambda s: (s[0],s[1:]) if s[0] == 's' else (s[0], tuple(s[1:].split('/'))), f.read().strip().split(",")))

part 1


In [107]:
def one_dance_move(programs, command, params):
    if command == 's':
        index = int(params)
        programs = programs[-index:] + programs[:-index]
    elif command == 'x':
        i1,i2 = tuple(map(int, params))
        c1, c2 = programs[i1], programs[i2]
        programs = programs.replace(c1,'z')
        programs = programs.replace(c2,c1)
        programs = programs.replace('z',c2)
    elif command == 'p':
        c1,c2 = params
        programs = programs.replace(c1,'z')
        programs = programs.replace(c2,c1)
        programs = programs.replace('z',c2)
    return programs

def danceit1(data, programs=None, length=16):
    programs = "".join([chr(ord('a')+i) for i in range(length)]) if programs is None else programs
    for command, params in data:
        programs = one_dance_move(programs, command, params)
    return programs

In [108]:
danceit1([('s','1'),('x',('3','4')),('p',('e','b'))], length=5) == 'baedc'


Out[108]:
True

In [109]:
danceit1(input_data, length=16)


Out[109]:
'jkmflcgpdbonihea'

part 2


In [121]:
def danceit2(data, length=16, rounds=int(1e9)):
    programs = "".join([chr(ord('a')+i) for i in range(length)])
    
    # lets find the cycle
    hash_map = {}
    prev_programs = programs
    cycle_round = None
    recycled_programs = None
    for r in range(rounds):
        programs = danceit1(input_data, prev_programs)
        if prev_programs in hash_map:
            cycle_round = r
            recycled_programs = prev_programs
            break
        hash_map[prev_programs] = programs
        prev_programs = programs
    
    # thru inspection we know its the same starting pattern
    # 'abcdefghijklmnop' occuring again, hence just harding coding this
    # if we need a general program, we need to process hash table to 
    # figure out the starting and the ending cycle and form the transformation as necessary
    programs = "".join([chr(ord('a')+i) for i in range(length)])
    for r in range(rounds%cycle_round):
        programs = danceit1(input_data, programs)
        
    print("----aftr",programs)
    return programs

In [122]:
danceit2(input_data)


----aftr ajcdefghpkblmion
Out[122]:
'ajcdefghpkblmion'

Day 17: Spinlock


In [4]:
input_data = 348
sample_data = 3

part 1


In [24]:
def spin_lock_insert(spin_size, last_insert=2017):
    current_insert = 2
    current_position = 1
    buffer = [0, 1]
    while current_insert <= last_insert:
        current_len = len(buffer)
        # inserting right after current_position
        # current_position = current_position + spin_size + 1
        # current_position = current_position % current_len if current_position > current_len else current_position
        current_position = ((current_position + spin_size) % current_len) + 1
        
        # print("b4",buffer, current_position)
        # print("b4",buffer[:current_position],[current_insert],buffer[current_position:])
        
        # buffer = buffer[:current_position] + [current_insert] + buffer[current_position:]
        buffer[current_position:current_position] = [current_insert]
        
        current_insert += 1
        # print("aftr",buffer, current_position)
        # print("------------------------")
    return buffer[buffer.index(2017) + 1]

In [25]:
spin_lock_insert(sample_data, last_insert=2017) == 638


Out[25]:
True

In [26]:
spin_lock_insert(input_data, last_insert=2017)


Out[26]:
417

part 2


In [29]:
def spin_lock_insert2(spin_size):
    current_position = 0
    insert_at_1 = 1
    # current_len is also the current_insert from prev part
    for current_len in range(1,int(5e7)+1):
        current_position = ((current_position + spin_size) % current_len) + 1
        # if we are inserting right after 0
        if current_position == 1:
            insert_at_1 = current_len
        # print("aftr",buffer, current_position)
        # print("------------------------")
    return insert_at_1

In [30]:
spin_lock_insert2(input_data)


Out[30]:
34334221

Day 18: Duet


In [1]:
#!cat day18_input.txt

In [3]:
input_data = None
with open("day18_input.txt") as f:
    input_data = [(inst.split()[0],tuple(inst.split()[1:]))  for inst in f.read().strip().split("\n")]
len(input_data), input_data[0]


Out[3]:
(41, ('set', ('i', '31')))

part 1


In [14]:
import operator

def is_digit(n):
    try:
        int(n)
        return True
    except ValueError:
        return  False
        
def process_instructions1(data):
    registers = {}
    played = {}
        
    get_register = lambda x: int(x) if is_digit(x) else registers.setdefault(x, 0)
    get_played = lambda x: played[x] if x in played else played.setdefault(x, 0)

    def get_operator_fn(op):
        return {
        'set' : lambda x,y: registers.update({x:get_register(y)}) ,
        'add' : lambda x,y: registers.update({x:get_register(x) + get_register(y)}) ,
        'mul' : lambda x,y: registers.update({x:get_register(x) * get_register(y)}) ,
        'mod' : lambda x,y: registers.update({x:get_register(x) % get_register(y)}) ,
        'snd' : lambda x: played.update({x:get_register(x)}),
        'rcv' : lambda x: get_played(x),
        }[op]

    current_cmd = None
    current_index = 0
    last_played_sound = 0
    while last_played_sound == 0:
        current_cmd, params = data[current_index]
        
        if current_cmd == 'jgz':
            if get_register(params[0]) > 0:
                current_index += int(params[1])
                # print("----", current_index, registers)
                continue
        else:  
            output = get_operator_fn(current_cmd)(*params)
        
        # print("----",current_cmd, params, output)
        if current_cmd == 'rcv' and output is not None:
            last_played_sound = output
            
        # print("----", current_index, registers)     
        # print("----", current_index, played)     
        current_index += 1
        
    return last_played_sound

In [15]:
sample_data = """set a 1
add a 2
mul a a
mod a 5
snd a
set a 0
rcv a
jgz a -1
set a 1
jgz a -2
"""
sample_data = [(inst.split()[0],tuple(inst.split()[1:]))  for inst in sample_data.strip().split("\n")]
sample_data


Out[15]:
[('set', ('a', '1')),
 ('add', ('a', '2')),
 ('mul', ('a', 'a')),
 ('mod', ('a', '5')),
 ('snd', ('a',)),
 ('set', ('a', '0')),
 ('rcv', ('a',)),
 ('jgz', ('a', '-1')),
 ('set', ('a', '1')),
 ('jgz', ('a', '-2'))]

In [16]:
process_instructions1(sample_data) == 4


Out[16]:
True

In [17]:
process_instructions1(input_data)


Out[17]:
7071

part 2


In [82]:
import queue as q

def process_instructions2(data):
    registers = {0: {'p':0}, 1:{'p':1}}
    status = {0: 'active', 1:'active'} # waiting
    current_index = {0: 0, 1:0}
    nof_sends = {0: 0, 1:0}
    q1 = [] # q.Queue() # send for 0, recv for 1
    q2 = [] # q.Queue() # send for 1, recv for 0
    queues = {0: (q1, q2), 1: (q2, q1)} # index 0-> send, index 1-> recv
    snd_qindex, rcv_qindex = 0,1
    
    
    # p refers to program id
    get_register = lambda p,x: int(x) if is_digit(x) else registers[p].setdefault(x, 0)
    def get_operator_fn(p,op):
        return {
        'set' : lambda x,y: registers[p].update({x:get_register(p,y)}) ,
        'add' : lambda x,y: registers[p].update({x:get_register(p,x) + get_register(p,y)}) ,
        'mul' : lambda x,y: registers[p].update({x:get_register(p,x) * get_register(p,y)}) ,
        'mod' : lambda x,y: registers[p].update({x:get_register(p,x) % get_register(p,y)}) ,
        }[op]
    
    pgm_id = 0
    while True:
        if len(queues[pgm_id][rcv_qindex]) == 0 and status[0] == 'waiting' and  status[1] == 'waiting':
            # deadlock if both the rcv qs are empty
            break
                        
        cmd, params = data[current_index[pgm_id]]
        # print("--- {}: {} -> {}".format(pgm_id, cmd, params) )
        
        if cmd == 'jgz':
            if get_register(pgm_id, params[0]) > 0:
                current_index[pgm_id] += get_register(pgm_id, params[1])
                continue
        elif cmd == 'snd':
            queues[pgm_id][snd_qindex].append(get_register(pgm_id, params[0]))
            nof_sends[pgm_id] += 1
        elif cmd == 'rcv':
            if len(queues[pgm_id][rcv_qindex]) == 0:
                if status[pgm_id] == 'active':
                    status[pgm_id] = 'waiting'
                pgm_id = 1 - pgm_id # this just oscillates between 0 and 1
                continue
            else:
                val = queues[pgm_id][rcv_qindex].pop(0)
                registers[pgm_id].update({params[0]: val})
                status[pgm_id] = 'active'
        else:  
            # normal operation non snd/rcv
            output = get_operator_fn(pgm_id, cmd)(*params)
            
        current_index[pgm_id] += 1 
    
    print("\n---- Done bitches",nof_sends, current_index, list(q1), list(q2))
    return nof_sends[1]

In [83]:
sample_data = """snd 1
snd 2
snd p
rcv a
rcv b
rcv c
rcv d
"""
sample_data = [(inst.split()[0],tuple(inst.split()[1:]))  for inst in sample_data.strip().split("\n")]
sample_data


Out[83]:
[('snd', ('1',)),
 ('snd', ('2',)),
 ('snd', ('p',)),
 ('rcv', ('a',)),
 ('rcv', ('b',)),
 ('rcv', ('c',)),
 ('rcv', ('d',))]

In [84]:
process_instructions2(sample_data)


---- Done bitches {0: 3, 1: 3} {0: 6, 1: 6} [] []
Out[84]:
3

In [85]:
process_instructions2(input_data)


---- Done bitches {0: 8128, 1: 8001} {0: 21, 1: 21} [] []
Out[85]:
8001

Day 19: A Series of Tubes


In [87]:
#!cat day19_input.txt

In [2]:
input_data = None
with open("day19_input.txt") as f:
    input_data = [ list(line) for line in f.read().split("\n")]
del input_data[-1]
len(input_data), " ".join(map(str,[len(sd) for sd in input_data]))


Out[2]:
(201,
 '201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201 201')

In [3]:
sample_input="""     |          
     |  +--+    
     A  |  C    
 F---|----E|--+ 
     |  |  |  D 
     +B-+  +--+ 
"""
sample_data = [ list(line) for line in sample_input.split("\n")]
del sample_data[-1]
len(sample_data), [len(sd) for sd in sample_data]


Out[3]:
(6, [16, 16, 16, 16, 16, 16])

part 1


In [19]:
def traverse_path1(data):
    cur_row_col = (0,0) # row, col
    for i,ch in enumerate(data[0]):
        if ch == '|':
            cur_row_col = (0,i)
    # print("----start",cur_row_col)
    
    update_dir = {
        'up': (-1,0),
        'down': (1,0),
        'right': (0,1),
        'left': (0,-1)
    }
    mirror_dir = {
        'up': 'down',
        'down': 'up',
        'right': 'left',
        'left': 'right'
    }
    tuple_sum = lambda t1,t2: (t1[0]+t2[0], t1[1]+t2[1])
    
    def next_rc(cur_rc, cur_d):
        ch = data[cur_rc[0]][cur_rc[1]]
        # print("---",cur_rc, ch)
        
        if str.isalpha(ch):
            cur_rc = tuple_sum(cur_rc,update_dir[cur_d])
            return (cur_rc, cur_d, ch)
        
        elif ch == '|':
            new_rc = tuple_sum(cur_rc,update_dir[cur_d])
            if data[new_rc[0]][new_rc[1]] == '-':
                new_rc = tuple_sum(new_rc,update_dir[cur_d])
            return (new_rc, cur_dir, None)

        elif ch == '-':
            new_rc = tuple_sum(cur_rc,update_dir[cur_d])
            if data[new_rc[0]][new_rc[1]] == '|':
                new_rc = tuple_sum(new_rc,update_dir[cur_d])
            return (new_rc, cur_dir, None)
            
        elif ch == '+':
            # print(list(set(update_dir.keys())-set([cur_d])))
            for d in list(set(update_dir.keys())-set([mirror_dir[cur_d]])):
                rc = tuple_sum(cur_rc,update_dir[d])
                if data[rc[0]][rc[1]] != " ":
                    return (rc, d, None)
                
        return (None, None, None)
    
    cur_dir = 'down'
    letters = ""
    while True:
        (cur_row_col,cur_dir,letter) = next_rc(cur_row_col,cur_dir)
        # print((cur_row_col,cur_dir,letter))
        letters += "" if letter is None else letter
        if cur_dir == None:
            break
        
    # print("----", letters)
    return letters

In [20]:
assert traverse_path1(sample_data) == 'ABCDEF'

In [21]:
traverse_path1(input_data)


Out[21]:
'GPALMJSOY'

part 2


In [34]:
def traverse_path2(data):
    cur_row_col = (0,0) # row, col
    for i,ch in enumerate(data[0]):
        if ch == '|':
            cur_row_col = (0,i)
    # print("----start",cur_row_col)
    
    update_dir = {
        'up': (-1,0),
        'down': (1,0),
        'right': (0,1),
        'left': (0,-1)
    }
    mirror_dir = {
        'up': 'down',
        'down': 'up',
        'right': 'left',
        'left': 'right'
    }
    
    tuple_sum = lambda t1,t2: (t1[0]+t2[0], t1[1]+t2[1])
    
    steps = 0
    def next_rc(cur_rc, cur_d):
        nonlocal steps
        ch = data[cur_rc[0]][cur_rc[1]]
        # print("---",cur_rc, ch)
        
        if str.isalpha(ch):
            cur_rc = tuple_sum(cur_rc,update_dir[cur_d])
            steps += 1
            return (cur_rc, cur_d, ch)
        
        elif ch == '|':
            new_rc = tuple_sum(cur_rc,update_dir[cur_d])
            steps += 1
            if data[new_rc[0]][new_rc[1]] == '-':
                new_rc = tuple_sum(new_rc,update_dir[cur_d])
                steps += 1
            return (new_rc, cur_dir, None)

        elif ch == '-':
            new_rc = tuple_sum(cur_rc,update_dir[cur_d])
            steps += 1
            if data[new_rc[0]][new_rc[1]] == '|':
                new_rc = tuple_sum(new_rc,update_dir[cur_d])
                steps += 1
            return (new_rc, cur_dir, None)
            
        elif ch == '+':
            # print(list(set(update_dir.keys())-set([cur_d])))
            for d in list(set(update_dir.keys())-set([mirror_dir[cur_d]])):
                rc = tuple_sum(cur_rc,update_dir[d])
                if data[rc[0]][rc[1]] != " ":
                    steps += 1
                    return (rc, d, None)
                
        return (None, None, None)
    
    cur_dir = 'down'
    letters = ""
    while True:
        (cur_row_col,cur_dir,letter) = next_rc(cur_row_col,cur_dir)
        # print((cur_row_col,cur_dir,letter))
        letters += "" if letter is None else letter
        if cur_dir == None:
            break
        
    # print("----", letters)
    return steps

In [36]:
assert traverse_path2(sample_data) == 38

In [37]:
traverse_path2(input_data)


Out[37]:
16204

Day 20: Particle Swarm


In [42]:
#!cat day20_input.txt

In [42]:
input_data = {}
with open("day20_input.txt") as f:
    i = 0
    for line in f.read().strip().split("\n"):
        m = re.match("p=<([-]*\d+,[-]*\d+,[-]*\d+)>,\s*v=<([-]*\d+,[-]*\d+,[-]*\d+)>,\s*a=<([-]*\d+,[-]*\d+,[-]*\d+)>\s*", line)
        input_data[i] = {'p':list(map(int, m.group(1).split(','))), 
                        'v':list(map(int, m.group(2).split(','))),
                        'a':list(map(int, m.group(3).split(',')))}
        i += 1
        
len(input_data), input_data[2]


Out[42]:
(1000, {'a': [12, 19, -2], 'p': [-2101, -2706, -1112], 'v': [-19, -66, 75]})

part 1


In [96]:
def swarm_particles1(data_in, simulation_length=5000):
    
    data = data_in.copy()
    def update_new_positions():
        nonlocal data
        for i,particle in data.items():
            # update velocity
            particle['v'][0] += particle['a'][0]
            particle['v'][1] += particle['a'][1]
            particle['v'][2] += particle['a'][2]
            # update position
            particle['p'][0] += particle['v'][0]
            particle['p'][1] += particle['v'][1]
            particle['p'][2] += particle['v'][2]
            
    
    def find_nearest_using_manhattan():
        nonlocal data
        min_dist = float('inf')
        nearest_particle = None
        for i,particle in data.items():
            dist = sum(list(map(abs, particle['p'])))
            if min_dist > dist:
                min_dist = dist
                nearest_particle = i
        
        return nearest_particle
    
    # simulation particle movement
    for i in range(simulation_length):
        update_new_positions()
    
    return find_nearest_using_manhattan()

In [97]:
sample_data = {
    0:{'a': [3,0,0], 'p': [2,0,0], 'v': [-1,0,0]},
    1:{'a': [4,0,0], 'p': [0,0,0], 'v': [-2,0,0]}
}

In [98]:
assert swarm_particles1(sample_data) == 0

In [99]:
swarm_particles1(input_data)


Out[99]:
144

part 2


In [36]:
def swarm_particles2(data_in, simulation_length=5000):
    
    data = copy.deepcopy(data_in)
    
    def update_positions_filter_collisions():
        nonlocal data
            
        inv_p_dict = {}
        colliding_particles = set()
        
        for i,particle in data.items():
            # update velocity
            particle['v'][0] += particle['a'][0]
            particle['v'][1] += particle['a'][1]
            particle['v'][2] += particle['a'][2]
            
            # update position
            particle['p'][0] += particle['v'][0]
            particle['p'][1] += particle['v'][1]
            particle['p'][2] += particle['v'][2]
            p = tuple(particle['p'])

            # current positions
            if p not in inv_p_dict:
                inv_p_dict[p] = i
            else:
                colliding_particles.add(i)
                colliding_particles.add(inv_p_dict[p])
        
        # filter colliding particles
        for i in colliding_particles:
            del data[i]
            
    # simulation particle movement
    for i in range(simulation_length):
        update_positions_filter_collisions()
        
    return len(data)

In [37]:
sample_data = {
0: {'p': [-6,0,0], 'v': [3,0,0], 'a': [0,0,0]},
1: {'p': [-4,0,0], 'v': [2,0,0], 'a': [0,0,0]},
2: {'p': [-2,0,0], 'v': [1,0,0], 'a': [0,0,0]},
3: {'p': [ 3,0,0], 'v': [1,0,0], 'a': [0,0,0]}
}

In [40]:
# assert swarm_particles2(sample_data) == 1
swarm_particles2(sample_data)


Out[40]:
1

In [43]:
swarm_particles2(input_data)


Out[43]:
477

Day 21: Fractal Art


In [ ]:
!cat day21_input.txt

In [ ]:

part 1 (incomplete)


In [ ]:


In [ ]:

part 2 (incomplete)


In [ ]:


In [ ]:

Day 22: Sporifica Virus


In [2]:
#!cat day22_input.txt

In [134]:
input_data = []
with open("day22_input.txt") as f:
    i = 0
    input_data = [list(line) for line in f.read().strip().split("\n")]
len(input_data), len(input_data[0])


Out[134]:
(25, 25)

part 1


In [143]:
def virus_burst1(data, bursts=10000):
    grid_size = bursts//4
    # lets place extra space around the data on sides
    grid = [['.']*(grid_size) + data[i] + ['.']*(grid_size) for i in range(len(data)) ]
    
    # lets place extra space around the data on top and bottom
    grid = [['.' for _ in range(len(grid[0]))] for _ in range(grid_size)] + grid 
    grid += [['.' for _ in range(len(grid[0]))] for _ in range(grid_size)]
    
    # find the starting point
    cur_row, cur_col, cur_dir = len(grid)//2, len(grid[0])//2, 'up'
    
    
    # direction update dictionary
    directions = {
        'up'   : {'left':(0,-1,'left'), 'right':(0,1,'right')},
        'down' : {'left':(0,1,'right'), 'right':(0,-1,'left')},
        'left' : {'left':(1,0,'down'), 'right':(-1,0,'up')},
        'right': {'left':(-1,0,'up'), 'right':(1,0,'down')}
    }
    
    move = lambda rcd,d: (rcd[0]+directions[rcd[2]][d][0], rcd[1]+directions[rcd[2]][d][1], directions[rcd[2]][d][2]) 
    infections = 0 
    for burst in range(bursts):
        # print("\n ----- ",burst,"\n")
        # print("cur_row, cur_col, cur_dir",cur_row, cur_col, cur_dir)
        # print("\n".join(["".join(p) for p in grid]))
        
        # non infected
        if grid[cur_row][cur_col] == '.':
            # print("moving left")
            infections += 1
            grid[cur_row][cur_col] = '#'
            (cur_row,cur_col, cur_dir) = move((cur_row,cur_col, cur_dir), 'left')
        else: # infected
            # print("moving right")
            grid[cur_row][cur_col] = '.'
            (cur_row,cur_col, cur_dir) = move((cur_row,cur_col, cur_dir), 'right')
        
    return infections

In [144]:
sample_data = [['.','.','#'],['#','.','.'],['.','.','.']]

In [145]:
assert virus_burst1(sample_data, bursts=10000) == 5587

In [146]:
virus_burst1(input_data, bursts=10000)


Out[146]:
5460

part 2


In [161]:
def virus_burst2(data, bursts=10000):
    grid_size = 10000 #bursts//4
    # lets place extra space around the data on sides
    grid = [['.']*(grid_size) + data[i] + ['.']*(grid_size) for i in range(len(data)) ]
    
    # lets place extra space around the data on top and bottom
    grid = [['.' for _ in range(len(grid[0]))] for _ in range(grid_size)] + grid 
    grid += [['.' for _ in range(len(grid[0]))] for _ in range(grid_size)]
    
    # find the starting point
    cur_row, cur_col, cur_dir = len(grid)//2, len(grid[0])//2, 'up'
    
    
    # direction update dictionary
    cids = {
                'up'   : {'left':(0,-1,'left'), 'right':(0,1,'right')},
                'down' : {'left':(0,1,'right'), 'right':(0,-1,'left')},
                'left' : {'left':(1,0,'down'), 'right':(-1,0,'up')},
                'right': {'left':(-1,0,'up'), 'right':(1,0,'down')}
        }
    
    wfds = {
        'w': {
                'up'   : (-1,0,'up'),
                'down' : (1,0,'down'),
                'left' : (0,-1,'left'),
                'right': (0,1,'right')
        },
        'f': {
                'up'   : (1,0,'down'),
                'down' : (-1,0,'up'),
                'left' : (0,1,'right'),
                'right': (0,-1,'left')
        }
    }

    move_ci = lambda r,c,d,t: (r+cids[d][t][0], c+cids[d][t][1], cids[d][t][2])
    move_wf = lambda r,c,d,s: (r+wfds[s][d][0], c+wfds[s][d][1], wfds[s][d][2])
    
    infections = 0 
    for burst in range(bursts):
        # print("\n ----- ",burst,"\n")
        # print("cur_row, cur_col, cur_dir",cur_row, cur_col, cur_dir)
        # print("\n".join(["".join(p) for p in grid]))
        
        if grid[cur_row][cur_col] == '.': # clean
            # print("moving left")
            grid[cur_row][cur_col] = 'w'
            (cur_row,cur_col, cur_dir) = move_ci(cur_row, cur_col, cur_dir, 'left')
            
        elif grid[cur_row][cur_col] == 'w': # weakened
            # print("no turn moving left")
            infections += 1
            grid[cur_row][cur_col] = '#'
            (cur_row,cur_col, cur_dir) = move_wf(cur_row, cur_col, cur_dir, 'w')

        elif grid[cur_row][cur_col] == '#': # infected
            # print("moving right")
            grid[cur_row][cur_col] = 'f'
            (cur_row,cur_col, cur_dir) = move_ci(cur_row, cur_col, cur_dir, 'right')
            
        else: # flagged
            # print("reverses moving right")
            grid[cur_row][cur_col] = '.'
            (cur_row,cur_col, cur_dir) = move_wf(cur_row, cur_col, cur_dir, 'f')
        
    return infections

In [162]:
sample_data = [['.','.','#'],['#','.','.'],['.','.','.']]

In [163]:
assert virus_burst2(sample_data, bursts=100) == 26
assert virus_burst2(sample_data, bursts=10000000) == 2511944

In [164]:
virus_burst2(input_data, bursts=10000000)


Out[164]:
2511702

Day 23: Coprocessor Conflagration


In [ ]:
# !cat day23_input.txt

In [52]:
input_data = None
with open("day23_input.txt") as f:
    input_data = [(inst.split()[0],tuple(inst.split()[1:]))  for inst in f.read().strip().split("\n")]
len(input_data), input_data


Out[52]:
(32,
 [('set', ('b', '84')),
  ('set', ('c', 'b')),
  ('jnz', ('a', '2')),
  ('jnz', ('1', '5')),
  ('mul', ('b', '100')),
  ('sub', ('b', '-100000')),
  ('set', ('c', 'b')),
  ('sub', ('c', '-17000')),
  ('set', ('f', '1')),
  ('set', ('d', '2')),
  ('set', ('e', '2')),
  ('set', ('g', 'd')),
  ('mul', ('g', 'e')),
  ('sub', ('g', 'b')),
  ('jnz', ('g', '2')),
  ('set', ('f', '0')),
  ('sub', ('e', '-1')),
  ('set', ('g', 'e')),
  ('sub', ('g', 'b')),
  ('jnz', ('g', '-8')),
  ('sub', ('d', '-1')),
  ('set', ('g', 'd')),
  ('sub', ('g', 'b')),
  ('jnz', ('g', '-13')),
  ('jnz', ('f', '2')),
  ('sub', ('h', '-1')),
  ('set', ('g', 'b')),
  ('sub', ('g', 'c')),
  ('jnz', ('g', '2')),
  ('jnz', ('1', '3')),
  ('sub', ('b', '-17')),
  ('jnz', ('1', '-23'))])

part 1


In [46]:
import operator

def is_digit(n):
    try:
        int(n)
        return True
    except ValueError:
        return  False
        
def coprocessing1(data):
    registers = {}
    played = {}
        
    get_register = lambda x: int(x) if is_digit(x) else registers.setdefault(x, 0)
    get_played = lambda x: played[x] if x in played else played.setdefault(x, 0)

    def get_operator_fn(op):
        return {
        'set' : lambda x,y: registers.update({x:get_register(y)}) ,
        'sub' : lambda x,y: registers.update({x:get_register(x) - get_register(y)}) ,
        'mul' : lambda x,y: registers.update({x:get_register(x) * get_register(y)}) ,
        }[op]

    current_cmd = None
    current_index = 0
    nof_muls = 0
    while current_index < len(data):
        current_cmd, params = data[current_index]
        print("----", current_index, current_cmd, params, registers)
        
        if current_cmd == 'mul':
            nof_muls += 1
            
        if current_cmd == 'jnz':
            if get_register(params[0]) != 0:
                current_index += int(params[1])
                #print("----", current_index, registers)
                continue
        else:  
            get_operator_fn(current_cmd)(*params)

        current_index += 1
        
    return nof_muls

In [47]:
sample_data = """set a 1
sub a 2
mul a a
set a 0
jnz a -1
set a 0
mul a a
jnz a -2
"""
sample_data = [(inst.split()[0],tuple(inst.split()[1:]))  for inst in sample_data.strip().split("\n")]
sample_data


Out[47]:
[('set', ('a', '1')),
 ('sub', ('a', '2')),
 ('mul', ('a', 'a')),
 ('set', ('a', '0')),
 ('jnz', ('a', '-1')),
 ('set', ('a', '0')),
 ('mul', ('a', 'a')),
 ('jnz', ('a', '-2'))]

In [48]:
coprocessing1(sample_data)


Out[48]:
2

In [49]:
coprocessing1(input_data)


Out[49]:
6724

part 2


In [62]:
import operator

def is_digit(n):
    try:
        int(n)
        return True
    except ValueError:
        return  False
        
def coprocessing2(data):
    registers = {'a':1}
    played = {}
        
    get_register = lambda x: int(x) if is_digit(x) else registers.setdefault(x, 0)
    get_played = lambda x: played[x] if x in played else played.setdefault(x, 0)

    def get_operator_fn(op):
        return {
        'set' : lambda x,y: registers.update({x:get_register(y)}) ,
        'sub' : lambda x,y: registers.update({x:get_register(x) - get_register(y)}) ,
        'mul' : lambda x,y: registers.update({x:get_register(x) * get_register(y)}) ,
        }[op]

    current_cmd = None
    
    # at current index 20
    # registers = {'a': 1, 'b': 108400, 'c': 125400, 'f': 1, 'd': 2, 'e': 108400, 'g': 0}
    # current_index = 20
    # at current index 25
    registers = {'a': 1, 'b': 108400, 'c': 125400, 'f': 1, 'd': 108400, 'e': 108400, 'g': 0}
    current_index = 25

    while current_index < len(data):
        current_cmd, params = data[current_index]
        print("----", current_index, current_cmd, params, registers)
            
        if current_cmd == 'jnz':
            if get_register(params[0]) != 0:
                current_index += int(params[1])
                #print("----", current_index, registers)
                continue
        else:  
            get_operator_fn(current_cmd)(*params)

        current_index += 1
        
    return registers['h']

In [65]:
# coprocessing2(input_data)

In [68]:
count = 0
for num in range(108400,125400 + 1, 17):
    for i in range(2,num):
        if (num % i) == 0:
            count += 1
            break
print(count)


903

Day 24: Electromagnetic Moat


In [3]:
# !cat day24_input.txt

In [2]:
input_data = []
with open("day24_input.txt") as f:
    for line in f.read().strip().split("\n"):
        input_data += [list(map(int,line.strip().split('/')))]
            
len(input_data)
# input_data


Out[2]:
57

In [13]:
sample_input ="""0/2
2/2
2/3
3/4
3/5
0/1
10/1
9/10"""
sample_data = []
for line in sample_input.strip().split("\n"):
    sample_data += [list(map(int,line.strip().split('/')))]
sample_data


Out[13]:
[[0, 2], [2, 2], [2, 3], [3, 4], [3, 5], [0, 1], [10, 1], [9, 10]]

part 1


In [14]:
def emMoat1(components, last_port):
    max_strength = 0
    bridge = []
    max_strength_bridge = []
    for i, component in enumerate(components):
        if component[0] == last_port or component[1] == last_port:
            new_components = components[:i]+components[i+1:]
            new_last_port = component[0] if component[1] == last_port else  component[1]
            bridge = component +  emMoat1(new_components, new_last_port)
            strength = sum(bridge)
            if strength > max_strength:
                max_strength = strength
                max_strength_bridge = bridge
    return max_strength_bridge

In [7]:
assert sum(emMoat1(sample_data, 0)) == 31

In [8]:
sum(emMoat1(input_data, 0))


Out[8]:
1695

part 2


In [28]:
def emMoat2(components, last_port):
    max_long_strength = 0
    max_length = 0
    bridge = []
    long_max_strength_bridge = []
    for i, component in enumerate(components):
        if component[0] == last_port or component[1] == last_port:
            new_components = components[:i]+components[i+1:]
            new_last_port = component[0] if component[1] == last_port else  component[1]
            bridge = component +  emMoat2(new_components, new_last_port)
            strength = sum(bridge)
            length = len(bridge)
            if length > max_length:
                max_long_strength, max_length = strength, length
                long_max_strength_bridge = bridge
            elif length == max_length:
                if strength > max_long_strength:
                    max_long_strength, max_length = strength, length
                    long_max_strength_bridge = bridge
                
    return long_max_strength_bridge

In [31]:
assert sum(emMoat2(sample_data, 0)) == 19

In [30]:
sum(emMoat2(input_data, 0))


Out[30]:
1673

Day 25: The Halting Problem


In [2]:
!cat day25_input.txt


Begin in state A.
Perform a diagnostic checksum after 12317297 steps.

In state A:
  If the current value is 0:
    - Write the value 1.
    - Move one slot to the right.
    - Continue with state B.
  If the current value is 1:
    - Write the value 0.
    - Move one slot to the left.
    - Continue with state D.

In state B:
  If the current value is 0:
    - Write the value 1.
    - Move one slot to the right.
    - Continue with state C.
  If the current value is 1:
    - Write the value 0.
    - Move one slot to the right.
    - Continue with state F.

In state C:
  If the current value is 0:
    - Write the value 1.
    - Move one slot to the left.
    - Continue with state C.
  If the current value is 1:
    - Write the value 1.
    - Move one slot to the left.
    - Continue with state A.

In state D:
  If the current value is 0:
    - Write the value 0.
    - Move one slot to the left.
    - Continue with state E.
  If the current value is 1:
    - Write the value 1.
    - Move one slot to the right.
    - Continue with state A.

In state E:
  If the current value is 0:
    - Write the value 1.
    - Move one slot to the left.
    - Continue with state A.
  If the current value is 1:
    - Write the value 0.
    - Move one slot to the right.
    - Continue with state B.

In state F:
  If the current value is 0:
    - Write the value 0.
    - Move one slot to the right.
    - Continue with state C.
  If the current value is 1:
    - Write the value 0.
    - Move one slot to the right.
    - Continue with state E.

In [7]:
input_steps = 12317297
input_table={
    'A':{ 0: (1,1,'B'), 1:(0,-1,'D') },
    'B':{ 0: (1,1,'C'), 1:(0,1,'F') },
    'C':{ 0: (1,-1,'C'), 1:(1,-1,'A') },
    'D':{ 0: (0,-1,'E'), 1:(1,1,'A') },
    'E':{ 0: (1,-1,'A'), 1:(0,1,'B') },
    'F':{ 0: (0,1,'C'),  1:(0,1,'E') },
}

sample_steps = 6
sample_table={
    'A':{ 0: (1,1,'B'), 1:(0,-1,'B') },
    'B':{ 0: (1,-1,'A'), 1:(1,1,'A') },
}

part 1


In [8]:
def executeTuringMachine(table, steps):
    tape = [0 for i in range(10000)]
    cursor = 500 # current index
    next_state = 'A' # begining state
    
    for i in range(steps):
        new_value, cursor_update, next_state = table[next_state][tape[cursor]]
        tape[cursor] = new_value
        cursor += cursor_update
        
    return sum(tape)

In [10]:
assert executeTuringMachine(table=sample_table, steps=sample_steps) == 3

In [ ]:
executeTuringMachine(table=input_table, steps=input_steps)

part 2


In [ ]: