


'''simple docstring'''



import argparse
import copy



def      UpperCAmelCase__   (      UpperCAmelCase_       :							Optional[Any]				)	->						Optional[int]:
     __lowerCamelCase  :      Optional[Any]														=						{}

     with open(UpperCAmelCase_				) as f:
          for line in f:
               if line.split()[0] not in dict_of_neighbours:
                    __lowerCamelCase  :      str														=						[]
                    _list.append([line.split()[1], line.split()[2]]				)
                    __lowerCamelCase  :      Any														=						_list
               else:
                    dict_of_neighbours[line.split()[0]].append(
                        [line.split()[1], line.split()[2]]				)
               if line.split()[1] not in dict_of_neighbours:
                    __lowerCamelCase  :      List[Any]														=						[]
                    _list.append([line.split()[0], line.split()[2]]				)
                    __lowerCamelCase  :      Optional[Any]														=						_list
               else:
                    dict_of_neighbours[line.split()[1]].append(
                        [line.split()[0], line.split()[2]]				)

     return dict_of_neighbours



def      UpperCAmelCase__   (      UpperCAmelCase_       :							Optional[int] ,       UpperCAmelCase_       :							Tuple				)	->						str:

     with open(UpperCAmelCase_				) as f:
          __lowerCamelCase  :      str														=						f.read(1				)
     __lowerCamelCase  :      Any														=						start_node

     __lowerCamelCase  :      str														=						[]

     __lowerCamelCase  :      Dict														=						start_node

     __lowerCamelCase  :      List[str]														=						0
     while visiting not in first_solution:
          __lowerCamelCase  :      List[str]														=						1_00_00
          for k in dict_of_neighbours[visiting]:
               if int(k[1]				) < int(UpperCAmelCase_				) and k[0] not in first_solution:
                    __lowerCamelCase  :      Tuple														=						k[1]
                    __lowerCamelCase  :      List[str]														=						k[0]

          first_solution.append(UpperCAmelCase_				)
          __lowerCamelCase  :      Dict														=						distance_of_first_solution + int(UpperCAmelCase_				)
          __lowerCamelCase  :      List[Any]														=						best_node

     first_solution.append(UpperCAmelCase_				)

     __lowerCamelCase  :      Optional[Any]														=						0
     for k in dict_of_neighbours[first_solution[-2]]:
          if k[0] == start_node:
               break
          position += 1

     __lowerCamelCase  :      Union[str, Any]														=						(
         distance_of_first_solution
         + int(dict_of_neighbours[first_solution[-2]][position][1]				)
         - 1_00_00
     )
     return first_solution, distance_of_first_solution



def      UpperCAmelCase__   (      UpperCAmelCase_       :							int ,       UpperCAmelCase_       :							Any				)	->						int:
     __lowerCamelCase  :      Optional[Any]														=						[]

     for n in solution[1:-1]:
          __lowerCamelCase  :      Optional[int]														=						solution.index(UpperCAmelCase_				)
          for kn in solution[1:-1]:
               __lowerCamelCase  :      Any														=						solution.index(UpperCAmelCase_				)
               if n == kn:
                    continue

               __lowerCamelCase  :      Dict														=						copy.deepcopy(UpperCAmelCase_				)
               __lowerCamelCase  :      Optional[Any]														=						kn
               __lowerCamelCase  :      int														=						n

               __lowerCamelCase  :      Tuple														=						0

               for k in _tmp[:-1]:
                    __lowerCamelCase  :      List[Any]														=						_tmp[_tmp.index(UpperCAmelCase_				) + 1]
                    for i in dict_of_neighbours[k]:
                         if i[0] == next_node:
                              __lowerCamelCase  :      Union[str, Any]														=						distance + int(i[1]				)
               _tmp.append(UpperCAmelCase_				)

               if _tmp not in neighborhood_of_solution:
                    neighborhood_of_solution.append(_tmp				)

     __lowerCamelCase  :      Any														=						len(neighborhood_of_solution[0]				) - 1

     neighborhood_of_solution.sort(key=lambda UpperCAmelCase_				: x[index_of_last_item_in_the_list]				)
     return neighborhood_of_solution



