



import math
import sys






def 					__lowerCAmelCase		(  __lowerCamelCase	:    str	)  ->						str:
					__lowerCAmelCase	   =""""""
					try:
										with open(__lowerCamelCase				,   """rb"""	) as binary_file:
															__lowerCAmelCase	   =binary_file.read()
										for dat in data:
															__lowerCAmelCase	   =f"""{dat:08b}"""
															result += curr_byte
										return result
					except OSError:
										print("""File not accessible"""	)
										sys.exit()






def 					__lowerCAmelCase		(  __lowerCamelCase	:    str	)  ->						str:
					__lowerCAmelCase	   ={"""0""": """0""", """1""": """1"""}
					__lowerCAmelCase   ,	__lowerCAmelCase	   ="""""", """"""
					__lowerCAmelCase	   =len(__lowerCamelCase	)

					for i in range(len(__lowerCamelCase	)	):
										curr_string += data_bits[i]
										if curr_string not in lexicon:
															continue

										__lowerCAmelCase	   =lexicon[curr_string]
										result += last_match_id
										__lowerCAmelCase	   =last_match_id + """0"""

										if math.loga(__lowerCamelCase	).is_integer():
															__lowerCAmelCase	   ={}
															for curr_key in list(__lowerCamelCase	):
																				__lowerCAmelCase	   =lexicon.pop(__lowerCamelCase	)
															__lowerCAmelCase	   =new_lex

										__lowerCAmelCase	   =last_match_id + """1"""
										index += 1
										__lowerCAmelCase	   =""""""
					return result






def 					__lowerCAmelCase		(  __lowerCamelCase	:    str				,   __lowerCamelCase	:    str	)  ->						None:
					__lowerCAmelCase	   =8
					try:
										with open(__lowerCamelCase				,   """wb"""	) as opened_file:
															__lowerCAmelCase	   =[
															    to_write[i : i + byte_length]
															    for i in range(0				,   len(__lowerCamelCase	)				,   __lowerCamelCase	)
															]

															if len(result_byte_array[-1]	) % byte_length == 0:
																				result_byte_array.append("""10000000"""	)
															else:
																				result_byte_array[-1] += "1" + "0" * (
																				    byte_length - len(result_byte_array[-1]	) - 1
																				)

															for elem in result_byte_array[:-1]:
																				opened_file.write(int(__lowerCamelCase				,   2	).to_bytes(1				,   byteorder="""big"""	)	)
					except OSError:
										print("""File not accessible"""	)
										sys.exit()






def 					__lowerCAmelCase		(  __lowerCamelCase	:    str	)  ->						str:
					__lowerCAmelCase	   =0
					for letter in data_bits:
										if letter == "1":
															break
										counter += 1

					__lowerCAmelCase	   =data_bits[counter:]
					__lowerCAmelCase	   =data_bits[counter + 1 :]
					return data_bits






def 					__lowerCAmelCase		(  __lowerCamelCase	:    str				,   __lowerCamelCase	:    str	)  ->						None:
					__lowerCAmelCase	   =read_file_binary(__lowerCamelCase	)
					__lowerCAmelCase	   =remove_prefix(__lowerCamelCase	)
					__lowerCAmelCase	   =decompress_data(__lowerCamelCase	)
					write_file_binary(__lowerCamelCase				,   __lowerCamelCase	)


if __name__ == "__main__":
				compress(sys.argv[1], sys.argv[2])









def 					__lowerCAmelCase		(  __lowerCamelCase	:    int	)  ->						None:
					__lowerCAmelCase	   =generate_pascal_triangle(__lowerCamelCase	)
					for row_idx in range(__lowerCamelCase	):
										# Print left spaces
										for _ in range(num_rows - row_idx - 1	):
															print(end=""" """	)
										# Print row values
										for col_idx in range(row_idx + 1	):
															if col_idx != row_idx:
																				print(triangle[row_idx][col_idx]				,   end=""" """	)
															else:
																				print(triangle[row_idx][col_idx]				,   end=""""""	)
										print()






