 Open in App
Not now

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

• Last Updated : 23 Jun, 2022

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 ``using` `namespace` `std;` `const` `int` `M = 18;``int` `a, b, dp[M];` `// 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 fib = ``new` `HashSet();`` ` `// 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 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 num = ``new` `Vector();`` ` `    ``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