


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





class    _a				:
	_a    :    Optional[Any]        =				"""block_{0}.dat"""




	def __init__(   self		:						int						,   _SCREAMING_SNAKE_CASE		:						str						)->			int:
			lowerCAmelCase__  :     List[str]       	=   filename
			lowerCAmelCase__  :     Tuple       	=   []




	def 				UpperCAmelCase__(   self		:						str						,   _SCREAMING_SNAKE_CASE		:						Any						,   _SCREAMING_SNAKE_CASE		:						List[Any]						)->			Tuple:
			lowerCAmelCase__  :     Dict       	=   self.BLOCK_FILENAME_FORMAT.format(_A						)
			with open(_A						,   '''w'''						) as file:
					file.write(_A						)
			self.block_filenames.append(_A						)




	def 				UpperCAmelCase__(   self		:						List[Any]						)->			List[Any]:
			return self.block_filenames




	def 				UpperCAmelCase__(   self		:						List[Any]						,   _SCREAMING_SNAKE_CASE		:						Optional[int]						,   _SCREAMING_SNAKE_CASE		:						List[str]=None						)->			Optional[Any]:
			lowerCAmelCase__  :     Optional[Any]       	=   0
			with open(self.filename						) as file:
					while True:
							lowerCAmelCase__  :     Dict       	=   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 				UpperCAmelCase__(   self		:						Dict						)->			List[str]:
			map(os.remove						,   self.block_filenames						)





class    _a				:




	def 				UpperCAmelCase__(   self		:						Dict						,   _SCREAMING_SNAKE_CASE		:						List[str]						)->			Tuple:
			lowerCAmelCase__  :     int       	=   -1
			lowerCAmelCase__  :     Optional[Any]       	=   None

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

			return min_index





class    _a				:




	def __init__(   self		:						Optional[int]						,   _SCREAMING_SNAKE_CASE		:						Dict						)->			Optional[int]:
			lowerCAmelCase__  :     Optional[Any]       	=   files
			lowerCAmelCase__  :     Union[str, Any]       	=   set()
			lowerCAmelCase__  :     Tuple       	=   len(_A						)
			lowerCAmelCase__  :     Optional[int]       	=   {i: None for i in range(self.num_buffers						)}




	def 				UpperCAmelCase__(   self		:						Dict						)->			List[Any]:
			return {
			    i: self.buffers[i] for i in range(self.num_buffers						) if i not in self.empty
			}




	def 				UpperCAmelCase__(   self		:						Any						)->			int:



			for i in range(self.num_buffers						):
					if self.buffers[i] is None and i not in self.empty:
							lowerCAmelCase__  :     int       	=   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 				UpperCAmelCase__(   self		:						int						,   _SCREAMING_SNAKE_CASE		:						int						)->			List[Any]:
			lowerCAmelCase__  :     Tuple       	=   self.buffers[index]
			lowerCAmelCase__  :     str       	=   None

			return value





class    _a				:




	def __init__(   self		:						Union[str, Any]						,   _SCREAMING_SNAKE_CASE		:						Optional[Any]						)->			Tuple:
			lowerCAmelCase__  :     Dict       	=   merge_strategy




	def 				UpperCAmelCase__(   self		:						int						,   _SCREAMING_SNAKE_CASE		:						Tuple						,   _SCREAMING_SNAKE_CASE		:						Tuple						,   _SCREAMING_SNAKE_CASE		:						Optional[Any]						)->			Optional[int]:
			lowerCAmelCase__  :     str       	=   FilesArray(self.get_file_handles(_A						,   _A						)						)
			with open(_A						,   '''w'''						,   _A						) as outfile:
					while buffers.refresh():
							lowerCAmelCase__  :     str       	=   self.merge_strategy.select(buffers.get_dict()						)
							outfile.write(buffers.unshift(_A						)						)




	def 				UpperCAmelCase__(   self		:						Optional[int]						,   _SCREAMING_SNAKE_CASE		:						Union[str, Any]						,   _SCREAMING_SNAKE_CASE		:						Tuple						)->			str:
			lowerCAmelCase__  :     Dict       	=   {}

			for i in range(len(_A						)						):
					lowerCAmelCase__  :     Tuple       	=   open(filenames[i]						,   '''r'''						,   _A						)  # noqa: UP015

			return files





