






import numpy as np


def __A       ( __lowerCAmelCase					,						__lowerCAmelCase="utf-8"					,						__lowerCAmelCase="surrogatepass"      )->    Any:





						"""simple docstring"""



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


def __A       ( __lowerCAmelCase					,						__lowerCAmelCase="utf-8"					,						__lowerCAmelCase="surrogatepass"      )->    str:





						"""simple docstring"""



						_UpperCAmelCase							   =     int(__lowerCAmelCase					,						2      )
						return n.to_bytes((n.bit_length() + 7) // 8					,						'big'      ).decode(__lowerCAmelCase					,						__lowerCAmelCase      ) or "\0"


def __A       ( __lowerCAmelCase					,						__lowerCAmelCase      )->    List[str]:





						"""simple docstring"""



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

						_UpperCAmelCase							   =     []
						_UpperCAmelCase							   =     []
						_UpperCAmelCase							   =     [bin(__lowerCAmelCase      )[2:] for x in range(1					,						size_par + len(__lowerCAmelCase      ) + 1      )]

						# sorted information data for the size of the output data
						_UpperCAmelCase							   =     []
						# data position template + parity
						_UpperCAmelCase							   =     []
						# parity bit counter
						_UpperCAmelCase							   =     0
						# counter position of data bits
						_UpperCAmelCase							   =     0

						for x in range(1					,						size_par + len(__lowerCAmelCase      ) + 1      ):
												# Performs a template of bit positions - who should be given,
												# and who should be parity
												if qtd_bp < size_par:
																		if (np.log(__lowerCAmelCase      ) / np.log(2      )).is_integer():
																								data_out_gab.append('P'      )
																								_UpperCAmelCase							   =     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(__lowerCAmelCase      )

    # Calculates parity
						_UpperCAmelCase							   =     0  # parity bit counter
						for bp in range(1					,						size_par + 1      ):
												# Bit counter one for a given parity
												_UpperCAmelCase							   =     0
												# counter to control the loop reading
												_UpperCAmelCase							   =     0
												for x in data_ord:
																		if x is not None:
																								try:
																														_UpperCAmelCase							   =     (bin_pos[cont_loop])[-1 * (bp)]
																								except IndexError:
																														_UpperCAmelCase							   =     '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							   =     0  # parity bit counter
						for x in range(0					,						size_par + len(__lowerCAmelCase      )      ):
												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       ( __lowerCAmelCase					,						__lowerCAmelCase      )->    List[str]:





						"""simple docstring"""



						_UpperCAmelCase							   =     []
						# Parity bit counter
						_UpperCAmelCase							   =     0
						# Counter p data bit reading
						_UpperCAmelCase							   =     0
						# list of parity received
						_UpperCAmelCase							   =     []
						_UpperCAmelCase							   =     []

						for x in range(1					,						len(__lowerCAmelCase      ) + 1      ):
												# Performs a template of bit positions - who should be given,
												#  and who should be parity
												if qtd_bp < size_par and (np.log(__lowerCAmelCase      ) / np.log(2      )).is_integer():
																		data_out_gab.append('P'      )
																		_UpperCAmelCase							   =     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							   =     []
						_UpperCAmelCase							   =     []
						_UpperCAmelCase							   =     [bin(__lowerCAmelCase      )[2:] for x in range(1					,						size_par + len(__lowerCAmelCase      ) + 1      )]

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

						for x in range(1					,						size_par + len(__lowerCAmelCase      ) + 1      ):
												# Performs a template position of bits - who should be given,
												# and who should be parity
												if qtd_bp < size_par and (np.log(__lowerCAmelCase      ) / np.log(2      )).is_integer():
																		data_out_gab.append('P'      )
																		_UpperCAmelCase							   =     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(__lowerCAmelCase      )

    # Calculates parity
						_UpperCAmelCase							   =     0  # parity bit counter
						for bp in range(1					,						size_par + 1      ):
												# Bit counter one for a certain parity
												_UpperCAmelCase							   =     0
												# Counter to control loop reading
												_UpperCAmelCase							   =     0
												for x in data_ord:
																		if x is not None:
																								try:
																														_UpperCAmelCase							   =     (bin_pos[cont_loop])[-1 * (bp)]
																								except IndexError:
																														_UpperCAmelCase							   =     '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							   =     0  # Parity bit counter
						for x in range(0					,						size_par + len(__lowerCAmelCase      )      ):
												if data_ord[x] is None:
																		data_out.append(str(parity[cont_bp]      )      )
																		cont_bp += 1
												else:
																		data_out.append(data_ord[x]      )

						_UpperCAmelCase							   =     parity_received == parity
						return data_output, ack








from __future__ import annotations

import re


def __A       ( __lowerCAmelCase      )->    list[str]:





						"""simple docstring"""



						def alphanum_key(__lowerCAmelCase      ):
												return [int(__lowerCAmelCase      ) if s.isdigit() else s.lower() for s in re.split('([0-9]+)'					,						__lowerCAmelCase      )]

						return sorted(__lowerCAmelCase					,						key=__lowerCAmelCase      )


if __name__ == "__main__":
		import doctest

		doctest.testmod()
