Advertisement
Guest User

Untitled

a guest
Nov 18th, 2019
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.60 KB | None | 0 0
  1. from treelib import Node, Tree
  2. import random
  3. import time
  4. import os
  5. import multiprocessing
  6.  
  7.  
  8. letter_morse = {'A': '.-', 'B': '-...',
  9.                 'C': '-.-.', 'D': '-..', 'E': '.',
  10.                 'F': '..-.', 'G': '--.', 'H': '....',
  11.                 'I': '..', 'J': '.---', 'K': '-.-',
  12.                 'L': '.-..', 'M': '--', 'N': '-.',
  13.                 'O': '---', 'P': '.--.', 'Q': '--.-',
  14.                 'R': '.-.', 'S': '...', 'T': '-',
  15.                 'U': '..-', 'V': '...-', 'W': '.--',
  16.                 'X': '-..-', 'Y': '-.--', 'Z': '--..'}
  17. morse_letter = dict()
  18. for k, v in letter_morse.items():
  19.     morse_letter[v] = k
  20.  
  21.  
  22. def build_tree(tree, morse_left, parent_nid, original, nid):
  23.     for k in tree.keys():
  24.         print(k, end = " ")
  25.     print()
  26.     # We only want to keep doing this if we have too
  27.     #
  28.     # Added optimization. REALLY only add a new leaf if we absolutely have to
  29.     #
  30.     # current_leaf = tree.get_node(parent_nid)
  31.     done = False
  32.     while not done:
  33.         try:
  34.             current_leaf = tree[str(parent_nid)]
  35.             done = True
  36.         except:
  37.             print("Stuck, can't find {}".format(parent_nid))
  38.             time.sleep(.5)
  39.     current_branch_length = 1
  40.     while not current_leaf.is_root():
  41.         current_leaf = tree[str(current_leaf.bpointer)]
  42.         current_branch_length += 1
  43.     #
  44.     #  Added the end to the if statement
  45.     #
  46.     # This is a CRITICAL piece of this code.
  47.     # If there is nothing left to evaluate, then dont.
  48.     # but also, if the current branch is already big enough, only evaluate ONE more.
  49.     if morse_left != "" and current_branch_length < len(original):
  50.         # loop through the morse string that's left, matching as we go
  51.         for i in range(len(morse_left) + 1):
  52.             # for every letter in the alphabet as morse, see if it matches
  53.             for j in morse_letter.keys():
  54.                 if j == morse_left[:i]:
  55.                     # tree.create_node(morse_letter[j], nid.value, parent=parent_nid)
  56.                     temp = Node(morse_letter[j], nid.value)
  57.                     temp.bpointer = parent_nid
  58.                     tree[str(nid.value)] = temp
  59.                     parent = nid.value
  60.                     nid.value += 1
  61.                     left_to_match = morse_left[i:]
  62.                     print("Created {}, nid:{} parent:{}".format(morse_letter[j], nid.value, parent_nid))
  63.                     build_tree(tree, left_to_match, parent, original, nid)
  64.  
  65. def build_roots(morse, original, nid):
  66.     # nid is the global node identifier. It must be unique
  67.     # trees list to return
  68.     manager = multiprocessing.Manager()
  69.     trees = manager.list()
  70.     # loop through the morse string, matching as we go
  71.     processes = []
  72.     for i in range(len(morse)):
  73.         # for every letter in the alphabet as morse, see if it matches
  74.         for l in morse_letter.keys():
  75.             # If it does match, make a tree and add it to the list of possible roots
  76.             if l == morse[:i]:
  77.                 left_to_match = morse[i:]
  78.                 # tree = Tree()
  79.                 # tree.create_node(morse_letter[l], nid.value)
  80.                 tree = manager.dict()
  81.                 tree[str(nid.value)] = Node(morse_letter[l], nid.value)
  82.                 print("Created {}, nid:{}".format(morse_letter[l], nid.value))
  83.  
  84.                 parent = nid.value
  85.                 trees.append(tree)
  86.                 nid.value += 1
  87.                 p = multiprocessing.Process(target=build_tree,
  88.                                             args=(tree, left_to_match, parent, original, nid))
  89.                 processes.append(p)
  90.     cpus = multiprocessing.cpu_count()
  91.     running = []
  92.     i = 1
  93.     while len(processes) > 0:
  94.         while len(running) < cpus:
  95.             if len(processes) > 0:
  96.                 current_p = processes.pop(0)
  97.                 running.append(current_p)
  98.                 print("appending")
  99.                 i += 1
  100.             if len(processes) == 0:
  101.                 break
  102.         for r in running:
  103.             print("starting")
  104.             r.start()
  105.         time.sleep(2)
  106.         for r in running:
  107.             r.join()
  108.             print("Removing")
  109.             running.remove(r)
  110.     return trees
  111.  
  112.  
  113. def build_test_string(n=10):
  114.     return "".join([chr(97 + random.randint(0, 25)) for e in range(n)])
  115.  
  116.  
  117. def get_answer(list_of_trees, original):
  118.     # Make a list for all possibilities
  119.     all_possibilities = []
  120.  
  121.     # We need to loop through all of the roots. The roots will be saved as trees.
  122.     # Its not fast, but it's very complete.
  123.     for tree in list_of_trees:
  124.         # tree.show()
  125.         # Paths to leaves is perfect, allows us to get all paths from root to each leaf
  126.         tree_path_lists = tree.paths_to_leaves()
  127.         for path_list in tree_path_lists:
  128.  
  129.             if len(path_list) != len(original):
  130.                 #
  131.                 # Added optimization, don't words we dont have to.
  132.                 #
  133.                 continue
  134.             for i in range(len(path_list)):
  135.                 # we need to get the actual tag of the node, that's the letter.
  136.                 path_list[i] = tree.get_node(path_list[i]).tag
  137.             # Add what we just made to the list of possibilities
  138.             possible = "".join(path_list)
  139.             if len(possible) == len(original):
  140.                 all_possibilities.append(possible)
  141.     # p = 1
  142.     # for word in all_possibilities:
  143.     #     print(word, end=" ")
  144.     #     if p % 5 == 0:
  145.     #         print()
  146.     #     p += 1
  147.     # print()
  148.     return len(all_possibilities)
  149.  
  150.  
  151. def get_morse(s):
  152.     """
  153.    get the morse code
  154.    :param s: string of letters
  155.    :return: morse code
  156.    """
  157.     global letter_morse
  158.     to_ret = ""
  159.     for c in s:
  160.         to_ret += letter_morse[c.upper()]
  161.     return to_ret
  162.  
  163.  
  164. if __name__ == "__main__":
  165.     start = time.time()
  166.     nid = multiprocessing.Value('i', 0)
  167.  
  168.     # input = build_test_string(n=10)
  169.     input = "eta"
  170.     morse = get_morse(input)
  171.     # print("\n"*5)
  172.     print(input, morse, len(morse))
  173.     actual_trees = build_roots(morse, input, nid)
  174.     # print(actual_trees)
  175.     trees = []
  176.     for tree in actual_trees:
  177.         t = Tree()
  178.         for k,v in tree.items():
  179.             tag = v.tag
  180.             nid = v.identifier
  181.             parent = v.bpointer
  182.             # print("Received {}, nid:{} parent:{}".format(tag,nid,parent))
  183.             if parent is None:
  184.                 t.create_node(tag,nid)
  185.             else:
  186.                 t.create_node(tag,nid,parent=parent)
  187.         trees.append(t)
  188.     print(input, get_answer(trees, input))
  189.     print(time.time()-start)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement