




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






class      A     :
     """simple docstring"""

     _snake_case:		Tuple       ="block_{0}.dat"




     def __init__(      self					:				Any		,					A__					:				Dict     )			->    List[str]:
           lowerCamelCase__ 					=			filename
           lowerCamelCase__ 					=			[]




     def 	__snake_case				(      self					:				Optional[int]		,					A__					:				str		,					A__					:				Optional[int]     )			->    Any:
           lowerCamelCase__ 					=			self.BLOCK_FILENAME_FORMAT.format(A__     )
           with open(A__		,					'w'     ) as file:
                 file.write(A__     )
           self.block_filenames.append(A__     )




     def 	__snake_case				(      self					:				Optional[Any]     )			->    Union[str, Any]:
           return self.block_filenames




     def 	__snake_case				(      self					:				int		,					A__					:				Any		,					A__					:				List[str]=None     )			->    Optional[int]:
           lowerCamelCase__ 					=			0
           with open(self.filename     ) as file:
                 while True:
                       lowerCamelCase__ 					=			file.readlines(A__     )

                       if lines == []:
                             break

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

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




     def 	__snake_case				(      self					:				Optional[int]     )			->    int:
           map(os.remove		,					self.block_filenames     )






class      A     :
     """simple docstring"""

     def 	__snake_case				(      self					:				Dict		,					A__					:				Dict     )			->    List[Any]:
           lowerCamelCase__ 					=			-1
           lowerCamelCase__ 					=			None

           for i in range(len(A__     )     ):
                 if min_str is None or choices[i] < min_str:
                       lowerCamelCase__ 					=			i

           return min_index






class      A     :
     """simple docstring"""

     def __init__(      self					:				Tuple		,					A__					:				str     )			->    str:
           lowerCamelCase__ 					=			files
           lowerCamelCase__ 					=			set()
           lowerCamelCase__ 					=			len(A__     )
           lowerCamelCase__ 					=			{i: None for i in range(self.num_buffers     )}




     def 	__snake_case				(      self					:				Any     )			->    Optional[int]:
           return {
               i: self.buffers[i] for i in range(self.num_buffers     ) if i not in self.empty
           }




     def 	__snake_case				(      self					:				Union[str, Any]     )			->    Any:
           for i in range(self.num_buffers     ):
                 if self.buffers[i] is None and i not in self.empty:
                       lowerCamelCase__ 					=			self.files[i].readline()

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

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

           return True




     def 	__snake_case				(      self					:				Any		,					A__					:				int     )			->    int:
           lowerCamelCase__ 					=			self.buffers[index]
           lowerCamelCase__ 					=			None

           return value






class      A     :
     """simple docstring"""

     def __init__(      self					:				Optional[int]		,					A__					:				Union[str, Any]     )			->    Union[str, Any]:
           lowerCamelCase__ 					=			merge_strategy




     def 	__snake_case				(      self					:				Tuple		,					A__					:				Dict		,					A__					:				Union[str, Any]		,					A__					:				int     )			->    Union[str, Any]:
           lowerCamelCase__ 					=			FilesArray(self.get_file_handles(A__		,					A__     )     )
           with open(A__		,					'w'		,					A__     ) as outfile:
                 while buffers.refresh():
                       lowerCamelCase__ 					=			self.merge_strategy.select(buffers.get_dict()     )
                       outfile.write(buffers.unshift(A__     )     )




     def 	__snake_case				(      self					:				str		,					A__					:				Dict		,					A__					:				str     )			->    Dict:
           lowerCamelCase__ 					=			{}

           for i in range(len(A__     )     ):
                 lowerCamelCase__ 					=			open(filenames[i]		,					'r'		,					A__     )  # noqa: UP015

           return files






