



from __future__ import annotations

import math



def 			_lowerCAmelCase       (					__lowerCAmelCase  ,  __lowerCAmelCase      )   ->					list:


				"""simple docstring"""

				if len(__lowerCAmelCase      ) != 2 or len(a[0]      ) != 2 or len(__lowerCAmelCase      ) != 2 or len(b[0]      ) != 2:
								raise Exception('''Matrices are not 2x2'''      )
				snake_case__	:      int     		=	[
				    [a[0][0] * b[0][0] + a[0][1] * b[1][0], a[0][0] * b[0][1] + a[0][1] * b[1][1]],
				    [a[1][0] * b[0][0] + a[1][1] * b[1][0], a[1][0] * b[0][1] + a[1][1] * b[1][1]],
				]
				return new_matrix



def 			_lowerCAmelCase       (					__lowerCAmelCase  ,  __lowerCAmelCase      )   ->					Dict:


				"""simple docstring"""

				return [
				    [matrix_a[row][col] + matrix_b[row][col] for col in range(len(matrix_a[row]      )      )]
				    for row in range(len(__lowerCAmelCase      )      )
				]



def 			_lowerCAmelCase       (					__lowerCAmelCase  ,  __lowerCAmelCase      )   ->					List[Any]:


				"""simple docstring"""

				return [
				    [matrix_a[row][col] - matrix_b[row][col] for col in range(len(matrix_a[row]      )      )]
				    for row in range(len(__lowerCAmelCase      )      )
				]



def 			_lowerCAmelCase       (					__lowerCAmelCase      )   ->					tuple[list, list, list, list]:


				"""simple docstring"""

				if len(__lowerCAmelCase      ) % 2 != 0 or len(a[0]      ) % 2 != 0:
								raise Exception('''Odd matrices are not supported!'''      )

				snake_case__	:      Dict     		=	len(__lowerCAmelCase      )
				snake_case__	:      Tuple     		=	matrix_length // 2

				snake_case__	:      Optional[int]     		=	[[a[i][j] for j in range(__lowerCAmelCase  ,  __lowerCAmelCase      )] for i in range(__lowerCAmelCase      )]
				snake_case__	:      str     		=	[
				    [a[i][j] for j in range(__lowerCAmelCase  ,  __lowerCAmelCase      )] for i in range(__lowerCAmelCase  ,  __lowerCAmelCase      )
				]

				snake_case__	:      Dict     		=	[[a[i][j] for j in range(__lowerCAmelCase      )] for i in range(__lowerCAmelCase      )]
				snake_case__	:      Union[str, Any]     		=	[[a[i][j] for j in range(__lowerCAmelCase      )] for i in range(__lowerCAmelCase  ,  __lowerCAmelCase      )]

				return top_left, top_right, bot_left, bot_right



def 			_lowerCAmelCase       (					__lowerCAmelCase      )   ->					tuple[int, int]:


				"""simple docstring"""

				return len(__lowerCAmelCase      ), len(matrix[0]      )



def 			_lowerCAmelCase       (					__lowerCAmelCase      )   ->					None:


				"""simple docstring"""

				print('''\n'''.join(str(__lowerCAmelCase      ) for line in matrix      )      )



