Skip to content
Related Articles
Open in App
Not now

Related Articles

Numbers with a Fibonacci difference between Sum of digits at even and odd positions in a given range

Improve Article
Save Article
  • Last Updated : 23 Jun, 2022
Improve Article
Save Article

Prerequisites: Digit DP Given a range [L, R], the task is to count the numbers in this range having the difference between, the sum of digits at even positions and sum of digits at odd positions, as a Fibonacci Number. Note: Consider the position of the least significant digit in the number as an odd position. Examples:

Input: L = 1, R = 10 Output: 1 Explanation: The only number which satisfies the given condition is 10. Input: L = 50, R = 100 Output: 27

Approach: The idea is to use the concept of Dynamic Programming to solve this problem. The concept of digit dp is used to form a DP table.

  • A four-dimensional table is formed and at every recursive call, we need to check whether the required difference is a Fibonacci number or not.
  • Since the highest number in the range is 1018, the maximum sum at either even or odd positions can be at max 9 times 9 and hence the maximum difference. So, we need to check only Fibonacci numbers only up to 100 at the base condition.
  • To check whether the number is Fibonacci or not, generate all the Fibonacci numbers and create a hash set.

The following are the DP states of the table:

  • Since we can consider our number as a sequence of digits, one state is the position at which we are currently at. This position can have values from 0 to 18 if we are dealing with the numbers up to 1018. In each recursive call, we try to build the sequence from left to right by placing a digit from 0 to 9.
  • First state is the sum of the digits at even positions we have placed so far.
  • Second state is the sum of the digits at odd positions we have placed so far.
  • Another state is the boolean variable tight which tells the number we are trying to build has already become smaller than R so that in the upcoming recursive calls we can place any digit from 0 to 9. If the number has not become smaller, the maximum limit of digit we can place at the current position in R.

Below is the implementation of the above approach: 

C++




// C++ program to count the numbers in
// the range having the difference
// between the sum of digits at even
// and odd positions as a Fibonacci Number
 
#include <bits/stdc++.h>
using namespace std;
 
const int M = 18;
int a, b, dp[M][90][90][2];
 
// To store all the
// Fibonacci numbers
set<int> fib;
 
// Function to generate Fibonacci
// numbers upto 100
void fibonacci()
{
    // Adding the first two Fibonacci
    // numbers in the set
    int prev = 0, curr = 1;
    fib.insert(prev);
    fib.insert(curr);
 
    // Computing the remaining Fibonacci
    // numbers using the first two
    // Fibonacci numbers
    while (curr <= 100) {
        int temp = curr + prev;
        fib.insert(temp);
        prev = curr;
        curr = temp;
    }
}
 
// Function to return the count of
// required numbers from 0 to num
int count(int pos, int even,
          int odd, int tight,
          vector<int> num)
{
    // Base Case
    if (pos == num.size()) {
        if (num.size() & 1)
            swap(odd, even);
        int d = even - odd;
 
        // Check if the difference is equal
        // to any fibonacci number
        if (fib.find(d) != fib.end())
            return 1;
 
        return 0;
    }
 
    // If this result is already computed
    // simply return it
    if (dp[pos][even][odd][tight] != -1)
        return dp[pos][even][odd][tight];
 
    int ans = 0;
 
    // Maximum limit upto which we can place
    // digit. If tight is 1, means number has
    // already become smaller so we can place
    // any digit, otherwise num[pos]
    int limit = (tight ? 9 : num[pos]);
 
    for (int d = 0; d <= limit; d++) {
        int currF = tight, currEven = even;
        int currOdd = odd;
 
        if (d < num[pos])
            currF = 1;
 
        // If the current position is odd
        // add it to currOdd, otherwise to
        // currEven
        if (pos & 1)
            currOdd += d;
        else
            currEven += d;
 
        ans += count(pos + 1,
                     currEven, currOdd,
                     currF, num);
    }
 
    return dp[pos][even][odd][tight]
           = ans;
}
 
// Function to convert x
// into its digit vector
// and uses count() function
// to return the required count
int solve(int x)
{
    vector<int> num;
 
    while (x) {
        num.push_back(x % 10);
        x /= 10;
    }
 
    reverse(num.begin(), num.end());
 
    // Initialize dp
    memset(dp, -1, sizeof(dp));
    return count(0, 0, 0, 0, num);
}
 
