I've written about \(n\)-free Fibonacci sequences in a post titled Free Fibonacci Sequences, one example of which is the 6-free Fibonacci sequence described as follows:
The sequences of \(n\)-free Fibonacci numbers were suggested by John H. Conway. The 6-free Fibonacci sequence is created by the sum of the two previous terms divided by the largest possible power of 6. The sequence coincides with the Fibonacci sequence until the first multiple of 6 in the Fibonacci sequence: 144, which in this sequence is divided by 36 to produce 4.
The resulting numbers form OEIS A232666 is:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 4, 93, 97, 190, 287, 477, 764, 1241, 2005, 541, 2546, 3087, 5633, 8720, 14353, 23073, 37426, 60499, 97925, 26404
The sequence is base-independent but the "twist" I'm giving to the traditional Fibonacci sequence in this post is base-dependent but it's nonetheless interesting as we'll see. Here is an explanation of what I'm doing. We start with a digit \(d\) between 0 and 9 and any integer \(s\) that does not contain \(d\). For example, \(d=1\) and \(s=2\) would be suitable. After that we begin the Fibonacci process using \(d\) and \(s\) as our seeds except that whenever a number appears containing one or more digits \(d\), they are all removed. A formal definition follows.
Formal Definition of the Digit-Restricted Fibonacci Sequence
Let $d\in\{0,1,2,\dots,9\}$ denote the restricted initial digit, and let $s\in\mathbb{Z}$ denote the arbitrary second initial term. We define a sequence $(a_n)_{n=0}^{\infty}$ generated by a modified second-order linear recurrence, subject to a nonlinear digit-deletion operator.
First, we define the digit-deletion function $\Phi_d:\mathbb{Z}\to\mathbb{Z}$. For any integer $x$, let the absolute value $|x|$ be represented in base-10 as a sequence of digits $C=c_kc_{k-1}\dots c_0$, where $c_i\in\{0,1,\dots,9\}$. Let $C'$ be the subsequence of digits obtained by removing all instances of the forbidden digit $d$ from $C$. The function is defined as:
where $\text{sgn}(x)$ represents the sign of $x$, and $\text{val}(C')$ represents the standard base-10 numerical evaluation of the concatenated digit string $C'$.
The sequence $(a_n)$ is then defined recursively by the following initial conditions and recurrence relation:
Termination Criteria
To algorithmically generate a finite subsequence $(a_n)_{n=0}^{N}$, we impose an upper bound constraint $M\in\mathbb{Z}^+$ (with a default of $M=40000$) and a period-detection mechanism. Sequence generation terminates at the index $N$ if either of the following conditions is satisfied:
Threshold Exceedance: The absolute value of the sequence term exceeds the designated maximum bound, such that:
$$|a_N|>M$$Loop Detection (Periodicity): The sequence enters a continuous cycle. Because $a_n$ is strictly dependent on the preceding pair $(a_{n-1},a_{n-2})$, periodicity is guaranteed if any consecutive pair repeats. The sequence terminates if there exists an index $k$ such that $1\le k<N-1$ satisfying:
$$(a_{k-1},a_k)=(a_{N-1},a_N)$$
Upon meeting either termination criterion, the resulting finite sequence $(a_0,a_1,\dots,a_N)$ is yielded.
Figure 1 was the final output which did exactly what I wanted using a "forbidden number" of 1 (thus \(d=1\) ) and a second number of 2 (thus \(s=2\) ). The 34 term sequence generated enters a loop once the terms 5 and 5 are reached with a highest value of 9:
![]() |
Figure 1: permalink |
![]() |
Figure 2: permalink |
This is a rather more interesting graph but the numbers eventually enter a loop. Every time a number exceeds 100, it ends up back under 100. For example:
- 1, 24, 25, 49, 74, 123 and the 123 becomes 23
- 23, 97, 120 and the 120 becomes 20
![]() |
Figure 3: permalink |
There's lots to explore here and I'll do that in subsequent posts but that's enough for now. Below the SageMath code is included for completeness.
Updated Python / SageMath Implementation
import matplotlib.pyplot as plt
def custom_fibonacci(forbidden_digit, second_num, max_val=40000):
"""
Generates a modified Fibonacci sequence where the starting digit is forbidden
from appearing in any subsequent terms.
"""
if not (0 <= forbidden_digit <= 9):
raise ValueError("The first entry must be a single digit from 0 to 9.")
sequence = [forbidden_digit, second_num]
seen_pairs = set()
seen_pairs.add((forbidden_digit, second_num))
forbidden_str = str(forbidden_digit)
entered_loop = False
while True:
raw_sum = sequence[-2] + sequence[-1]
sum_str = str(raw_sum)
filtered_str = sum_str.replace(forbidden_str, '')
if filtered_str == '' or filtered_str == '-':
next_term = 0
else:
next_term = int(filtered_str)
if next_term > max_val:
break
current_pair = (sequence[-1], next_term)
if current_pair in seen_pairs:
entered_loop = True
break
sequence.append(next_term)
seen_pairs.add(current_pair)
return sequence, entered_loop
def plot_trajectory(sequence, forbidden_digit, second_num):
"""
Plots the sequence trajectory with thin black lines, small black circles,
and dynamic headroom to prevent annotation overlap with the title.
"""
plt.figure(figsize=(12, 6))
# Plot with thin black lines and small black circles
plt.plot(sequence, color='black', marker='o', markersize=4, linewidth=1, linestyle='-')
# Find and annotate the maximum value
max_val = max(sequence)
max_index = sequence.index(max_val)
# Dynamically expand the y-axis to create headroom for the annotation
plt.ylim(bottom=min(sequence) - (max_val * 0.05), top=max_val * 1.15)
plt.annotate(f'Max Value Reached: {max_val}',
xy=(max_index, max_val),
xytext=(0, 15), # Offsets the text 15 points above the point
textcoords='offset points',
ha='center',
va='bottom',
bbox=dict(boxstyle='round,pad=0.3', fc='white', ec='gray', lw=0.5),
arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=0', color='black'))
# Formatting the graph with added title padding
plt.title(f"Modified Fibonacci Trajectory\nForbidden Digit: {forbidden_digit}
| Starting Number: {second_num}", pad=20)
plt.xlabel("Sequence Index (Term Number)")
plt.ylabel("Value")
plt.grid(True, linestyle='--', alpha=0.5)
plt.tight_layout()
plt.show()
# --- Execution and Display ---
digit_1 = 1
digit_2 = 2
max_limit = 40000
result_sequence, is_loop = custom_fibonacci(digit_1, digit_2, max_val=max_limit)
# 1. Print Text Output First
print(f"Starting Parameters: Forbidden Digit = {digit_1}, Second Number = {digit_2}")
print(f"Max Value Limit: {max_limit}")
print("-" * 50)
print(f"Resulting Sequence ({len(result_sequence)} terms):")
print(result_sequence)
print("-" * 50)
if is_loop:
print("Conclusion: The sequence entered a continuous loop.")
print(f"The repeating pair that triggered the stop was:
({result_sequence[-2]}, {result_sequence[-1]})")
else:
print(f"Conclusion: The sequence stopped because a term exceeded {max_limit}.")
# 2. Render Graph Below
plot_trajectory(result_sequence, digit_1, digit_2)



No comments:
Post a Comment