def 			_lowerCAmelCase       (					__lowerCAmelCase  ,  __lowerCAmelCase      )   ->					list:


				"""simple docstring"""

				if matrix_dimensions(__lowerCAmelCase      ) == (2, 2):
								return default_matrix_multiplication(__lowerCAmelCase  ,  __lowerCAmelCase      )

				snake_case__		, snake_case__		, snake_case__		, snake_case__	:      Tuple     		=	split_matrix(__lowerCAmelCase      )
				snake_case__		, snake_case__		, snake_case__		, snake_case__	:      Tuple     		=	split_matrix(__lowerCAmelCase      )

				snake_case__	:      Any     		=	actual_strassen(__lowerCAmelCase  ,  matrix_subtraction(__lowerCAmelCase  ,  __lowerCAmelCase      )      )
				snake_case__	:      List[str]     		=	actual_strassen(matrix_addition(__lowerCAmelCase  ,  __lowerCAmelCase      )  ,  __lowerCAmelCase      )
				snake_case__	:      str     		=	actual_strassen(matrix_addition(__lowerCAmelCase  ,  __lowerCAmelCase      )  ,  __lowerCAmelCase      )
				snake_case__	:      List[str]     		=	actual_strassen(__lowerCAmelCase  ,  matrix_subtraction(__lowerCAmelCase  ,  __lowerCAmelCase      )      )
				snake_case__	:      str     		=	actual_strassen(matrix_addition(__lowerCAmelCase  ,  __lowerCAmelCase      )  ,  matrix_addition(__lowerCAmelCase  ,  __lowerCAmelCase      )      )
				snake_case__	:      int     		=	actual_strassen(matrix_subtraction(__lowerCAmelCase  ,  __lowerCAmelCase      )  ,  matrix_addition(__lowerCAmelCase  ,  __lowerCAmelCase      )      )
				snake_case__	:      Tuple     		=	actual_strassen(matrix_subtraction(__lowerCAmelCase  ,  __lowerCAmelCase      )  ,  matrix_addition(__lowerCAmelCase  ,  __lowerCAmelCase      )      )

				snake_case__	:      Optional[int]     		=	matrix_addition(matrix_subtraction(matrix_addition(__lowerCAmelCase  ,  __lowerCAmelCase      )  ,  __lowerCAmelCase      )  ,  __lowerCAmelCase      )
				snake_case__	:      Optional[Any]     		=	matrix_addition(__lowerCAmelCase  ,  __lowerCAmelCase      )
				snake_case__	:      List[str]     		=	matrix_addition(__lowerCAmelCase  ,  __lowerCAmelCase      )
				snake_case__	:      str     		=	matrix_subtraction(matrix_subtraction(matrix_addition(__lowerCAmelCase  ,  __lowerCAmelCase      )  ,  __lowerCAmelCase      )  ,  __lowerCAmelCase      )

				# construct the new matrix from our 4 quadrants
				snake_case__	:      int     		=	[]
				for i in range(len(__lowerCAmelCase      )      ):
								new_matrix.append(top_left[i] + top_right[i]      )
				for i in range(len(__lowerCAmelCase      )      ):
								new_matrix.append(bot_left[i] + bot_right[i]      )
				return new_matrix



def 			_lowerCAmelCase       (					__lowerCAmelCase  ,  __lowerCAmelCase      )   ->					list:


				"""simple docstring"""

				if matrix_dimensions(__lowerCAmelCase      )[1] != matrix_dimensions(__lowerCAmelCase      )[0]:
								snake_case__	:      Tuple     		=	(
								    '''Unable to multiply these matrices, please check the dimensions.\n'''
								    f"""Matrix A: {matrixa}\n"""
								    f"""Matrix B: {matrixa}"""
								)
								raise Exception(__lowerCAmelCase      )
				snake_case__	:      str     		=	matrix_dimensions(__lowerCAmelCase      )
				snake_case__	:      str     		=	matrix_dimensions(__lowerCAmelCase      )

				if dimensiona[0] == dimensiona[1] and dimensiona[0] == dimensiona[1]:
								return [matrixa, matrixa]

				snake_case__	:      List[Any]     		=	max(*__lowerCAmelCase  ,  *__lowerCAmelCase      )
				snake_case__	:      int     		=	int(math.pow(2  ,  math.ceil(math.loga(__lowerCAmelCase      )      )      )      )
				snake_case__	:      Union[str, Any]     		=	matrixa
				snake_case__	:      Optional[int]     		=	matrixa

				# Adding zeros to the matrices so that the arrays dimensions are the same and also
				# power of 2
				for i in range(0  ,  __lowerCAmelCase      ):
								if i < dimensiona[0]:
												for _ in range(dimensiona[1]  ,  __lowerCAmelCase      ):
																new_matrixa[i].append(0      )
								else:
												new_matrixa.append([0] * maxim      )
								if i < dimensiona[0]:
												for _ in range(dimensiona[1]  ,  __lowerCAmelCase      ):
																new_matrixa[i].append(0      )
								else:
												new_matrixa.append([0] * maxim      )

				snake_case__	:      Union[str, Any]     		=	actual_strassen(__lowerCAmelCase  ,  __lowerCAmelCase      )

				# Removing the additional zeros
				for i in range(0  ,  __lowerCAmelCase      ):
								if i < dimensiona[0]:
												for _ in range(dimensiona[1]  ,  __lowerCAmelCase      ):
																final_matrix[i].pop()
								else:
												final_matrix.pop()
				return final_matrix


