import math


def bf_wheel (n):
	"""
	Bruteforce trial factorization with successive integers as
	candidate factors. uses a wheel mod 6 to speed things 
	up a lot. can be expanded to wheel mod 30 by adding to the
	prime basis, but takes extra steps in the trial phase. this seems
	to be the most optimized version I could put together.

	Arguments:
		n (:int) - the number to factor
	Returns:
		(generator) - prime factors of n
	Examples:
		>>> [p for p in bf_wheel(20)]
		(2, 2, 5,)
	Author: ChairsDaily
	"""
	if n <= 3: return n > 1
	while math.sqrt(n) == int(math.sqrt(n)):
		yield math.sqrt(n)
		n //= math.sqrt(n)
	if not n % 2 or not n % 3:
		while not n % 2: 
			yield 2
			n //= 2
		
		while not n % 3: 
			yield 3
			n //= 3

	# starting value for candidate
	# and improved upper bound
	d = 5
	upper = math.ceil(math.sqrt(n))

	while d < upper:
		while n % d == 0:
			n //= d
			yield d

		# correction case for wheel mod 6
		# we skipped the middle five digits essentially
		while n % (d + 2) == 0: 
			n //= (d + 2)
			yield (d + 2)

		if n == 1: break 
		d += 6
	if n > 1: yield n