class      A     :
     """simple docstring"""

     def __init__(      self					:				Tuple		,					A__					:				Optional[int]     )			->    List[str]:
           lowerCamelCase__ 					=			block_size




     def 	__snake_case				(      self					:				List[str]		,					A__					:				Union[str, Any]		,					A__					:				Union[str, Any]=None     )			->    Optional[Any]:
           lowerCamelCase__ 					=			self.get_number_blocks(A__		,					self.block_size     )
           lowerCamelCase__ 					=			FileSplitter(A__     )
           splitter.split(self.block_size		,					A__     )

           lowerCamelCase__ 					=			FileMerger(NWayMerge()     )
           lowerCamelCase__ 					=			self.block_size / (num_blocks + 1)
           merger.merge(splitter.get_block_filenames()		,					filename + '.out'		,					A__     )

           splitter.cleanup()




     def 	__snake_case				(      self					:				Tuple		,					A__					:				List[str]		,					A__					:				Optional[Any]     )			->    List[str]:
           return (os.stat(A__     ).st_size / block_size) + 1

def      lowerCAmelCase_     (					lowerCamelCase:    int  )   ->     List[Any]:


      '''simple docstring'''




      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_     (					)   ->     Tuple:


      '''simple docstring'''




      lowerCamelCase__ 					=			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'  )
      lowerCamelCase__ 					=			parser.parse_args()

      lowerCamelCase__ 					=			ExternalSort(parse_memory(args.mem  )  )
      sorter.sort(args.filename[0]  )


if __name__ == "__main__":
      main()





def      lowerCAmelCase_     (					lowerCamelCase:    list       ,			lowerCamelCase:    int       ,			lowerCamelCase:    int  )   ->     None:


      '''simple docstring'''




      if right <= left:
            return
      lowerCamelCase__ 					=			lowerCamelCase__ 					=			left
      lowerCamelCase__ 					=			right
      lowerCamelCase__ 					=			sorting[left]
      while i <= b:
            if sorting[i] < pivot:
                  lowerCamelCase__					,						lowerCamelCase__ 					=			sorting[i], sorting[a]
                  a += 1
                  i += 1
            elif sorting[i] > pivot:
                  lowerCamelCase__					,						lowerCamelCase__ 					=			sorting[i], sorting[b]
                  b -= 1
            else:
                  i += 1
      quick_sort_apartition(lowerCamelCase       ,			lowerCamelCase       ,			a - 1  )
      quick_sort_apartition(lowerCamelCase       ,			b + 1       ,			lowerCamelCase  )

def      lowerCAmelCase_     (					lowerCamelCase:    list       ,			lowerCamelCase:    int       ,			lowerCamelCase:    int  )   ->     None:


      '''simple docstring'''




      if left < right:
            lowerCamelCase__ 					=			lomuto_partition(lowerCamelCase       ,			lowerCamelCase       ,			lowerCamelCase  )
            quick_sort_lomuto_partition(lowerCamelCase       ,			lowerCamelCase       ,			pivot_index - 1  )
            quick_sort_lomuto_partition(lowerCamelCase       ,			pivot_index + 1       ,			lowerCamelCase  )

def      lowerCAmelCase_     (					lowerCamelCase:    list       ,			lowerCamelCase:    int       ,			lowerCamelCase:    int  )   ->     int:


      '''simple docstring'''




      lowerCamelCase__ 					=			sorting[right]
      lowerCamelCase__ 					=			left
      for i in range(lowerCamelCase       ,			lowerCamelCase  ):
            if sorting[i] < pivot:
                  lowerCamelCase__					,						lowerCamelCase__ 					=			sorting[i], sorting[store_index]
                  store_index += 1
      lowerCamelCase__					,						lowerCamelCase__ 					=			sorting[store_index], sorting[right]
      return store_index

def      lowerCAmelCase_     (					lowerCamelCase:    list  )   ->     list:


      '''simple docstring'''




      if len(lowerCamelCase  ) <= 1:
            return sorting
      return (
          three_way_radix_quicksort([i for i in sorting if i < sorting[0]]  )
          + [i for i in sorting if i == sorting[0]]
          + three_way_radix_quicksort([i for i in sorting if i > sorting[0]]  )
      )


if __name__ == "__main__":
      import doctest

      doctest.testmod(verbose=True)

      __SCREAMING_SNAKE_CASE      :				Optional[int]				      =input("""Enter numbers separated by a comma:\n""").strip()
      __SCREAMING_SNAKE_CASE      :				str				      =[int(item) for item in user_input.split(""",""")]
      quick_sort_apartition(unsorted, 0, len(unsorted) - 1)
      print(unsorted)