



import argparse
import copy





def      __snake_case	(			_UpperCAmelCase				):
    __a						       =				{}

    with open(_lowerCAmelCase				) as f:
        for line in f:
            if line.split()[0] not in dict_of_neighbours:
                __a						       =				[]
                _list.append([line.split()[1], line.split()[2]]				)
                __a						       =				_list
            else:
                dict_of_neighbours[line.split()[0]].append(
                    [line.split()[1], line.split()[2]]				)
            if line.split()[1] not in dict_of_neighbours:
                __a						       =				[]
                _list.append([line.split()[0], line.split()[2]]				)
                __a						       =				_list
            else:
                dict_of_neighbours[line.split()[1]].append(
                    [line.split()[0], line.split()[2]]				)

    return dict_of_neighbours





def      __snake_case	(			_UpperCAmelCase   , _UpperCAmelCase				):

    with open(_lowerCAmelCase				) as f:
        __a						       =				f.read(1				)
    __a						       =				start_node

    __a						       =				[]

    __a						       =				start_node

    __a						       =				0
    while visiting not in first_solution:
        __a						       =				10000
        for k in dict_of_neighbours[visiting]:
            if int(k[1]				) < int(_lowerCAmelCase				) and k[0] not in first_solution:
                __a						       =				k[1]
                __a						       =				k[0]

        first_solution.append(_lowerCAmelCase				)
        __a						       =				distance_of_first_solution + int(_lowerCAmelCase				)
        __a						       =				best_node

    first_solution.append(_lowerCAmelCase				)

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

    __a						       =				(
        distance_of_first_solution
        + int(dict_of_neighbours[first_solution[-2]][position][1]				)
        - 10000
    )
    return first_solution, distance_of_first_solution





def      __snake_case	(			_UpperCAmelCase   , _UpperCAmelCase				):
    __a						       =				[]

    for n in solution[1:-1]:
        __a						       =				solution.index(_lowerCAmelCase				)
        for kn in solution[1:-1]:
            __a						       =				solution.index(_lowerCAmelCase				)
            if n == kn:
                continue

            __a						       =				copy.deepcopy(_lowerCAmelCase				)
            __a						       =				kn
            __a						       =				n

            __a						       =				0

            for k in _tmp[:-1]:
                __a						       =				_tmp[_tmp.index(_lowerCAmelCase				) + 1]
                for i in dict_of_neighbours[k]:
                    if i[0] == next_node:
                        __a						       =				distance + int(i[1]				)
            _tmp.append(_lowerCAmelCase				)

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

    __a						       =				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      __snake_case	(			_UpperCAmelCase   , _UpperCAmelCase   , _UpperCAmelCase   , _UpperCAmelCase   , _UpperCAmelCase				):
    __a						       =				1
    __a						       =				first_solution
    __a						       =				[]
    __a						       =				distance_of_first_solution
    __a						       =				solution

    while count <= iters:
        __a						       =				find_neighborhood(_lowerCAmelCase   , _lowerCAmelCase				)
        __a						       =				0
        __a						       =				neighborhood[index_of_best_solution]
        __a						       =				len(_lowerCAmelCase				) - 1

        __a						       =				False
        while not found:
            __a						       =				0
            while i < len(_lowerCAmelCase				):
                if best_solution[i] != solution[i]:
                    __a						       =				best_solution[i]
                    __a						       =				solution[i]
                    break
                __a						       =				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]				)
                __a						       =				True
                __a						       =				best_solution[:-1]
                __a						       =				neighborhood[index_of_best_solution][best_cost_index]
                if cost < best_cost:
                    __a						       =				cost
                    __a						       =				solution
            else:
                __a						       =				index_of_best_solution + 1
                __a						       =				neighborhood[index_of_best_solution]

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

        __a						       =				count + 1

    return best_solution_ever, best_cost





def      __snake_case	(			_UpperCAmelCase=None				):
    __a						       =				generate_neighbours(args.File				)

    __a						       =				generate_first_solution(
        args.File   , _lowerCAmelCase				)

    __a						       =				tabu_search(
        _lowerCAmelCase   , _lowerCAmelCase   , _lowerCAmelCase   , args.Iterations   , args.Size   , )

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


if __name__ == "__main__":
 __snake_case						:List[Any]      		=     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 random

from .binary_exp_mod import bin_exp_mod


def  snake_case_     (					_lowerCAmelCase  :						Tuple   ,      _lowerCAmelCase  :						Optional[Any]=1000  )      ->   int:
							if n < 2:
														return False

							if n % 2 == 0:
														return n == 2

							# this means n is odd
							UpperCAmelCase :       str 							=		n - 1
							UpperCAmelCase :       List[Any] 							=		0
							while d % 2 == 0:
														d /= 2
														exp += 1

							# n - 1=d*(2**exp)
							UpperCAmelCase :       List[str] 							=		0
							while count < prec:
														UpperCAmelCase :       int 							=		random.randint(2   ,      n - 1  )
														UpperCAmelCase :       List[str] 							=		bin_exp_mod(_lowerCAmelCase   ,      _lowerCAmelCase   ,      _lowerCAmelCase  )
														if b != 1:
																					UpperCAmelCase :       int 							=		True
																					for _ in range(_lowerCAmelCase  ):
																												if b == n - 1:
																																			UpperCAmelCase :       Dict 							=		False
																																			break
																												UpperCAmelCase :       str 							=		b * b
																												b %= n
																					if flag:
																												return False
																					count += 1
							return True


if __name__ == "__main__":
						UpperCamelCase__:   Optional[int]								=			abs(int(input("Enter bound : ").strip()))
						print("Here's the list of primes:")
						print(", ".join(str(i) for i in range(n + 1) if is_prime_big(i)))





