Monday, 16 March 2026

There Can Be Only One 2

Let's recall the Fibonacci-like sequence from my previous blog post titled There Can Be Only One 1.

We start with a digit \(d\) between 0 and 9 and any integer \(s\) that does not contain \(d\). For example, 1 and 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. 

In my previous post, I looked at three scenarios:

  • \(d=1\) and \(s=2\)
  • \(d=1\) and \(s=24\)
  • \(d=1\) and \(s=70\)
A major change occurs when we consider \(d=2\) as our "forbidden digit". Suddenly the 100 barrier can be breached as can be seen in Figure 1 where the sequence for \(d=2\) and \(s=1\) is depicted. Here the resulting sequence does not loop but exceeds the upper bound of 40000 that was set.


Figure 1: permalink

The sequence progresses like this:

[2, 1, 3, 4, 7, 11, 18, 9, 7, 16, 3, 19, 0, 19, 19, 38, 57, 95, 15, 110, 15, 15, 30, 45, 75, 10, 85, 95, 180, 75, 55, 130, 185, 315, 500, 815, 1315, 130, 1445, 1575, 300, 1875, 175, 50, 5, 55, 60, 115, 175, 90, 65, 155, 0, 155, 155, 310, ...

We can see that 155 + 155 = 310 jumps over the 200 barrier and from there it becomes seemingly unbounded (I tested up to ten million).

Not all values of \(s\) lead to unbounded sequences. For example, \(s=5\) leads quickly to a loop (see Figure 2): 

Starting Parameters: Forbidden Digit = 2, Second Number = 5

Max Value Limit: 40000
--------------------------------------------------
Resulting Sequence (17 terms):
[2, 5, 7, 1, 8, 9, 17, 6, 3, 9, 1, 10, 11, 1, 1, 0, 1]
--------------------------------------------------
Conclusion: The sequence entered a continuous loop.
The repeating pair that triggered the stop was: (0, 1)

Figure 2: permalink

Sequences are unbounded for \(s=1, 3, 4\) but loop for \(s=5, 6, 7, 8, 9, 10\) before becoming unbounded again for \(s=11\).

Sunday, 15 March 2026

There Can Be Only One 1

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:

$$\Phi_d(x)=\begin{cases}0&\text{if }C'\text{ is the empty string},\\\text{sgn}(x)\cdot\text{val}(C')&\text{otherwise},\end{cases}$$

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:

$$\begin{aligned}a_0&=d,\\a_1&=s,\\a_n&=\Phi_d(a_{n-1}+a_{n-2})\quad\text{for }n\ge 2.\end{aligned}$$


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:
  1. Threshold Exceedance: The absolute value of the sequence term exceeds the designated maximum bound, such that:

    $$|a_N|>M$$
  2. 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:

1, 2, 3, 5, 8, 3, 0, 3, 3, 6, 9, 5, 4, 9, 3, 2, 5, 7, 2, 9, 0, 9, 9, 8, 7, 5, 2, 7, 9, 6, 5, 0, 5, 5


Figure 1: permalink

Let's retain 1 as our "forbidden number" (thus \(d=1\) ) and use 24 as the second number (thus \(s=24\) ). Figure 2 shows the result. The 134 term sequence that generated enters a loop once the terms 2 and 8 are reached with a highest value of 98:

1, 24, 25, 49, 74, 23, 97, 20, 7, 27, 34, 6, 40, 46, 86, 32, 8, 40, 48, 88, 36, 24, 60, 84, 44, 28, 72, 0, 72, 72, 44, 6, 50, 56, 6, 62, 68, 30, 98, 28, 26, 54, 80, 34, 4, 38, 42, 80, 22, 2, 24, 26, 50, 76, 26, 2, 28, 30, 58, 88, 46, 34, 80, 4, 84, 88, 72, 60, 32, 92, 24, 6, 30, 36, 66, 2, 68, 70, 38, 8, 46, 54, 0, 54, 54, 8, 62, 70, 32, 2, 34, 36, 70, 6, 76, 82, 58, 40, 98, 38, 36, 74, 0, 74, 74, 48, 22, 70, 92, 62, 54, 6, 60, 66, 26, 92, 8, 0, 8, 8, 6, 4, 0, 4, 4, 8, 2, 0, 2, 2, 4, 6, 0, 6, 6, 2, 8


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
The result is that the maximum value that this 137 term sequence reaches is 98. Let's try 70 as our second number (thus \(d=1\) and \(s=70\) ). Figure 3 shows the result. The resulting 171 term sequence enters a loop once 2 and 8 are reached with a maximum value of 98:

1, 70, 7, 77, 84, 6, 90, 96, 86, 82, 68, 50, 8, 58, 66, 24, 90, 4, 94, 98, 92, 90, 82, 72, 54, 26, 80, 6, 86, 92, 78, 70, 48, 8, 56, 64, 20, 84, 4, 88, 92, 80, 72, 52, 24, 76, 0, 76, 76, 52, 28, 80, 8, 88, 96, 84, 80, 64, 44, 8, 52, 60, 2, 62, 64, 26, 90, 6, 96, 2, 98, 0, 98, 98, 96, 94, 90, 84, 74, 58, 32, 90, 22, 2, 24, 26, 50, 76, 26, 2, 28, 30, 58, 88, 46, 34, 80, 4, 84, 88, 72, 60, 32, 92, 24, 6, 30, 36, 66, 2, 68, 70, 38, 8, 46, 54, 0, 54, 54, 8, 62, 70, 32, 2, 34, 36, 70, 6, 76, 82, 58, 40, 98, 38, 36, 74, 0, 74, 74, 48, 22, 70, 92, 62, 54, 6, 60, 66, 26, 92, 8, 0, 8, 8, 6, 4, 0, 4, 4, 8, 2, 0, 2, 2, 4, 6, 0, 6, 6, 2, 8


Figure 3: permalink

Though this sequence of 171 terms oscillates wildly, it still only reaches a maximum value of 98 before eventually looping. With a forbidden digit of 1 (\(d=1\)) and a starting number that is below 100 (\(s<100\)), no sequence member can exceed 100 and so the sequence must eventually loop.

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

Python
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)