






from __future__ import annotations

from PIL import Image

# Define glider example
UpperCamelCase        =				[
    [0, 1, 0, 0, 0, 0, 0, 0],
    [0, 0, 1, 0, 0, 0, 0, 0],
    [1, 1, 1, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0],
]

# Define blinker example
UpperCamelCase        =				[[0, 1, 0], [0, 1, 0], [0, 1, 0]]




def 				A		(					lowercase__  :  list[list[int]]  )		-> list[list[int]]:
	UpperCamelCase__ :List[str]						=      []
	for i in range(len(lowercase__  )  ):
		UpperCamelCase__ :Optional[int]						=      []
		for j in range(len(cells[i]  )  ):
			# Get the number of live neighbours
			UpperCamelCase__ :Union[str, Any]						=      0
			if i > 0 and j > 0:
				neighbour_count += cells[i - 1][j - 1]
			if i > 0:
				neighbour_count += cells[i - 1][j]
			if i > 0 and j < len(cells[i]  ) - 1:
				neighbour_count += cells[i - 1][j + 1]
			if j > 0:
				neighbour_count += cells[i][j - 1]
			if j < len(cells[i]  ) - 1:
				neighbour_count += cells[i][j + 1]
			if i < len(lowercase__  ) - 1 and j > 0:
				neighbour_count += cells[i + 1][j - 1]
			if i < len(lowercase__  ) - 1:
				neighbour_count += cells[i + 1][j]
			if i < len(lowercase__  ) - 1 and j < len(cells[i]  ) - 1:
				neighbour_count += cells[i + 1][j + 1]

			# Rules of the game of life (excerpt from Wikipedia):
			# 1. Any live cell with two or three live neighbours survives.
			# 2. Any dead cell with three live neighbours becomes a live cell.
			# 3. All other live cells die in the next generation.
			#    Similarly, all other dead cells stay dead.
			UpperCamelCase__ :List[str]						=      cells[i][j] == 1
			if (
			    (alive and 2 <= neighbour_count <= 3)
			    or not alive
			    and neighbour_count == 3
			):
				next_generation_row.append(1  )
			else:
				next_generation_row.append(0  )

		next_generation.append(lowercase__  )
	return next_generation




def 				A		(					lowercase__  :  list[list[int]] ,		lowercase__  :  int  )		-> list[Image.Image]:
	UpperCamelCase__ :Tuple						=      []
	for _ in range(lowercase__  ):
		# Create output image
		UpperCamelCase__ :str						=      Image.new("""RGB""" ,		(len(cells[0]  ), len(lowercase__  ))  )
		UpperCamelCase__ :Any						=      img.load()

		# Save cells to image
		for x in range(len(lowercase__  )  ):
			for y in range(len(cells[0]  )  ):
				UpperCamelCase__ :Dict						=      255 - cells[y][x] * 255
				UpperCamelCase__ :Union[str, Any]						=      (colour, colour, colour)

        # Save image
		images.append(lowercase__  )
		UpperCamelCase__ :Union[str, Any]						=      new_generation(lowercase__  )
	return images


if __name__ == "__main__":
							UpperCamelCase        =				generate_images(GLIDER, 16)
							images[0].save("out.gif", save_all=True, append_images=images[1:])






import re

from flax.core.frozen_dict import freeze
from flax.traverse_util import flatten_dict, unflatten_dict
from jax.experimental import PartitionSpec as P


# Sentinels
_A					:				Optional[int]				=			object()

# For specifying empty leaf dict `{}`
_A					:				Tuple				=			object()


def 							__snake_case							(    lowerCAmelCase_ ,							lowerCAmelCase_	)				->						Dict:
    SCREAMING_SNAKE_CASE__											=			tuple((re.compile(x + '''$'''	) for x in qs)	)
    for i in range(len(lowerCAmelCase_	) - len(lowerCAmelCase_	) + 1	):
        SCREAMING_SNAKE_CASE__											=			[x.match(lowerCAmelCase_	) for x, y in zip(lowerCAmelCase_ ,							ks[i:]	)]
        if matches and all(lowerCAmelCase_	):
            return True
    return False


def 							__snake_case							(    lowerCAmelCase_	)				->						int:
    def replace(lowerCAmelCase_ ,							lowerCAmelCase_	):
        for rule, replacement in rules:
            if _match(lowerCAmelCase_ ,							lowerCAmelCase_	):
                return replacement
        return val

    return replace


def 							__snake_case							(    )				->						Optional[int]:
    return [
        # embeddings
        (("transformer", "wpe", "embedding"), P('''mp''' ,							lowerCAmelCase_	)),
        (("transformer", "wte", "embedding"), P('''mp''' ,							lowerCAmelCase_	)),
        # atention
        (("attention", "(q_proj|k_proj|v_proj)", "kernel"), P(lowerCAmelCase_ ,							'''mp'''	)),
        (("attention", "out_proj", "kernel"), P('''mp''' ,							lowerCAmelCase_	)),
        (("attention", "out_proj", "bias"), None),
        # mlp
        (("mlp", "c_fc", "kernel"), P(lowerCAmelCase_ ,							'''mp'''	)),
        (("mlp", "c_fc", "bias"), P('''mp'''	)),
        (("mlp", "c_proj", "kernel"), P('''mp''' ,							lowerCAmelCase_	)),
        (("mlp", "c_proj", "bias"), None),
        # layer norms
        ((r"ln_\d+", "bias"), None),
        ((r"\d+", r"ln_\d+", "scale"), None),
        (("ln_f", "bias"), None),
        (("ln_f", "scale"), None),
    ]



def 							__snake_case							(    lowerCAmelCase_	)				->						Optional[Any]:
    SCREAMING_SNAKE_CASE__											=			_get_partition_rules()
    SCREAMING_SNAKE_CASE__											=			_replacement_rules(lowerCAmelCase_	)
    SCREAMING_SNAKE_CASE__											=			{k: _unmatched for k in flatten_dict(lowerCAmelCase_	)}
    SCREAMING_SNAKE_CASE__											=			{k: replace(lowerCAmelCase_ ,							lowerCAmelCase_	) for k, v in initd.items()}
    assert _unmatched not in result.values(), "Incomplete partition spec."
    return freeze(unflatten_dict(lowerCAmelCase_	)	)