def 					__lowerCAmelCase		(  __lowerCamelCase	:    int	)  ->						list[list[int]]:

					if not isinstance(__lowerCamelCase				,   __lowerCamelCase	):
										raise TypeError("""The input value of 'num_rows' should be 'int'"""	)

					if num_rows == 0:
										return []
					elif num_rows < 0:
										raise ValueError(
										    """The input value of 'num_rows' should be greater than or equal to 0"""	)

					__lowerCAmelCase	   =[]
					for current_row_idx in range(__lowerCamelCase	):
										__lowerCAmelCase	   =populate_current_row(__lowerCamelCase				,   __lowerCamelCase	)
										triangle.append(__lowerCamelCase	)
					return triangle






def 					__lowerCAmelCase		(  __lowerCamelCase	:    list[list[int]]				,   __lowerCamelCase	:    int	)  ->						list[int]:
					__lowerCAmelCase	   =[-1] * (current_row_idx + 1)
					# first and last elements of current row are equal to 1
					__lowerCAmelCase   ,	__lowerCAmelCase	   =1, 1
					for current_col_idx in range(1				,   __lowerCamelCase	):
										calculate_current_element(
										    __lowerCamelCase				,   __lowerCamelCase				,   __lowerCamelCase				,   __lowerCamelCase	)
					return current_row






def 					__lowerCAmelCase		(  __lowerCamelCase	:    list[list[int]]				,   __lowerCamelCase	:    list[int]				,   __lowerCamelCase	:    int				,   __lowerCamelCase	:    int				,   )  ->						None:
					__lowerCAmelCase	   =triangle[current_row_idx - 1][current_col_idx - 1]
					__lowerCAmelCase	   =triangle[current_row_idx - 1][current_col_idx]
					__lowerCAmelCase	   =above_to_left_elt + above_to_right_elt






def 					__lowerCAmelCase		(  __lowerCamelCase	:    int	)  ->						list[list[int]]:

					if not isinstance(__lowerCamelCase				,   __lowerCamelCase	):
										raise TypeError("""The input value of 'num_rows' should be 'int'"""	)

					if num_rows == 0:
										return []
					elif num_rows < 0:
										raise ValueError(
										    """The input value of 'num_rows' should be greater than or equal to 0"""	)

					__lowerCAmelCase	   =[[1]]

					for row_index in range(1				,   __lowerCamelCase	):
										__lowerCAmelCase	   =[0] + result[-1] + [0]
										__lowerCAmelCase	   =row_index + 1
										# Calculate the number of distinct elements in a row
										__lowerCAmelCase	   =sum(divmod(__lowerCamelCase				,   2	)	)
										__lowerCAmelCase	   =[
										    temp_row[i - 1] + temp_row[i] for i in range(1				,   distinct_elements + 1	)
										]
										__lowerCAmelCase	   =row_first_half[: (row_index + 1) // 2]
										row_second_half.reverse()
										__lowerCAmelCase	   =row_first_half + row_second_half
										result.append(__lowerCamelCase	)

					return result






def 					__lowerCAmelCase		(  )  ->						None:
					from collections.abc import Callable
					from timeit import timeit

					def benchmark_a_function(__lowerCamelCase	:    Callable				,   __lowerCamelCase	:    int	) -> None:
										__lowerCAmelCase	   =f"""{func.__name__}({value})"""
										__lowerCAmelCase	   =timeit(f"""__main__.{call}"""				,   setup="""import __main__"""	)
										# print(f"{call:38} = {func(value)} -- {timing:.4f} seconds")
										print(f"""{call:38} -- {timing:.4f} seconds"""	)

					for value in range(15	):  # (1, 7, 14):
										for func in (generate_pascal_triangle, generate_pascal_triangle_optimized):
															benchmark_a_function(__lowerCamelCase				,   __lowerCamelCase	)
										print()


if __name__ == "__main__":
				import doctest

				doctest.testmod()
				benchmark()