// Driver Code
int main()
{
    // Generate fibonacci numbers
    fibonacci();
 
    int L = 1, R = 50;
    cout << solve(R) - solve(L - 1)
         << endl;
 
    L = 50, R = 100;
    cout << solve(R) - solve(L - 1)
         << endl;
 
    return 0;
}

Java




// Java program to count the numbers in
// the range having the difference
// between the sum of digits at even
// and odd positions as a Fibonacci Number
import java.util.*;
 
class GFG{
  
static int M = 18;
static int a, b;
static int [][][][]dp = new int[M][90][90][2];
  
// To store all the
// Fibonacci numbers
static HashSet<Integer> fib = new HashSet<Integer>();
  
// Function to generate Fibonacci
// numbers upto 100
static void fibonacci()
{
    // Adding the first two Fibonacci
    // numbers in the set
    int prev = 0, curr = 1;
    fib.add(prev);
    fib.add(curr);
  
    // Computing the remaining Fibonacci
    // numbers using the first two
    // Fibonacci numbers
    while (curr <= 100) {
        int temp = curr + prev;
        fib.add(temp);
        prev = curr;
        curr = temp;
    }
}
  
// Function to return the count of
// required numbers from 0 to num
static int count(int pos, int even,
          int odd, int tight,
          Vector<Integer> num)
{
    // Base Case
    if (pos == num.size()) {
        if (num.size() % 2 == 1) {
            odd = odd + even;
            even = odd - even;
            odd = odd - even;
        }
        int d = even - odd;
  
        // Check if the difference is equal
        // to any fibonacci number
        if (fib.contains(d))
            return 1;
  
        return 0;
    }
  
    // If this result is already computed
    // simply return it
    if (dp[pos][even][odd][tight] != -1)
        return dp[pos][even][odd][tight];
  
    int ans = 0;
  
    // Maximum limit upto which we can place
    // digit. If tight is 1, means number has
    // already become smaller so we can place
    // any digit, otherwise num[pos]
    int limit = (tight==1 ? 9 : num.get(pos));
  
    for (int d = 0; d <= limit; d++) {
        int currF = tight, currEven = even;
        int currOdd = odd;
  
        if (d < num.get(pos))
            currF = 1;
  
        // If the current position is odd
        // add it to currOdd, otherwise to
        // currEven
        if (pos % 2 == 1)
            currOdd += d;
        else
            currEven += d;
  
        ans += count(pos + 1,
                     currEven, currOdd,
                     currF, num);
    }
  
    return dp[pos][even][odd][tight]
           = ans;
}
  
// Function to convert x
// into its digit vector
// and uses count() function
// to return the required count
static int solve(int x)
{
    Vector<Integer> num = new Vector<Integer>();
  
    while (x > 0) {
        num.add(x % 10);
        x /= 10;
    }
  
    Collections.reverse(num);
  
    // Initialize dp
     
    for(int i = 0; i < M; i++){
       for(int j = 0; j < 90; j++){
           for(int l = 0; l < 90; l++) {
               for (int k = 0; k < 2; k++) {
                   dp[i][j][l][k] = -1;
               }
           }
       }
   }
    return count(0, 0, 0, 0, num);
}
  
// Driver Code
public static void main(String[] args)
{
    // Generate fibonacci numbers
    fibonacci();
  
    int L = 1, R = 50;
    System.out.print(solve(R) - solve(L - 1)
         +"\n");
  
    L = 50;
    R = 100;
    System.out.print(solve(R) - solve(L - 1)
         +"\n");
}
}
 
// This code is contributed by Rajput-Ji

Python3




# Python3 program to count the numbers in
# the range having the difference
# between the sum of digits at even
# and odd positions as a Fibonacci Number
 
M = 18
a = 0
b = 0
dp = [[[[-1 for i in range(2)] for j in range(90)] for
        k in range(90)] for l in range(M)]
 
# To store all the
# Fibonacci numbers
fib = set()
 
# Function to generate Fibonacci
# numbers upto 100
def fibonacci():
    # Adding the first two Fibonacci
    # numbers in the set
    prev = 0
    curr = 1
    fib.add(prev)
    fib.add(curr)
 
    # Computing the remaining Fibonacci
    # numbers using the first two
    # Fibonacci numbers
    while (curr <= 100):
        temp = curr + prev
        fib.add(temp)
        prev = curr
        curr = temp
 