class    _a				:




	def __init__(   self		:						Dict						,   _SCREAMING_SNAKE_CASE		:						Union[str, Any]						)->			Optional[int]:
			lowerCAmelCase__  :     Any       	=   block_size




	def 				UpperCAmelCase__(   self		:						int						,   _SCREAMING_SNAKE_CASE		:						int						,   _SCREAMING_SNAKE_CASE		:						int=None						)->			Tuple:
			lowerCAmelCase__  :     int       	=   self.get_number_blocks(_A						,   self.block_size						)
			lowerCAmelCase__  :     str       	=   FileSplitter(_A						)
			splitter.split(self.block_size						,   _A						)

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

			splitter.cleanup()




	def 				UpperCAmelCase__(   self		:						str						,   _SCREAMING_SNAKE_CASE		:						Optional[int]						,   _SCREAMING_SNAKE_CASE		:						Optional[Any]						)->			Tuple:
			return (os.stat(_A						).st_size / block_size) + 1






def 	lowerCamelCase_       (			_a			):




		"""simple docstring"""






		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(SCREAMING_SNAKE_CASE_			)






def 	lowerCamelCase_       (			):




		"""simple docstring"""






		lowerCAmelCase__  :     Union[str, 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'''			)
		lowerCAmelCase__  :     List[Any]       	=   parser.parse_args()

		lowerCAmelCase__  :     Union[str, Any]       	=   ExternalSort(parse_memory(args.mem			)			)
		sorter.sort(args.filename[0]			)


if __name__ == "__main__":
		main()










from __future__ import annotations

from pathlib import Path







def       _a (		SCREAMING_SNAKE_CASE_				:							tuple[int, int] , SCREAMING_SNAKE_CASE_				:							tuple[int, int]	):
					return pointa[0] * pointa[1] - pointa[1] * pointa[0]







def       _a (		SCREAMING_SNAKE_CASE_				:							int , SCREAMING_SNAKE_CASE_				:							int , SCREAMING_SNAKE_CASE_				:							int , SCREAMING_SNAKE_CASE_				:							int , SCREAMING_SNAKE_CASE_				:							int , SCREAMING_SNAKE_CASE_				:							int	):
					__lowerCAmelCase							  =			(xa, ya)
					__lowerCAmelCase							  =			(xa - xa, ya - ya)
					__lowerCAmelCase							  =			(xa - xa, ya - ya)
					__lowerCAmelCase							  =			-vector_product(SCREAMING_SNAKE_CASE_ , SCREAMING_SNAKE_CASE_	) / vector_product(
					    SCREAMING_SNAKE_CASE_ , SCREAMING_SNAKE_CASE_	)
					__lowerCAmelCase							  =			+vector_product(SCREAMING_SNAKE_CASE_ , SCREAMING_SNAKE_CASE_	) / vector_product(
					    SCREAMING_SNAKE_CASE_ , SCREAMING_SNAKE_CASE_	)

					return a > 0 and b > 0 and a + b < 1







def       _a (		SCREAMING_SNAKE_CASE_				:							str = "p102_triangles.txt"	):
					__lowerCAmelCase							  =			Path(SCREAMING_SNAKE_CASE_	).parent.joinpath(SCREAMING_SNAKE_CASE_	).read_text(encoding="utf-8"	)

					__lowerCAmelCase							  =			[]
					for line in data.strip().split("\n"	):
										triangles.append([int(SCREAMING_SNAKE_CASE_	) for number in line.split(","	)]	)

					__lowerCAmelCase							  =			0
					__lowerCAmelCase							  =			42

					for triangle in triangles:
										ret += contains_origin(*SCREAMING_SNAKE_CASE_	)

					return ret


if __name__ == "__main__":
					print(f'''{solution() = }''')




