
import numpy as np




def 		A						(  SCREAMING_SNAKE_CASE     ,						SCREAMING_SNAKE_CASE="utf-8"     ,						SCREAMING_SNAKE_CASE="surrogatepass"							):




			"""simple docstring"""


			UpperCAmelCase__		:Any 		=    bin(int.from_bytes(text.encode(SCREAMING_SNAKE_CASE     ,						SCREAMING_SNAKE_CASE							)     ,						'big'							)							)[2:]
			return bits.zfill(8 * ((len(SCREAMING_SNAKE_CASE							) + 7) // 8)							)




def 		A						(  SCREAMING_SNAKE_CASE     ,						SCREAMING_SNAKE_CASE="utf-8"     ,						SCREAMING_SNAKE_CASE="surrogatepass"							):




			"""simple docstring"""


			UpperCAmelCase__		:Dict 		=    int(SCREAMING_SNAKE_CASE     ,						2							)
			return n.to_bytes((n.bit_length() + 7) // 8     ,						'big'							).decode(SCREAMING_SNAKE_CASE     ,						SCREAMING_SNAKE_CASE							) or "\0"




def 		A						(  SCREAMING_SNAKE_CASE     ,						SCREAMING_SNAKE_CASE							):




			"""simple docstring"""


			if size_par + len(SCREAMING_SNAKE_CASE							) <= 2**size_par - (len(SCREAMING_SNAKE_CASE							) - 1):
						raise ValueError('size of parity don\'t match with size of data'							)

			UpperCAmelCase__		:Dict 		=    []
			UpperCAmelCase__		:str 		=    []
			UpperCAmelCase__		:Optional[int] 		=    [bin(SCREAMING_SNAKE_CASE							)[2:] for x in range(1     ,						size_par + len(SCREAMING_SNAKE_CASE							) + 1							)]

			# sorted information data for the size of the output data
			UpperCAmelCase__		:Any 		=    []
			# data position template + parity
			UpperCAmelCase__		:int 		=    []
			# parity bit counter
			UpperCAmelCase__		:Optional[int] 		=    0
			# counter position of data bits
			UpperCAmelCase__		:Union[str, Any] 		=    0

			for x in range(1     ,						size_par + len(SCREAMING_SNAKE_CASE							) + 1							):
						# Performs a template of bit positions - who should be given,
						# and who should be parity
						if qtd_bp < size_par:
									if (np.log(SCREAMING_SNAKE_CASE							) / np.log(2							)).is_integer():
												data_out_gab.append('P'							)
												UpperCAmelCase__		:str 		=    qtd_bp + 1
									else:
												data_out_gab.append('D'							)
						else:
									data_out_gab.append('D'							)

						# Sorts the data to the new output size
						if data_out_gab[-1] == "D":
									data_ord.append(data[cont_data]							)
									cont_data += 1
						else:
									data_ord.append(SCREAMING_SNAKE_CASE							)

    # Calculates parity
			UpperCAmelCase__		:Optional[Any] 		=    0  # parity bit counter
			for bp in range(1     ,						size_par + 1							):
						# Bit counter one for a given parity
						UpperCAmelCase__		:List[str] 		=    0
						# counter to control the loop reading
						UpperCAmelCase__		:Any 		=    0
						for x in data_ord:
									if x is not None:
												try:
															UpperCAmelCase__		:Optional[int] 		=    (bin_pos[cont_loop])[-1 * (bp)]
												except IndexError:
															UpperCAmelCase__		:str 		=    '0'
												if aux == "1" and x == "1":
															cont_bo += 1
									cont_loop += 1
						parity.append(cont_bo % 2							)

						qtd_bp += 1

			# Mount the message
			UpperCAmelCase__		:Any 		=    0  # parity bit counter
			for x in range(0     ,						size_par + len(SCREAMING_SNAKE_CASE							)							):
						if data_ord[x] is None:
									data_out.append(str(parity[cont_bp]							)							)
									cont_bp += 1
						else:
									data_out.append(data_ord[x]							)

			return data_out




def 		A						(  SCREAMING_SNAKE_CASE     ,						SCREAMING_SNAKE_CASE							):




			"""simple docstring"""


			UpperCAmelCase__		:Any 		=    []
			# Parity bit counter
			UpperCAmelCase__		:Union[str, Any] 		=    0
			# Counter p data bit reading
			UpperCAmelCase__		:Union[str, Any] 		=    0
			# list of parity received
			UpperCAmelCase__		:Any 		=    []
			UpperCAmelCase__		:Any 		=    []

			for x in range(1     ,						len(SCREAMING_SNAKE_CASE							) + 1							):
						# Performs a template of bit positions - who should be given,
						#  and who should be parity
						if qtd_bp < size_par and (np.log(SCREAMING_SNAKE_CASE							) / np.log(2							)).is_integer():
									data_out_gab.append('P'							)
									UpperCAmelCase__		:Optional[Any] 		=    qtd_bp + 1
						else:
									data_out_gab.append('D'							)

						# Sorts the data to the new output size
						if data_out_gab[-1] == "D":
									data_output.append(data[cont_data]							)
						else:
									parity_received.append(data[cont_data]							)
						cont_data += 1

			# -----------calculates the parity with the data
			UpperCAmelCase__		:Optional[Any] 		=    []
			UpperCAmelCase__		:str 		=    []
			UpperCAmelCase__		:List[str] 		=    [bin(SCREAMING_SNAKE_CASE							)[2:] for x in range(1     ,						size_par + len(SCREAMING_SNAKE_CASE							) + 1							)]

			#  sorted information data for the size of the output data
			UpperCAmelCase__		:str 		=    []
			# Data position feedback + parity
			UpperCAmelCase__		:str 		=    []
			# Parity bit counter
			UpperCAmelCase__		:Dict 		=    0
			# Counter p data bit reading
			UpperCAmelCase__		:Any 		=    0

			for x in range(1     ,						size_par + len(SCREAMING_SNAKE_CASE							) + 1							):
						# Performs a template position of bits - who should be given,
						# and who should be parity
						if qtd_bp < size_par and (np.log(SCREAMING_SNAKE_CASE							) / np.log(2							)).is_integer():
									data_out_gab.append('P'							)
									UpperCAmelCase__		:Tuple 		=    qtd_bp + 1
						else:
									data_out_gab.append('D'							)

						# Sorts the data to the new output size
						if data_out_gab[-1] == "D":
									data_ord.append(data_output[cont_data]							)
									cont_data += 1
						else:
									data_ord.append(SCREAMING_SNAKE_CASE							)

    # Calculates parity
			UpperCAmelCase__		:str 		=    0  # parity bit counter
			for bp in range(1     ,						size_par + 1							):
						# Bit counter one for a certain parity
						UpperCAmelCase__		:List[Any] 		=    0
						# Counter to control loop reading
						UpperCAmelCase__		:Union[str, Any] 		=    0
						for x in data_ord:
									if x is not None:
												try:
															UpperCAmelCase__		:List[str] 		=    (bin_pos[cont_loop])[-1 * (bp)]
												except IndexError:
															UpperCAmelCase__		:Optional[Any] 		=    '0'
												if aux == "1" and x == "1":
															cont_bo += 1
									cont_loop += 1
						parity.append(str(cont_bo % 2							)							)

						qtd_bp += 1

			# Mount the message
			UpperCAmelCase__		:Optional[Any] 		=    0  # Parity bit counter
			for x in range(0     ,						size_par + len(SCREAMING_SNAKE_CASE							)							):
						if data_ord[x] is None:
									data_out.append(str(parity[cont_bp]							)							)
									cont_bp += 1
						else:
									data_out.append(data_ord[x]							)

			UpperCAmelCase__		:List[Any] 		=    parity_received == parity
			return data_output, ack







from __future__ import annotations

from queue import Queue


class 	UpperCamelCase__       :

						'''simple docstring'''



						def __init__(  self	)  ->None:
									UpperCAmelCase__		:dict[int, list[int]] 		=    {}


						def    A__       (  self	)  ->None:
									for i in self.vertices:
												print(A  , ' : '  , ' -> '.join([str(A	) for j in self.vertices[i]]	)	)


						def    A__       (  self  , A  , A	)  ->None:
									if from_vertex in self.vertices:
												self.vertices[from_vertex].append(A	)
									else:
												UpperCAmelCase__		:Union[str, Any] 		=    [to_vertex]


						def    A__       (  self  , A	)  ->set[int]:
									UpperCAmelCase__		:str 		=    set()

									# create a first in first out queue to store all the vertices for BFS
									UpperCAmelCase__		:Queue 		=    Queue()

									# mark the source node as visited and enqueue it
									visited.add(A	)
									queue.put(A	)

									while not queue.empty():
												UpperCAmelCase__		:List[str] 		=    queue.get()

												# loop through all adjacent vertex and enqueue it if not yet visited
												for adjacent_vertex in self.vertices[vertex]:
															if adjacent_vertex not in visited:
																		queue.put(A	)
																		visited.add(A	)
									return visited


if __name__ == "__main__":
						from doctest import testmod

						testmod(verbose=True)

						__snake_case					:							Any           =							Graph()
						g.add_edge(0, 1)
						g.add_edge(0, 2)
						g.add_edge(1, 2)
						g.add_edge(2, 0)
						g.add_edge(2, 3)
						g.add_edge(3, 3)

						g.print_graph()
						# 0  :  1 -> 2
						# 1  :  2
						# 2  :  0 -> 3
						# 3  :  3

						assert sorted(g.bfs(2)) == [0, 1, 2, 3]