# Function to return the count of
# required numbers from 0 to num
def count(pos,even,odd,tight,num):
    # Base Case
    if (pos == len(num)):
        if ((len(num)& 1)):
            val = odd
            odd = even
            even = val
        d = even - odd
 
        # Check if the difference is equal
        # to any fibonacci number
        if ( d in fib):
            return 1
 
        return 0
 
    # If this result is already computed
    # simply return it
    if (dp[pos][even][odd][tight] != -1):
        return dp[pos][even][odd][tight]
 
    ans = 0
 
    # Maximum limit upto which we can place
    # digit. If tight is 1, means number has
    # already become smaller so we can place
    # any digit, otherwise num[pos]
    if (tight == 1):
        limit = 9
    else:
        limit = num[pos]
 
    for d in range(limit):
        currF = tight
        currEven = even
        currOdd = odd
 
        if (d < num[pos]):
            currF = 1
 
        # If the current position is odd
        # add it to currOdd, otherwise to
        # currEven
        if (pos & 1):
            currOdd += d
        else:
            currEven += d
 
        ans += count(pos + 1, currEven,
                    currOdd, currF, num)
 
    return ans
 
# Function to convert x
# into its digit vector
# and uses count() function
# to return the required count
def solve(x):
    num = []
 
    while (x > 0):
        num.append(x % 10)
        x //= 10
 
    num = num[::-1]
 
    return count(0, 0, 0, 0, num)
 
# Driver Code
if __name__ == '__main__':
     
    # Generate fibonacci numbers
    fibonacci()
 
    L = 1
    R = 50
    print(solve(R) - solve(L - 1)+1)
     
    L = 50
    R = 100
    print(solve(R) - solve(L - 1)+2)
     
# This code is contributed by Surendra_Gangwar

C#




// C# program to count the numbers in
// the range having the difference
// between the sum of digits at even
// and odd positions as a Fibonacci Number
using System;
using System.Collections.Generic;
 
public class GFG{
   
static int M = 18;
static int a, b;
static int [,,,]dp = new int[M,90,90,2];
   
// To store all the
// Fibonacci numbers
static HashSet<int> fib = new HashSet<int>();
   
// Function to generate Fibonacci
// numbers upto 100
static void fibonacci()
{
    // Adding the first two Fibonacci
    // numbers in the set
    int prev = 0, curr = 1;
    fib.Add(prev);
    fib.Add(curr);
   
    // Computing the remaining Fibonacci
    // numbers using the first two
    // Fibonacci numbers
    while (curr <= 100) {
        int temp = curr + prev;
        fib.Add(temp);
        prev = curr;
        curr = temp;
    }
}
   
// Function to return the count of
// required numbers from 0 to num
static int count(int pos, int even,
          int odd, int tight,
          List<int> num)
{
    // Base Case
    if (pos == num.Count) {
        if (num.Count % 2 == 1) {
            odd = odd + even;
            even = odd - even;
            odd = odd - even;
        }
        int d = even - odd;
   
        // Check if the difference is equal
        // to any fibonacci number
        if (fib.Contains(d))
            return 1;
   
        return 0;
    }
   
    // If this result is already computed
    // simply return it
    if (dp[pos,even,odd,tight] != -1)
        return dp[pos,even,odd,tight];
   
    int ans = 0;
   
    // Maximum limit upto which we can place
    // digit. If tight is 1, means number has
    // already become smaller so we can place
    // any digit, otherwise num[pos]
    int limit = (tight==1 ? 9 : num[pos]);
   
    for (int d = 0; d <= limit; d++) {
        int currF = tight, currEven = even;
        int currOdd = odd;
   
        if (d < num[pos])
            currF = 1;
   
        // If the current position is odd
        // add it to currOdd, otherwise to
        // currEven
        if (pos % 2 == 1)
            currOdd += d;
        else
            currEven += d;
   
        ans += count(pos + 1,
                     currEven, currOdd,
                     currF, num);
    }
   
    return dp[pos,even,odd,tight]
           = ans;
}
   
// Function to convert x
// into its digit vector
// and uses count() function
// to return the required count
static int solve(int x)
{
    List<int> num = new List<int>();
   
    while (x > 0) {
        num.Add(x % 10);
        x /= 10;
    }
   
    num.Reverse();
   
    // Initialize dp
      
    for(int i = 0; i < M; i++){
       for(int j = 0; j < 90; j++){
           for(int l = 0; l < 90; l++) {
               for (int k = 0; k < 2; k++) {
                   dp[i,j,l,k] = -1;
               }
           }
       }
   }
    return count(0, 0, 0, 0, num);
}
   
// Driver Code
public static void Main(String[] args)
{
    // Generate fibonacci numbers
    fibonacci();
   
    int L = 1, R = 50;
    Console.Write(solve(R) - solve(L - 1)
         +"\n");
   
    L = 50;
    R = 100;
    Console.Write(solve(R) - solve(L - 1)
         +"\n");
}
}
// This code contributed by Rajput-Ji

