





#
# Sort large text files in a minimum amount of memory
#
import argparse
import os



class 				_lowerCAmelCase			:


  '''simple docstring'''
  a_							:				str					    ="""block_{0}.dat"""







  def __init__(					self					:    Union[str, Any]					, UpperCamelCase					:    Tuple							):


    '''simple docstring'''





    _snake_case      : Any														=		filename
    _snake_case      : str														=		[]







  def UpperCamelCase_       (					self					:    Optional[int]					, UpperCamelCase					:    str					, UpperCamelCase					:    Dict							):


    '''simple docstring'''





    _snake_case      : str														=		self.BLOCK_FILENAME_FORMAT.format(UpperCamelCase							)
    with open(UpperCamelCase					, 'w'							) as file:
      file.write(UpperCamelCase							)
    self.block_filenames.append(UpperCamelCase							)







  def UpperCamelCase_       (					self					:    List[str]							):


    '''simple docstring'''





    return self.block_filenames







  def UpperCamelCase_       (					self					:    Union[str, Any]					, UpperCamelCase					:    List[str]					, UpperCamelCase					:    int=None							):


    '''simple docstring'''





    _snake_case      : Dict														=		0
    with open(self.filename							) as file:
      while True:
        _snake_case      : Optional[Any]														=		file.readlines(UpperCamelCase							)

        if lines == []:
          break

        if sort_key is None:
          lines.sort()
        else:
          lines.sort(key=UpperCamelCase							)

        self.write_block(''.join(UpperCamelCase							)					, UpperCamelCase							)
        i += 1







  def UpperCamelCase_       (					self					:    Optional[Any]							):


    '''simple docstring'''





    map(os.remove					, self.block_filenames							)




class 				_lowerCAmelCase			:


  '''simple docstring'''







  def UpperCamelCase_       (					self					:    Union[str, Any]					, UpperCamelCase					:    Any							):


    '''simple docstring'''





    _snake_case      : List[Any]														=		-1
    _snake_case      : Dict														=		None

    for i in range(len(UpperCamelCase							)							):
      if min_str is None or choices[i] < min_str:
        _snake_case      : List[Any]														=		i

    return min_index




class 				_lowerCAmelCase			:


  '''simple docstring'''







  def __init__(					self					:    Tuple					, UpperCamelCase					:    Tuple							):


    '''simple docstring'''





    _snake_case      : Optional[Any]														=		files
    _snake_case      : str														=		set()
    _snake_case      : Dict														=		len(UpperCamelCase							)
    _snake_case      : Optional[Any]														=		{i: None for i in range(self.num_buffers							)}







  def UpperCamelCase_       (					self					:    int							):


    '''simple docstring'''





    return {
        i: self.buffers[i] for i in range(self.num_buffers							) if i not in self.empty
    }







  def UpperCamelCase_       (					self					:    Dict							):


    '''simple docstring'''





    for i in range(self.num_buffers							):
      if self.buffers[i] is None and i not in self.empty:
        _snake_case      : Tuple														=		self.files[i].readline()

        if self.buffers[i] == "":
          self.empty.add(UpperCamelCase							)
          self.files[i].close()

    if len(self.empty							) == self.num_buffers:
      return False

    return True







  def UpperCamelCase_       (					self					:    List[str]					, UpperCamelCase					:    List[Any]							):


    '''simple docstring'''





    _snake_case      : str														=		self.buffers[index]
    _snake_case      : Optional[Any]														=		None

    return value




class 				_lowerCAmelCase			:


  '''simple docstring'''







  def __init__(					self					:    List[Any]					, UpperCamelCase					:    str							):


    '''simple docstring'''





    _snake_case      : List[Any]														=		merge_strategy







  def UpperCamelCase_       (					self					:    Dict					, UpperCamelCase					:    Union[str, Any]					, UpperCamelCase					:    List[str]					, UpperCamelCase					:    Dict							):


    '''simple docstring'''





    _snake_case      : int														=		FilesArray(self.get_file_handles(UpperCamelCase					, UpperCamelCase							)							)
    with open(UpperCamelCase					, 'w'					, UpperCamelCase							) as outfile:
      while buffers.refresh():
        _snake_case      : Tuple														=		self.merge_strategy.select(buffers.get_dict()							)
        outfile.write(buffers.unshift(UpperCamelCase							)							)







  def UpperCamelCase_       (					self					:    List[str]					, UpperCamelCase					:    Dict					, UpperCamelCase					:    Any							):


    '''simple docstring'''





    _snake_case      : Any														=		{}

    for i in range(len(UpperCamelCase							)							):
      _snake_case      : Optional[Any]														=		open(filenames[i]					, 'r'					, UpperCamelCase							)  # noqa: UP015

    return files




