<jupyter_start><jupyter_text>Q1.1<jupyter_code># Q1.1 and Q2.1: Consider the case where d=4, n=10, and m=10.
# How many valid walks start from the corner (0, 0, 0, 0)?

d = 4   # 4, 8
n = 10  # 10, 12
m = 10  # 10, 12
origin = [0] * d 

resQ11 = sol.validWalkNum(origin, d, n, m)

print(f"How many valid walks start from the corner {origin}?")
print("Answer:", resQ11)<jupyter_output>How many valid walks start from the corner [0, 0, 0, 0]?
Answer: 44569724<jupyter_text>Q1.2<jupyter_code># Q1.2: Consider the case where d=4, n=10, and m=10.
# Consider the count of valid walks associated with each possible starting position. What is the ratio of the highest count of valid walks to smallest count of valid walks?

dictQ12 = dict()

for position in product(range(n), repeat=d):
    
    position = list(position)
    if str(position) in dictQ12:
        continue
    numWays = sol.validWalkNum(position, d, n, m)
    dictQ12[str(position)] = numWays 
    
    
    # Other Symmetric Positions
    for newPos in product([position[0], n - 1 - position[0]], [position[1], n - 1 - position[1]],
                          [position[2], n - 1 - position[2]], [position[3], n - 1 - position[3]]):
        # newPos is a list
        for newPos2 in list(permutations(newPos)):
            # newPos2 is a tuple
            newPos2 = list(newPos2)
            if str(newPos2) in dictQ12:
                continue
            dictQ12[str(newPos2)] = numWays


            
values = list(dictQ12.values())

print("What is the ratio of the highest count of valid walks to smallest count of valid walks?")
print(max(values)/min(values))<jupyter_output>What is the ratio of the highest count of valid walks to smallest count of valid walks?
23.81209118548726<jupyter_text>Q1.3<jupyter_code># Q1.3 Consider the case where d=4, n=10, and m=10.
# Consider the count of valid walks associated with each possible starting position. 
# What is the ratio of the standard deviation of the number of valid walks to the mean of the number of valid walks?

print("What is the ratio of the standard deviation of the number of valid walks to the mean\
        of the number of valid walks?")
print(np.std(values)/np.mean(values))<jupyter_output>What is the ratio of the standard deviation of the number of valid walks to the mean        of the number of valid walks?
0.5106573744484553<jupyter_text>Q2.1<jupyter_code># Q1.1 and Q2.1: Consider the case where d=4, n=10, and m=10.
# How many valid walks start from the corner (0, 0, 0, 0)?

d = 8   # 4, 8
n = 12  # 10, 12
m = 12  # 10, 12
origin = [0] * d 

resQ11 = sol.validWalkNum(origin, d, n, m)

print(f"How many valid walks start from the corner {origin}?")
print("Answer:", resQ11)<jupyter_output>How many valid walks start from the corner [0, 0, 0, 0, 0, 0, 0, 0]?
Answer: 2479092118264<jupyter_text>Q2.2<jupyter_code># Q2.2: Consider the case where d=8, n=12, and m=12.
# Consider the count of valid walks associated with each possible starting position. What is the ratio of the highest count of valid walks to smallest count of valid walks?
# Generate unique points

digitMax = n//2 - 1
uniqPoints = [[0]*d]
cur = [0] * d
while cur != [digitMax] * d:
    if cur[-1] < digitMax:
        cur[-1] += 1
        uniqPoints.append(cur[:])
    else:
        for pivot in reversed(range(d)):
            # print(pivot)
            # print(cur)
            if cur[pivot] < digitMax:
                cur[pivot] += 1
                cur[pivot+1:] = [cur[pivot]] * (d - pivot - 1)
                uniqPoints.append(cur[:])
                break
                
print(len(uniqPoints))  # list of lists

# Each unique points can generate how many symmetry points
def removeDupUpToPerm(input):
    """
    input: list of tuples, each tuple is d dimensional coordinate in N-D Space
    """
    return set(tuple(sorted(x)) for x in input) 

uniquePointToNumSymPoints = dict()

for uniqPoint in uniqPoints:
    # print(uniqPoint)
    
    # Step 1: generate symmetry points on each axis 

    allSymPoints = set()
    symmetryPoints = list(product([uniqPoint[0], n - 1 - uniqPoint[0]], [uniqPoint[1], n - 1 - uniqPoint[1]],
                          [uniqPoint[2], n - 1 - uniqPoint[2]], [uniqPoint[3], n - 1 - uniqPoint[3]],
                          [uniqPoint[4], n - 1 - uniqPoint[4]], [uniqPoint[5], n - 1 - uniqPoint[5]], 
                          [uniqPoint[6], n - 1 - uniqPoint[6]], [uniqPoint[7], n - 1 - uniqPoint[7]]))
    #print(symmetryPoints)  # list of tuple
    
    # Step 1.1: remove duplicates up to coordinate permutation
    # e.g. input = [(0,0,2), (0,4,2), (4,0,2), (4,4,2), (4,0,2), (0,4,2), (4,4,2)] 
    #      output: {(0, 2, 4), (0, 0, 2), (2, 4, 4)}
    symmetryPoints = removeDupUpToPerm(symmetryPoints)  # set of tuple
    
    # print("after remove")
    # print(symmetryPoints)
    
    # Step 2: for each symmetry points, further compute how many symmetry points it can generate
    # e.g. (0,0,2) has 3, they are (0,0,2), (0,2,0), (2,0,0)
    #      formula is 3!/2!
    # python: np.unique((1,1,2,2,3,3,3,4),return_counts=True), return (array([1, 2, 3, 4]), array([2, 2, 3, 1]))
    num = 0
    for symmetryPoint in symmetryPoints:
        _, denominator = np.unique(symmetryPoint, return_counts=True)
        num += math.factorial(d) / np.prod([math.factorial(i) for i in denominator])
        # print(num)
    uniquePointToNumSymPoints[tuple(uniqPoint)] = int(num)

