





'''simple docstring'''






from __future__ import annotations

import math






def      __A						(							a_						:  list      ,a_						:  list	):
		if len(a_	) != 2 or len(a[0]	) != 2 or len(a_	) != 2 or len(b[0]	) != 2:
				raise Exception("Matrices are not 2x2"	)
		lowerCAmelCase     :    Optional[Any]						=   [
		    [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      __A						(							a_						:  list      ,a_						:  list	):
		return [
		    [matrix_a[row][col] + matrix_b[row][col] for col in range(len(matrix_a[row]	)	)]
		    for row in range(len(a_	)	)
		]






def      __A						(							a_						:  list      ,a_						:  list	):
		return [
		    [matrix_a[row][col] - matrix_b[row][col] for col in range(len(matrix_a[row]	)	)]
		    for row in range(len(a_	)	)
		]






def      __A						(							a_						:  list	):
		if len(a_	) % 2 != 0 or len(a[0]	) % 2 != 0:
				raise Exception("Odd matrices are not supported!"	)

		lowerCAmelCase     :    Any						=   len(a_	)
		lowerCAmelCase     :    Optional[Any]						=   matrix_length // 2

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

		lowerCAmelCase     :    List[str]						=   [[a[i][j] for j in range(a_	)] for i in range(a_	)]
		lowerCAmelCase     :    str						=   [[a[i][j] for j in range(a_	)] for i in range(a_      ,a_	)]

		return top_left, top_right, bot_left, bot_right






def      __A						(							a_						:  list	):
		return len(a_	), len(matrix[0]	)






def      __A						(							a_						:  list	):
		print("\n".join(str(a_	) for line in matrix	)	)






def      __A						(							a_						:  list      ,a_						:  list	):
		if matrix_dimensions(a_	) == (2, 2):
				return default_matrix_multiplication(a_      ,a_	)

		lowerCAmelCase	,		lowerCAmelCase	,		lowerCAmelCase	,		lowerCAmelCase     :    Tuple						=   split_matrix(a_	)
		lowerCAmelCase	,		lowerCAmelCase	,		lowerCAmelCase	,		lowerCAmelCase     :    Union[str, Any]						=   split_matrix(a_	)

		lowerCAmelCase     :    Optional[Any]						=   actual_strassen(a_      ,matrix_subtraction(a_      ,a_	)	)
		lowerCAmelCase     :    Tuple						=   actual_strassen(matrix_addition(a_      ,a_	)      ,a_	)
		lowerCAmelCase     :    List[str]						=   actual_strassen(matrix_addition(a_      ,a_	)      ,a_	)
		lowerCAmelCase     :    List[Any]						=   actual_strassen(a_      ,matrix_subtraction(a_      ,a_	)	)
		lowerCAmelCase     :    Tuple						=   actual_strassen(matrix_addition(a_      ,a_	)      ,matrix_addition(a_      ,a_	)	)
		lowerCAmelCase     :    Any						=   actual_strassen(matrix_subtraction(a_      ,a_	)      ,matrix_addition(a_      ,a_	)	)
		lowerCAmelCase     :    Any						=   actual_strassen(matrix_subtraction(a_      ,a_	)      ,matrix_addition(a_      ,a_	)	)

		lowerCAmelCase     :    Optional[int]						=   matrix_addition(matrix_subtraction(matrix_addition(a_      ,a_	)      ,a_	)      ,a_	)
		lowerCAmelCase     :    List[str]						=   matrix_addition(a_      ,a_	)
		lowerCAmelCase     :    List[Any]						=   matrix_addition(a_      ,a_	)
		lowerCAmelCase     :    Optional[int]						=   matrix_subtraction(matrix_subtraction(matrix_addition(a_      ,a_	)      ,a_	)      ,a_	)

		# construct the new matrix from our 4 quadrants
		lowerCAmelCase     :    Union[str, Any]						=   []
		for i in range(len(a_	)	):
				new_matrix.append(top_left[i] + top_right[i]	)
		for i in range(len(a_	)	):
				new_matrix.append(bot_left[i] + bot_right[i]	)
		return new_matrix






def      __A						(							a_						:  list      ,a_						:  list	):
		if matrix_dimensions(a_	)[1] != matrix_dimensions(a_	)[0]:
				lowerCAmelCase     :    str						=   (
				    "Unable to multiply these matrices, please check the dimensions.\n"
				    f'''Matrix A: {matrixa}\n'''
				    f'''Matrix B: {matrixa}'''
				)
				raise Exception(a_	)
		lowerCAmelCase     :    Optional[int]						=   matrix_dimensions(a_	)
		lowerCAmelCase     :    Union[str, Any]						=   matrix_dimensions(a_	)

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

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

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

		lowerCAmelCase     :    Optional[Any]						=   actual_strassen(a_      ,a_	)

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


if __name__ == "__main__":
					lowerCAmelCase       		=      [
					    [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],
					]
					lowerCAmelCase       		=      [[0, 2, 1, 1], [16, 2, 3, 3], [2, 2, 7, 7], [13, 11, 22, 4]]
					print(strassen(matrixa, matrixa))










'''simple docstring'''






def      __A						(							a_						:  int	):
		assert (
		    isinstance(a_      ,a_	) and number_of_steps > 0
		), f'''number_of_steps needs to be positive integer, your input {number_of_steps}'''
		if number_of_steps == 1:
				return 1
		lowerCAmelCase	,		lowerCAmelCase     :    int						=   1, 1
		for _ in range(number_of_steps - 1	):
				lowerCAmelCase	,		lowerCAmelCase     :    Union[str, Any]						=   current + previous, current
		return current


if __name__ == "__main__":
					import doctest

					doctest.testmod()