if __name__ == "__main__":
				A__								=						[
				    [2, 3, 4, 5],
				    [6, 4, 3, 1],
				    [2, 3, 6, 7],
				    [3, 1, 2, 4],
				    [2, 3, 4, 5],
				    [6, 4, 3, 1],
				    [2, 3, 6, 7],
				    [3, 1, 2, 4],
				    [2, 3, 4, 5],
				    [6, 2, 3, 1],
				]
				A__								=						[[0, 2, 1, 1], [16, 2, 3, 3], [2, 2, 7, 7], [13, 11, 22, 4]]
				print(strassen(matrixa, matrixa))






import math
import sys



def 			_lowerCAmelCase       (					__lowerCAmelCase      )   ->					str:


				"""simple docstring"""

				snake_case__	:      Optional[Any]     		=	''''''
				try:
								with open(__lowerCAmelCase  ,  '''rb'''      ) as binary_file:
												snake_case__	:      int     		=	binary_file.read()
								for dat in data:
												snake_case__	:      Any     		=	f"""{dat:08b}"""
												result += curr_byte
								return result
				except OSError:
								print('''File not accessible'''      )
								sys.exit()



def 			_lowerCAmelCase       (					__lowerCAmelCase      )   ->					str:


				"""simple docstring"""

				snake_case__	:      List[str]     		=	{'''0''': '''0''', '''1''': '''1'''}
				snake_case__		, snake_case__	:      List[Any]     		=	'''''', ''''''
				snake_case__	:      Tuple     		=	len(__lowerCAmelCase      )

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

								snake_case__	:      Tuple     		=	lexicon[curr_string]
								result += last_match_id
								snake_case__	:      Any     		=	last_match_id + '''0'''

								if math.loga(__lowerCAmelCase      ).is_integer():
												snake_case__	:      Tuple     		=	{}
												for curr_key in list(__lowerCAmelCase      ):
																snake_case__	:      Union[str, Any]     		=	lexicon.pop(__lowerCAmelCase      )
												snake_case__	:      Optional[Any]     		=	new_lex

								snake_case__	:      Tuple     		=	last_match_id + '''1'''
								index += 1
								snake_case__	:      Dict     		=	''''''
				return result



def 			_lowerCAmelCase       (					__lowerCAmelCase  ,  __lowerCAmelCase      )   ->					None:


				"""simple docstring"""

				snake_case__	:      Dict     		=	8
				try:
								with open(__lowerCAmelCase  ,  '''wb'''      ) as opened_file:
												snake_case__	:      Union[str, Any]     		=	[
												    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:


				"""simple docstring"""

				snake_case__	:      Any     		=	0
				for letter in data_bits:
								if letter == "1":
												break
								counter += 1

				snake_case__	:      Optional[int]     		=	data_bits[counter:]
				snake_case__	:      int     		=	data_bits[counter + 1 :]
				return data_bits



def 			_lowerCAmelCase       (					__lowerCAmelCase  ,  __lowerCAmelCase      )   ->					None:


				"""simple docstring"""

				snake_case__	:      Union[str, Any]     		=	read_file_binary(__lowerCAmelCase      )
				snake_case__	:      List[str]     		=	remove_prefix(__lowerCAmelCase      )
				snake_case__	:      Any     		=	decompress_data(__lowerCAmelCase      )
				write_file_binary(__lowerCAmelCase  ,  __lowerCAmelCase      )


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