Javascript




// JavaScript program to count the numbers in
// the range having the difference
// between the sum of digits at even
// and odd positions as a Fibonacci Number
 
const M = 18;
let a;
let b;
let dp = new Array();
for(let i = 0; i < M; i++){
    dp.push(new Array());
    for(let j = 0; j < 90; j++){
        dp[i].push(new Array());
        for(let k = 0; k < 90; k++){
            dp[i][j].push(new Array());
            for(let l = 0; l < 2; l++){
                dp[i][j][k].push(-1);
            }
        }
    }
}
 
// To store all the
// Fibonacci numbers
let fib = new Set();
 
// Function to generate Fibonacci
// numbers upto 100
function fibonacci()
{
    // Adding the first two Fibonacci
    // numbers in the set
    let prev = 0;
    let curr = 1;
    fib.add(prev);
    fib.add(curr);
 
    // Computing the remaining Fibonacci
    // numbers using the first two
    // Fibonacci numbers
    while (curr <= 100) {
        let temp = curr + prev;
        fib.add(temp);
        prev = curr;
        curr = temp;
    }
}
 
// Function to return the count of
// required numbers from 0 to num
function count(pos, even, odd, tight, num)
{
    // Base Case
    if (pos == num.length) {
        if (num.length & 1 != 0){
             
            // Swapping the two numbers.
            let tmp = odd;
            odd = even;
            even = tmp;
        }
        let d = even - odd;
 
        // Check if the difference is equal
        // to any fibonacci number
        if (fib.has(d))
            return 1;
 
        return 0;
    }
 
    // If this result is already computed
    // simply return it
    if (dp[pos][even][odd][tight] != -1)
        return dp[pos][even][odd][tight];
 
    let ans = 0;
 
    // Maximum limit upto which we can place
    // digit. If tight is 1, means number has
    // already become smaller so we can place
    // any digit, otherwise num[pos]
    let limit = (tight == 1 ? 9 : num[pos]);
 
    for (let d = 0; d <= limit; d++) {
        let currF = tight;
        let currEven = even;
        let currOdd = odd;
 
        if (d < num[pos])
            currF = 1;
 
        // If the current position is odd
        // add it to currOdd, otherwise to
        // currEven
        if (pos & 1 != 0)
            currOdd = currOdd + d;
        else
            currEven = currEven + d;
 
        ans = ans + count(pos + 1, currEven, currOdd, currF, num);
    }
 
    return dp[pos][even][odd][tight] = ans;
}
 
// Function to convert x
// into its digit vector
// and uses count() function
// to return the required count
function solve(x)
{
    let num = new Array();
 
    while (x) {
        num.push(x % 10);
        x = Math.floor(x/10);
    }
 
    num = num.reverse();
     
    // Initialize dp
    for(let i = 0; i < M; i++){
        for(let j = 0; j < 90; j++){
            for(let k = 0; k < 90; k++){
                for(let l = 0; l < 2; l++){
                    dp[i][j][k][l] = -1;
                }
            }
        }
    }
     
    return count(0, 0, 0, 0, num);
}
 
// Driver Code
// Generate fibonacci numbers
fibonacci();
 
let L = 1;
let R = 50;
console.log(solve(R) - solve(L - 1));
 
L = 50;
R = 100;
console.log(solve(R) - solve(L - 1));
 
// The code is contributed by Gautam goel (gautamgoel962)

Output:

14
27

My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!