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


class   __lowerCAmelCase		:



      """simple docstring"""







      A__		:     List[Any]       				=      '''block_{0}.dat'''




      def __init__( self						:    str			,    _snake_case						:    int			):
          __lowercase						:     Union[str, Any]		      =    filename
          __lowercase						:     Union[str, Any]		      =    []




      def 						snake_case_     ( self						:    int			,    _snake_case						:    Dict			,    _snake_case						:    Dict			):
          __lowercase						:     str		      =    self.BLOCK_FILENAME_FORMAT.format(_snake_case			)
          with open(_snake_case			,    '''w'''			) as file:
              file.write(_snake_case			)
          self.block_filenames.append(_snake_case			)




      def 						snake_case_     ( self						:    int			):
          return self.block_filenames




      def 						snake_case_     ( self						:    Optional[int]			,    _snake_case						:    Optional[int]			,    _snake_case						:    str=None			):
          __lowercase						:     int		      =    0
          with open(self.filename			) as file:
              while True:
                  __lowercase						:     int		      =    file.readlines(_snake_case			)

                  if lines == []:
                      break

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

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




      def 						snake_case_     ( self						:    Dict			):
          map(os.remove			,    self.block_filenames			)






class   __lowerCAmelCase		:



      """simple docstring"""







      def 						snake_case_     ( self						:    Any			,    _snake_case						:    Tuple			):
          __lowercase						:     List[str]		      =    -1
          __lowercase						:     Optional[int]		      =    None

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

          return min_index






class   __lowerCAmelCase		:



      """simple docstring"""







      def __init__( self						:    Optional[int]			,    _snake_case						:    Dict			):
          __lowercase						:     Optional[Any]		      =    files
          __lowercase						:     List[Any]		      =    set()
          __lowercase						:     Optional[int]		      =    len(_snake_case			)
          __lowercase						:     Optional[int]		      =    {i: None for i in range(self.num_buffers			)}




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




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

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

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

          return True




      def 						snake_case_     ( self						:    List[Any]			,    _snake_case						:    Any			):
          __lowercase						:     Union[str, Any]		      =    self.buffers[index]
          __lowercase						:     List[Any]		      =    None

          return value






class   __lowerCAmelCase		:



      """simple docstring"""







      def __init__( self						:    List[str]			,    _snake_case						:    Tuple			):
          __lowercase						:     Optional[int]		      =    merge_strategy




      def 						snake_case_     ( self						:    Dict			,    _snake_case						:    List[Any]			,    _snake_case						:    Any			,    _snake_case						:    str			):
          __lowercase						:     Union[str, Any]		      =    FilesArray(self.get_file_handles(_snake_case			,    _snake_case			)			)
          with open(_snake_case			,    '''w'''			,    _snake_case			) as outfile:
              while buffers.refresh():
                  __lowercase						:     Optional[int]		      =    self.merge_strategy.select(buffers.get_dict()			)
                  outfile.write(buffers.unshift(_snake_case			)			)




      def 						snake_case_     ( self						:    Optional[Any]			,    _snake_case						:    Tuple			,    _snake_case						:    Any			):
          __lowercase						:     Any		      =    {}

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

          return files






class   __lowerCAmelCase		:



      """simple docstring"""







      def __init__( self						:    Optional[int]			,    _snake_case						:    List[str]			):
          __lowercase						:     List[str]		      =    block_size




      def 						snake_case_     ( self						:    int			,    _snake_case						:    List[str]			,    _snake_case						:    Dict=None			):
          __lowercase						:     Optional[Any]		      =    self.get_number_blocks(_snake_case			,    self.block_size			)
          __lowercase						:     Optional[int]		      =    FileSplitter(_snake_case			)
          splitter.split(self.block_size			,    _snake_case			)

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

          splitter.cleanup()




      def 						snake_case_     ( self						:    str			,    _snake_case						:    Union[str, Any]			,    _snake_case						:    Any			):
          return (os.stat(_snake_case			).st_size / block_size) + 1






def       UpperCAmelCase_					(  __lowerCAmelCase		)	->  str:
    if string[-1].lower() == "k":
        return int(string[:-1]		) * 1_024
    elif string[-1].lower() == "m":
        return int(string[:-1]		) * 1_024 * 1_024
    elif string[-1].lower() == "g":
        return int(string[:-1]		) * 1_024 * 1_024 * 1_024
    else:
        return int(__lowerCAmelCase		)


def       UpperCAmelCase_					(  )	->  Tuple:
    __lowercase						:     Any		      =    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'''		)
    __lowercase						:     Optional[int]		      =    parser.parse_args()

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


if __name__ == "__main__":
 main()




from __future__ import annotations

from collections import Counter


def       UpperCAmelCase_					(  __lowerCAmelCase		)	->  list[int]:
    __lowercase						:     Any		      =    [True] * n
    __lowercase						:     str		      =    False
    __lowercase						:     int		      =    False
    __lowercase						:     List[Any]		      =    True

    for i in range(3		,   int(n**0.5 + 1		)		,   2		):
        __lowercase						:     List[str]		      =    i * 2
        while index < n:
            __lowercase						:     List[Any]		      =    False
            __lowercase						:     Dict		      =    index + i

    __lowercase						:     Tuple		      =    [2]

    for i in range(3		,   __lowerCAmelCase		,   2		):
        if is_prime[i]:
            primes.append(__lowerCAmelCase		)

    return primes


def       UpperCAmelCase_					(  __lowerCAmelCase		)	->  list[list[int]]:
    __lowercase						:     Optional[int]		      =    str(__lowerCAmelCase		)
    __lowercase						:     List[str]		      =    []
    __lowercase						:     int		      =    ['''0''', '''1''', '''2''', '''3''', '''4''', '''5''', '''6''', '''7''', '''8''', '''9''']

    for duplicate in Counter(__lowerCAmelCase		) - Counter(set(__lowerCAmelCase		)		):
        __lowercase						:     Union[str, Any]		      =    [int(number_str.replace(__lowerCAmelCase		,   __lowerCAmelCase		)		) for digit in digits]
        replacements.append(__lowerCAmelCase		)

    return replacements


def       UpperCAmelCase_					(  __lowerCAmelCase = 8		)	->  int:
    __lowercase						:     Tuple		      =    set()

    # Filter primes with less than 3 replaceable digits
    __lowercase						:     int		      =    {
        x for x in set(prime_sieve(1_000_000		)		) if len(str(__lowerCAmelCase		)		) - len(set(str(__lowerCAmelCase		)		)		) >= 3
    }

    for prime in primes:
        if prime in numbers_checked:
            continue

        __lowercase						:     str		      =    digit_replacements(__lowerCAmelCase		)

        for family in replacements:
            numbers_checked.update(__lowerCAmelCase		)
            __lowercase						:     List[Any]		      =    primes.intersection(__lowerCAmelCase		)

            if len(__lowerCAmelCase		) != family_length:
                continue

            return min(__lowerCAmelCase		)

    return -1


if __name__ == "__main__":
 print(solution())