class 				_lowerCAmelCase			:


  '''simple docstring'''







  def __init__(					self					:    Any					, UpperCamelCase					:    str							):


    '''simple docstring'''





    _snake_case      : Union[str, Any]														=		block_size







  def UpperCamelCase_       (					self					:    str					, UpperCamelCase					:    List[Any]					, UpperCamelCase					:    Tuple=None							):


    '''simple docstring'''





    _snake_case      : List[Any]														=		self.get_number_blocks(UpperCamelCase					, self.block_size							)
    _snake_case      : Any														=		FileSplitter(UpperCamelCase							)
    splitter.split(self.block_size					, UpperCamelCase							)

    _snake_case      : int														=		FileMerger(NWayMerge()							)
    _snake_case      : Optional[Any]														=		self.block_size / (num_blocks + 1)
    merger.merge(splitter.get_block_filenames()					, filename + '.out'					, UpperCamelCase							)

    splitter.cleanup()







  def UpperCamelCase_       (					self					:    List[str]					, UpperCamelCase					:    List[str]					, UpperCamelCase					:    List[str]							):


    '''simple docstring'''





    return (os.stat(UpperCamelCase							).st_size / block_size) + 1




def 			lowerCamelCase_		(					lowerCAmelCase:		Dict )->						Dict:
  if string[-1].lower() == "k":
    return int(string[:-1] ) * 10_24
  elif string[-1].lower() == "m":
    return int(string[:-1] ) * 10_24 * 10_24
  elif string[-1].lower() == "g":
    return int(string[:-1] ) * 10_24 * 10_24 * 10_24
  else:
    return int(lowerCAmelCase )


def 			lowerCamelCase_		(					)->						List[Any]:
  _snake_case      : str														=		argparse.ArgumentParser()
  parser.add_argument(
      '-m'			,							'--mem'			,							help='amount of memory to use for sorting'			,							default='100M' )
  parser.add_argument(
      'filename'			,							metavar='<filename>'			,							nargs=1			,							help='name of file to sort' )
  _snake_case      : Optional[Any]														=		parser.parse_args()

  _snake_case      : Tuple														=		ExternalSort(parse_memory(args.mem ) )
  sorter.sort(args.filename[0] )


if __name__ == "__main__":
      main()











def 			lowerCamelCase_		(					lowerCAmelCase:		str			,							lowerCAmelCase:		str )->						int:
  # The longer word should come first
  if len(lowerCAmelCase ) < len(lowerCAmelCase ):
    return levenshtein_distance(lowerCAmelCase			,							lowerCAmelCase )

  if len(lowerCAmelCase ) == 0:
    return len(lowerCAmelCase )

  _snake_case      : Dict														=		list(range(len(lowerCAmelCase ) + 1 ) )

  for i, ca in enumerate(lowerCAmelCase ):
    _snake_case      : Optional[int]														=		[i + 1]

    for j, ca in enumerate(lowerCAmelCase ):
      # Calculate insertions, deletions and substitutions
      _snake_case      : Optional[Any]														=		previous_row[j + 1] + 1
      _snake_case      : Optional[int]														=		current_row[j] + 1
      _snake_case      : Union[str, Any]														=		previous_row[j] + (ca != ca)

      # Get the minimum to append to the current row
      current_row.append(min(lowerCAmelCase			,							lowerCAmelCase			,							lowerCAmelCase ) )

    # Store the previous row
    _snake_case      : str														=		current_row

  # Returns the last element (distance)
  return previous_row[-1]


if __name__ == "__main__":
      lowerCAmelCase_        =			input("""Enter the first word:\n""").strip()
      lowerCAmelCase_        =			input("""Enter the second word:\n""").strip()

      lowerCAmelCase_        =			levenshtein_distance(first_word, second_word)
      print(F"""Levenshtein distance between {first_word} and {second_word} is {result}""")