def      UpperCAmelCase__   (      UpperCAmelCase_       :							str ,       UpperCAmelCase_       :							Any ,       UpperCAmelCase_       :							Any ,       UpperCAmelCase_       :							Dict ,       UpperCAmelCase_       :							Optional[Any]				)	->						Optional[int]:
     __lowerCamelCase  :      Union[str, Any]														=						1
     __lowerCamelCase  :      Union[str, Any]														=						first_solution
     __lowerCamelCase  :      str														=						[]
     __lowerCamelCase  :      Optional[int]														=						distance_of_first_solution
     __lowerCamelCase  :      Union[str, Any]														=						solution

     while count <= iters:
          __lowerCamelCase  :      Any														=						find_neighborhood(UpperCAmelCase_ ,       UpperCAmelCase_				)
          __lowerCamelCase  :      Optional[Any]														=						0
          __lowerCamelCase  :      Optional[Any]														=						neighborhood[index_of_best_solution]
          __lowerCamelCase  :      List[str]														=						len(UpperCAmelCase_				) - 1

          __lowerCamelCase  :      Union[str, Any]														=						False
          while not found:
               __lowerCamelCase  :      List[Any]														=						0
               while i < len(UpperCAmelCase_				):
                    if best_solution[i] != solution[i]:
                         __lowerCamelCase  :      Optional[Any]														=						best_solution[i]
                         __lowerCamelCase  :      str														=						solution[i]
                         break
                    __lowerCamelCase  :      Union[str, Any]														=						i + 1

               if [first_exchange_node, second_exchange_node] not in tabu_list and [
                   second_exchange_node,
                   first_exchange_node,
               ] not in tabu_list:
                    tabu_list.append([first_exchange_node, second_exchange_node]				)
                    __lowerCamelCase  :      List[Any]														=						True
                    __lowerCamelCase  :      List[str]														=						best_solution[:-1]
                    __lowerCamelCase  :      List[Any]														=						neighborhood[index_of_best_solution][best_cost_index]
                    if cost < best_cost:
                         __lowerCamelCase  :      Dict														=						cost
                         __lowerCamelCase  :      str														=						solution
               else:
                    __lowerCamelCase  :      List[Any]														=						index_of_best_solution + 1
                    __lowerCamelCase  :      List[Any]														=						neighborhood[index_of_best_solution]

          if len(UpperCAmelCase_				) >= size:
               tabu_list.pop(0				)

          __lowerCamelCase  :      Optional[Any]														=						count + 1

     return best_solution_ever, best_cost



def      UpperCAmelCase__   (      UpperCAmelCase_       :							Any=None				)	->						Union[str, Any]:
     __lowerCamelCase  :      Optional[Any]														=						generate_neighbours(args.File				)

     __lowerCamelCase							,			__lowerCamelCase  :      str														=						generate_first_solution(
         args.File ,       UpperCAmelCase_				)

     __lowerCamelCase							,			__lowerCamelCase  :      Optional[int]														=						tabu_search(
         UpperCAmelCase_ ,       UpperCAmelCase_ ,       UpperCAmelCase_ ,       args.Iterations ,       args.Size ,       )

     print(F'Best solution: {best_sol}, with total distance: {best_cost}.'				)


if __name__ == "__main__":
      A__						:   Dict				=    argparse.ArgumentParser(description="""Tabu Search""")
      parser.add_argument(
          """-f""",
          """--File""",
          type=str,
          help="""Path to the file containing the data""",
          required=True,
      )
      parser.add_argument(
          """-i""",
          """--Iterations""",
          type=int,
          help="""How many iterations the algorithm should perform""",
          required=True,
      )
      parser.add_argument(
          """-s""", """--Size""", type=int, help="""Size of the tabu list""", required=True
      )

      # Pass the arguments to main method
      main(parser.parse_args())










'''simple docstring'''



import argparse


A__						:   Optional[Any]				=    """docs/source/_static/js/custom.js"""



def      UpperCAmelCase__   (      UpperCAmelCase_       :							Optional[int]				)	->						int:
     with open(UpperCAmelCase_ ,       encoding='utf-8' ,       newline='\n'				) as f:
          __lowerCamelCase  :      Dict														=						f.readlines()
     __lowerCamelCase  :      Tuple														=						0

     # First let's put the right version
     while not lines[index].startswith('const stableVersion ='				):
          index += 1
     __lowerCamelCase  :      Dict														=						F'const stableVersion = "v{version}"\n'

     # Then update the dictionary
     while not lines[index].startswith('const versionMapping = {'				):
          index += 1

     # We go until the end
     while not lines[index].startswith('}'				):
          index += 1
     # We add the new version at the end
     lines[index - 1] += F'    "v{version}": "v{version}",\n'

     with open(UpperCAmelCase_ ,       'w' ,       encoding='utf-8' ,       newline='\n'				) as f:
          f.writelines(UpperCAmelCase_				)


if __name__ == "__main__":
      A__						:   str				=    argparse.ArgumentParser()
      parser.add_argument("""--version""", help="""Release version.""")
      A__						:   Any				=    parser.parse_args()
      update_custom_js(args.version)