print(uniquePointToNumSymPoints) # dict: {tuple: int}
# # Single Core: 
# uniquePointToWays = dict()
# for i, uniqPoint in enumerate(uniqPoints):
#     print("Finish {:.2%}".format(i/len(uniqPoints)))
#     uniquePointToWays[tuple(uniqPoint)] = sol.validWalkNum(uniqPoint, d, n, m)
    
# # ###########################################
# Use All 6 cores
from multiprocessing import Process, Manager
import multiprocessing

def f(d, uniqPoints):
    for i, uniqPoint in enumerate(uniqPoints):
        # print(i, uniqPoint)
        print(f"{multiprocessing.current_process()} Finish {i/len(uniqPoints):.2%}")
        uniquePointToWays[tuple(uniqPoint)] = sol.validWalkNum(uniqPoint, d, n, m)


manager = Manager()

uniquePointToWays = manager.dict()

c1, c2, c3, c4, c5 = len(uniqPoints) // 6, 2*len(uniqPoints) // 6, 3* len(uniqPoints) // 6, \
                            4* len(uniqPoints) // 6, 5* len(uniqPoints) // 6 

p1 = Process(target=f, args=(d, uniqPoints[:c1]))
p2 = Process(target=f, args=(d, uniqPoints[c1:c2]))
p3 = Process(target=f, args=(d, uniqPoints[c2:c3]))
p4 = Process(target=f, args=(d, uniqPoints[c3:c4]))
p5 = Process(target=f, args=(d, uniqPoints[c4:c5]))
p6 = Process(target=f, args=(d, uniqPoints[c5:]))

p1.start()
p2.start()
p3.start()
p4.start()
p5.start()
p6.start()

p1.join()
p2.join()
p3.join()
p4.join()
p5.join()
p6.join()


resQ22 = []
for uniqPoint in uniqPoints:
    resQ22.append([uniquePointToWays[tuple(uniqPoint)]] * uniquePointToNumSymPoints[tuple(uniqPoint)])
    
print("What is the ratio of the standard deviation of the number of valid walks to the mean\
        of the number of valid walks?")
print(np.std(resQ22)/np.mean(resQ22))
import pickle
file = open('res.pickle', 'rb')

# dump information to that file
data = pickle.load(file)
# close the file
file.close()

print(12**8)
print(sum(data.values()))

Q_sum = 0
for ways, symPoints in data.items():
    Q_sum += ways * symPoints

Q_mean = Q_sum/sum(data.values())
print("Mean no. of ways is", Q_mean)

up = 0

for ways, symPoints in data.items():
    up += np.abs(ways - Q_mean) **2 * symPoints

Q_std = np.sqrt(up/sum(data.values()))
print("Std no. of ways is", Q_std)

print(Q_std/Q_mean)<jupyter_output>429981696
429981696
Mean no. of ways is 124569755771678.3
Std no. of ways is 64199008139878.055
0.5153659308568228<jupyter_text>Q2.3<jupyter_code># Q2.3 Consider the case where d=8, n=12, and m=12.
# Consider the count of valid walks associated with each possible starting position. 
# What is the ratio of the standard deviation of the number of valid walks to the mean of the number of valid walks?
print("What is the ratio of the highest count of valid walks to smallest count of valid walks?")

up = sol.validWalkNum([5,5,5,5,5,5,5,5], d, n, m)
down = sol.validWalkNum([0,0,0,0,0,0,0,0], d, n, m)

print("max is", up)
print("min is", down)
print("ratio is", up/down)

data = (1, 2, 3, [[1,2,3],[4,5,6]], ['a','b','c'])
with open('data.pickle', 'wb') as f:
    pickle.dump(data, f)
    
infile = open("file.pkl", "rb")
tmp = pickle.load(infile)
infile.close()
import numpy as np

a = np.array([[1,2,3,4,5,6,4,2,4,5]])
print(np.std(a))
print(np.sqrt(np.mean(abs(a - a.mean())**2)))
a = {1:2, 2:3, 3:4}
b = {1:2, 2:3, 3:4}
np.inner(list(a.values()), list(b.values()))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14802933088909256, 'fraction_numerical': 0.054651695692025666, 'mean_word_length': 3.39305485656769, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '23864', 'license': 'CC-BY-3.0', 'n_tokens_mistral': 3410, 'n_tokens_neox': 3165, 'n_words': 954, 'path': 'Question 2.ipynb', 'repo_name': 'kzhang14/Crime-Analysis-Chicago', 'size': '8728'}