Python Forum
Thread Rating:
  • 1 Vote(s) - 4 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Recaman Sequence
#1
I saw this video on YouTube about the Recaman Sequence. I thought it was kind of interesting, so I wrote some code to play around with it:

"""
recaman.py

The Recaman Sequence and other similar sequences.

The Recaman Sequence has a value and a step. If the current value minus the
step is positive and has not been visited, that is the next value. Otherwise,
the next value is the current value plus the step. In either case, the step
increase by one.

Functions:
limit_list: Return a list from a generator, with limits. (list)
recaman: A generator for the Recaman sequence. (int)
recamanish: A generator for sequences similar to the Recaman sequence. (int)
step_function: Wrap a generator so it provides steps for recamanish. (callable)
"""

def limit_list(generator, max_len = 0, max_value = None):
	"""
	Return a list from a generator, with limits. (list)

	Parameters:
	max_size: return the list when it reaches this length. (int)
	max_value: return the list if it exceeds this value. (int)
	"""
	# Get values from the generator.
	output = []
	for value in generator:
		output.append(value)
		# Check for maximum length
		if len(output) == max_len:
			break
		# Check for maximum value.
		if max_value is not None and value > max_value:
			break
	return output

def recaman():
	"""A generator for the Recaman sequence. (int)"""
	# Set up initial values.
	current, step = 1, 1
	visited = set()
	while True:
		# Retun the current value
		yield current
		# Update value tracking
		visited.add(current)
		# Step backwards if possible, forwards otherwise.
		back = current - step
		if back > 0 and back not in visited:
			current = back
		else:
			current += step
		step += 1

def recamanish(current = 1, step = 1, step_mod = 1, step_forward = True,
	step_backward = True, step_function = None):
	"""
	A generator for sequences similar to the Recaman sequence. (int)

	The step_function should take two paramters: the current value and the current
	step. It returns the next step. If a step_function is provided, step_mod is
	ignored.

	Parameters:
	current: The starting value. (int)
	step: The initial step. (int)
	step_mod: How much the step increases each step. (int)
	step_forward: A flag for changing the step when moving forward. (bool)
	step_backward: A flag for changing the step when moving backward. (bool)
	step_function: A function to determine the next step. (callable)
	"""
	# Generate default step function if one is not given.
	if step_function is None:
		step_function = lambda current, step: step + step_mod
	visited = set()
	while True:
		# Return the current value.
		yield current
		# Update value tracking.
		visited.add(current)
		back = current - step
		# Check for backward movement.
		if back > 0 and back not in visited:
			current = back
			if step_backward:
				step = step_function(current, step)
		# Otherwise move forward.
		else:
			current += step
			if step_forward:
				step = step_function(current, step)

def step_function(step_generator):
	"""
	Wrap a generator so it provides steps for recamanish. (callable)

	Parameter:
	step_generator: A generator of integer values. (int)
	"""
	def step_func(current, step):
		return next(step_generator)
	return step_func
It's maybe not optimal, I don't use generators a lot.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020