Open In App

Closest number to N having the given digit sum

Last Updated : 10 Nov, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given two integers N and D, the task is to find the closest number to N with the sum of digits equal to D.

Examples:

Input: N = 2022, D = 25
Output: 1996
Explanation: First smaller number than 2022 with sum of digits 25 is 1996 
and first greater number than 2022 with sum of digits 25 is 2599. 
But 1996 is closer to 2022.

Input: N = 87220000221835856, D = 102
Output: 87219999999993000

Naive Approach:

Iterate through numbers smaller and greater than the given number and check if the sum of digits is equal to the given sum.  

Follow the steps to implement the naive approach:

  • Initialize num1 = num2 = N.
  • Decrement num1 and increment num2 at each iteration until one of them has the sum of digits equal to D and return that number.

Below is the implementation of the naive approach:

C++




// C++ program to implement Naive Approach
#include <bits/stdc++.h>
using namespace std;
 
int sum_current(ulong n)
{
    int sum = 0;
    while (n > 0) {
        sum = sum + n % 10;
        n /= 10;
    }
    return sum;
}
 
ulong closest_number(ulong N, int D)
{
    ulong n1 = N, n2 = N;
    while (true) {
        if (sum_current(n1) == D)
            return n1;
        n1--;
        if (sum_current(n2) == D)
            return n2;
        n2++;
    }
}
 
// Driver code
int main()
{
    ulong N = 2022;
    int D = 25;
    cout << closest_number(N, D) << endl;
    return 0;
}


Java




/*package whatever //do not write package name here */
import java.io.*;
 
class GFG
{
   
  // Java program to implement Naive Approach
  static long sum_current(long n)
  {
    long sum = 0;
    while (n > 0) {
      sum = sum + n % 10;
      n /= 10;
    }
    return sum;
  }
 
  static long closest_number(long N, int D)
  {
    long n1 = N, n2 = N;
    while (true) {
      if (sum_current(n1) == D)
        return n1;
      n1--;
      if (sum_current(n2) == D)
        return n2;
      n2++;
    }
  }
 
  // Driver code
  public static void main (String[] args)
  {
    long N = 2022;
    int D = 25;
    System.out.println(closest_number(N, D));
  }
}
 
// This code is contributed by satwik4409.


Python3




# Python code to implement the approach
 
def sum_current(n) :
     
    sum = 0
    while (n > 0) :
        sum = sum + n % 10
        n //= 10
     
    return sum
  
def closest_number(N, D) :
 
    n1 = N
    n2 = N
    while (True) :
        if (sum_current(n1) == D) :
            return n1
        n1 -= 1
        if (sum_current(n2) == D) :
            return n2
        n2 += 1
 
# Driver code
N = 2022
D = 25
print(closest_number(N, D))
 
# This code is contributed by code_hunt.


C#




// C# program to implement Naive Approach
using System;
public class GFG{
 
  static long sum_current(long n)
  {
    long sum = 0;
    while (n > 0) {
      sum = sum + n % 10;
      n /= 10;
    }
    return sum;
  }
 
  static long closest_number(long N, int D)
  {
    long n1 = N, n2 = N;
    while (true) {
      if (sum_current(n1) == D)
        return n1;
      n1--;
      if (sum_current(n2) == D)
        return n2;
      n2++;
    }
  }
 
  // Driver code
  static public void Main (){
    long N = 2022;
    int D = 25;
    Console.Write(closest_number(N, D));
  }
}
 
// This code is contributed by hrithikgarg03188.


Javascript




  <script>
// Javascript program to implement Naive Approach
function sum_current( n)
{
    let sum = 0;
    while (n > 0) {
        sum = sum + n % 10;
        n /= 10;
    }
    return sum;
}
 
function closest_number( N, D)
{
    let n1 = N, n2 = N;
    while (true) {
        if (sum_current(n1) == D)
            return n1;
        n1--;
        if (sum_current(n2) == D)
            return n2;
        n2++;
    }
}
 
// Driver code
    let  N = 2022;
    let D = 25;
    document.write(closest_number(N, D));
     
    // This code is contributed by satwik4409.
    </script>


Output

1996

Time Complexity: O(d*N) where d is the number of digits
Auxiliary Space: O(1)

Efficient Approach:

Manipulate digits and generate two numbers that have sum of digits D which are closest smaller and bigger than N, and return the one which is closest to N.

Follow the steps to solve this problem efficiently:

  • Calculate the current sum of digits of N and store it in a variable cur_sum.
  • If D = cur_sum, return N.
  • If D < cur_sum:
    • Starting from the last digit, make digits of N = 0 until cur_sum – D in less than 10.
    • To generate a number with the sum of digits = D and is just smaller than N, set the last digit that is not 0 to make cur_sum = D.
    • To generate a number with the sum of digits = D and is just greater than N, increment the last digit that is not 0 and then:
      • starting from the last digit set digits = 9 until cur_sum – D is less than 10.
      • set the current digit that is not 9 to make cur_sum = D.
    • Among the numbers obtained above, return the one closer to N.
  • If D > cur_sum:
    • To generate a number with the sum of digits = D and is just greater than N:
      • starting from the last digit set digits equal to 9 until D – cur_sum is less than 10.
      • set the current digit that is not set to 9 to make cur_sum = D.
    • To generate a number with the sum of digits = D and is just smaller than N:
      • starting from the last digit set digits equal to 9 cur_sum > D.
      • decrease by 1 the last digit that is not set to 9.
      • starting from last digit, set digits = 0, until cur_sum – D is less than 10.
      • set the current digit to make cur_sum = D.
    • Among the numbers obtained above, return the one closer to N.

Below is the implementation of the efficient approach:    

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to convert vector to integer
ulong toInt(const vector<int>& digits)
{
    ulong n = 0;
    for (int i = digits.size() - 1; i >= 0; i--)
        n = n * 10 + digits[i];
    return n;
}
 
// Function to find the number closest to N
// with sum of digits D
ulong closest_number(ulong N, int D)
{
    vector<int> digits;
    ulong temp_num = N;
 
    int cur_sum = 0, temp_cur_sum, index;
    while (temp_num > 0) {
        int digit = temp_num % 10;
        digits.push_back(digit);
        cur_sum += digit;
        temp_num /= 10;
    }
    temp_cur_sum = cur_sum;
    if (D == cur_sum)
        return N;
 
    else if (D < cur_sum) {
        auto n1 = digits;
        for (index = 0; cur_sum - D >= n1[index]; index++) {
            cur_sum -= n1[index];
            n1[index] = 0;
        }
        n1[index] -= (cur_sum - D);
        auto n2 = digits;
        cur_sum = temp_cur_sum;
        for (index = 0; cur_sum >= D; index++) {
            cur_sum -= n2[index];
            n2[index] = 0;
        }
        if (index < n2.size())
            ++n2[index];
        else
            n2.push_back(1);
        ++cur_sum;
        for (int i = index; i < n2.size() && n2[i] > 9;
             i++) {
            n2[i] = 0;
            if (i == n2.size() - 1)
                n2.push_back(1);
            else
                ++n2[i + 1];
            cur_sum -= 9;
        }
        for (index = 0; D - cur_sum + n2[index] >= 10;
             index++) {
            cur_sum += (9 - n2[index]);
            n2[index] = 9;
        }
        n2[index] += D - cur_sum;
        if (N - toInt(n1) <= toInt(n2) - N)
            return toInt(n1);
        else
            return toInt(n2);
    }
    else {
        auto n1 = digits;
        for (index = 0; D - cur_sum + n1[index] >= 10;
             index++) {
            if (index == n1.size())
                n1.push_back(0);
            cur_sum += (9 - n1[index]);
            n1[index] = 9;
        }
        if (index == n1.size())
            n1.push_back(0);
        n1[index] += D - cur_sum;
        auto n2 = digits;
        int cur_sum = temp_cur_sum;
        for (index = 0; cur_sum < D && index < n2.size();
             index++) {
            cur_sum += (9 - n2[index]);
            n2[index] = 9;
        }
        --n2[index];
        --cur_sum;
        if (cur_sum < D)
            n2.clear();
        else {
            for (int i = index; i < n2.size() && n2[i] < 0;
                 i++) {
                n2[i] = 9;
                if (i == n2.size() - 1)
                    n2.pop_back();
                else
                    --n2[i + 1];
                cur_sum += 9;
            }
            for (index = 0; cur_sum - D >= n2[index];
                 index++) {
                cur_sum -= n2[index];
                n2[index] = 0;
            }
            n2[index] = 9 - (cur_sum - D);
        }
        if (n2.size() > 0 && N - toInt(n2) <= toInt(n1) - N)
            return toInt(n2);
        else
            return toInt(n1);
    }
}
 
// Driver code
int main()
{
    ulong N = 87220000221835856;
    int D = 102;
 
    // Function call
    cout << closest_number(N, D);
    return 0;
}


Java




// Java Code for above approach
import java.util.*;
 
public class Solution
{
 
  // Function to convert vector to integer
  static long toInt(ArrayList<Integer> digits)
  {
    long n = 0;
    for (int i = digits.size() - 1; i >= 0; i--)
      n = n * 10 + digits.get(i);
    return n;
  }
 
  // Function to find the number closest to N
  // with sum of digits D
  static long closest_number(long N, int D)
  {
    ArrayList<Integer> digits = new ArrayList<>();
    long temp_num = N;
 
    int cur_sum = 0, temp_cur_sum, index;
    while (temp_num > 0) {
      int digit = (int)(temp_num % 10);
      digits.add(digit);
      cur_sum += digit;
      temp_num /= 10;
    }
    temp_cur_sum = cur_sum;
    if (D == cur_sum)
      return N;
 
    else if (D < cur_sum) {
      ArrayList<Integer> n1 = new ArrayList<>(digits);
      for (index = 0; cur_sum - D >= n1.get(index);
           index++) {
        cur_sum -= n1.get(index);
        n1.set(index, 0);
      }
 
      n1.set(index, n1.get(index) - (cur_sum - D));
      ArrayList<Integer> n2 = new ArrayList<>(digits);
      cur_sum = temp_cur_sum;
      for (index = 0; cur_sum >= D; index++) {
        cur_sum -= n2.get(index);
        n2.set(index, 0);
      }
      if (index < n2.size())
        n2.set(index, n2.get(index) + 1);
      else
        n2.add(1);
      ++cur_sum;
      for (int i = index;
           i < n2.size() && n2.get(i) > 9; i++) {
        n2.set(i, 0);
        if (i == n2.size() - 1)
          n2.add(1);
        else
          n2.set(i + 1, n2.get(i + 1) + 1);
        cur_sum -= 9;
      }
      for (index = 0;
           D - cur_sum + n2.get(index) >= 10;
           index++) {
        cur_sum += (9 - n2.get(index));
        n2.set(index, 9);
      }
 
      n2.set(index, n2.get(index + D - cur_sum));
      if (N - toInt(n1) <= toInt(n2) - N)
        return toInt(n1);
      else
        return toInt(n2);
    }
    else {
      ArrayList<Integer> n1 = new ArrayList<>(digits);
      for (index = 0;
           D - cur_sum + n1.get(index) >= 10;
           index++) {
        if (index == n1.size())
          n1.add(0);
        cur_sum += (9 - n1.get(index));
        n1.set(index, 9);
      }
      if (index == n1.size())
        n1.add(0);
      n1.set(index, n1.get(index) + D - cur_sum);
 
      ArrayList<Integer> n2 = new ArrayList<>(digits);
      cur_sum = temp_cur_sum;
      for (index = 0;
           cur_sum < D && index < n2.size();
           index++) {
        cur_sum += (9 - n2.get(index));
 
        n2.set(index, 9);
      }
 
      n2.set(index, n2.get(index) - 1);
      --cur_sum;
      if (cur_sum < D)
        n2.clear();
      else {
        for (int i = index;
             i < n2.size() && n2.get(i) < 0; i++) {
          n2.set(i, 9);
          if (i == n2.size() - 1)
            n2.remove(n2.size() - 1);
          else
            n2.set(i + 1, n2.get(i + 1) - 1);
          cur_sum += 9;
        }
        for (index = 0;
             cur_sum - D >= n2.get(index);
             index++) {
          cur_sum -= n2.get(index);
          n2.set(index, 0);
        }
        n2.set(index, 9 - (cur_sum - D));
      }
      if (n2.size() > 0
          && N - toInt(n2) <= toInt(n1) - N)
        return toInt(n2);
      else
        return toInt(n1);
    }
  }
 
  // Driver code
  public static void main(String[] args)
  {
    long N = 87220000221835856L;
    int D = 102;
 
    // Function call
    System.out.println(closest_number(N, D));
  }
}
 
// This code is contributed by karandeep1234


Python3




# Python program for the above approach
# Function to convert vector to integer
def toInt(digits):
  n = 0
  for i in range(len(digits)-1,-1 ,-1):
    n = n * 10 + digits[i]
  return n
# Function to find the number closest to N
# with sum of digits D
def closest_number(N, D):
  digits = []
  temp_num = N
  cur_sum = 0
  while (temp_num > 0):
    digit = temp_num % 10
    digits.append(digit)
    cur_sum += digit
    temp_num //= 10
  temp_cur_sum = cur_sum
  if (D == cur_sum):
    return N
 
  elif (D < cur_sum):
    n1 = digits.copy()
    index=0
    while(cur_sum - D >= n1[index]):
      cur_sum -= n1[index]
      n1[index] = 0
      index += 1
    n1[index] = n1[index]- (cur_sum - D)
    n2 = digits
    cur_sum = temp_cur_sum
    index=0
    while(cur_sum >= D):
      cur_sum = cur_sum - n2[index]
      n2[index] = 0
      index = index + 1
    if (index < len(n2)):
      n2[index] += 1
    else:
      n2.append(1)
    cur_sum += 1
    i=index
    while(i < len(n2) and n2[i] > 9):
      n2[i] = 0
      i+=1
      if (i == len(n2)- 1):
        n2.append(1)
      else:
        n2[i + 1] += 1
      cur_sum -= 9
    index=0
    while(D - cur_sum + n2[index] >= 10):
      cur_sum += (9 - n2[index])
      n2[index] = 9
      index += 1
    n2[index] += D - cur_sum
    if (N - toInt(n1) <= toInt(n2) - N):
      return toInt(n1)
    else:
      return toInt(n2)
  else:
    n1 = digits.copy()
    index = 0
    while(D - cur_sum + n1[index] >= 10):
      if (index == len(n1)):
        n1.append(0)
      cur_sum += (9 - n1[index])
      n1[index] = 9
      index += 1
    if (index == len(n1)):
      n1.append(0)
    n1[index] += D - cur_sum
    n2 = digits.copy()
    cur_sum = temp_cur_sum
    index = 0
    while(cur_sum < D and index < len(n2)):
      cur_sum += (9 - n2[index])
      n2[index] = 9
      index += 1
    n2[index] -= 1
    cur_sum -= 1
    if (cur_sum < D):
      n2.clear()
    else:
      i = index
      while(i < len(n2) and n2[i] < 0):
        n2[i] = 9
        if (i == len(n2) - 1):
          n2.pop()
          i += 1
        else:
          n2[i + 1] -= 1
          cur_sum += 9
          i += 1
      index = 0
      while(cur_sum - D >= n2[index]):
        cur_sum -= n2[index]
        n2[index] = 0
        index += 1
      n2[index] = 9 - (cur_sum - D)
    if (len(n2) > 0 and N - toInt(n2) <= toInt(n1) - N):
      return toInt(n2)
    else:
      return toInt(n1)
       
# Driver code
N = 87220000221835856
D = 102
 
# Function call
print(closest_number(N, D))
 
# This code is contributed by Atul_kumar_shrivastava.


C#




// C# Code for above approach
using System;
using System.Collections.Generic;
 
public class Solution {
 
  // Function to convert vector to integer
  static long toInt(List<int> digits)
  {
    long n = 0;
    for (int i = digits.Count - 1; i >= 0; i--)
      n = n * 10 + digits[i];
    return n;
  }
 
  // Function to find the number closest to N
  // with sum of digits D
  static long closest_number(long N, int D)
  {
    List<int> digits = new List<int>();
    long temp_num = N;
 
    int cur_sum = 0, temp_cur_sum, index;
    while (temp_num > 0) {
      int digit = (int)(temp_num % 10);
      digits.Add(digit);
      cur_sum += digit;
      temp_num /= 10;
    }
    temp_cur_sum = cur_sum;
    if (D == cur_sum)
      return N;
 
    else if (D < cur_sum) {
      List<int> n1 = new List<int>(digits);
      for (index = 0; cur_sum - D >= n1[index];
           index++) {
        cur_sum -= n1[index];
        n1[index] = 0;
      }
 
      n1[index] = n1[index] - (cur_sum - D);
      List<int> n2 = new List<int>(digits);
      cur_sum = temp_cur_sum;
      for (index = 0; cur_sum >= D; index++) {
        cur_sum -= n2[index];
        n2[index] = 0;
      }
      if (index < n2.Count)
        n2[index] = n2[index] + 1;
      else
        n2.Add(1);
      ++cur_sum;
      for (int i = index; i < n2.Count && n2[i] > 9;
           i++) {
        n2[i] = 0;
        if (i == n2.Count - 1)
          n2.Add(1);
        else
          n2[i + 1] = n2[i + 1] + 1;
        cur_sum -= 9;
      }
      for (index = 0; D - cur_sum + n2[index] >= 10;
           index++) {
        cur_sum += (9 - n2[index]);
        n2[index] = 9;
      }
 
      n2[index] = n2[index + D - cur_sum];
      if (N - toInt(n1) <= toInt(n2) - N)
        return toInt(n1);
      else
        return toInt(n2);
    }
    else {
      List<int> n1 = new List<int>(digits);
      for (index = 0; D - cur_sum + n1[index] >= 10;
           index++) {
        if (index == n1.Count)
          n1.Add(0);
        cur_sum += (9 - n1[index]);
        n1[index] = 9;
      }
      if (index == n1.Count)
        n1.Add(0);
      n1[index] = n1[index] + D - cur_sum;
 
      List<int> n2 = new List<int>(digits);
      cur_sum = temp_cur_sum;
      for (index = 0; cur_sum < D && index < n2.Count;
           index++) {
        cur_sum += (9 - n2[index]);
 
        n2[index] = 9;
      }
 
      n2[index] = n2[index] - 1;
      --cur_sum;
      if (cur_sum < D)
        n2.Clear();
      else {
        for (int i = index;
             i < n2.Count && n2[i] < 0; i++) {
          n2[i] = 9;
          if (i == n2.Count - 1)
            n2.Remove(n2.Count - 1);
          else
            n2[i + 1] = n2[i + 1] - 1;
          cur_sum += 9;
        }
        for (index = 0; cur_sum - D >= n2[index];
             index++) {
          cur_sum -= n2[index];
          n2[index] = 0;
        }
        n2[index] = 9 - (cur_sum - D);
      }
      if (n2.Count > 0
          && N - toInt(n2) <= toInt(n1) - N)
        return toInt(n2);
      else
        return toInt(n1);
    }
  }
 
  // Driver code
  public static void Main(string[] args)
  {
    long N = 87220000221835856L;
    int D = 102;
 
    // Function call
    Console.WriteLine(closest_number(N, D));
  }
}
 
// This code is contributed by karandeep1234


Javascript




// javascript program for the above approach
 
// Function to convert vector to integer
 
 
function toInt(digits = [])
{
    let n = 0;
    for (let i = digits.length - 1; i >= 0; i--)
        n = n * 10 + digits[i];
    return n;
}
 
// Function to find the number closest to N
// with sum of digits D
function closest_number(N,D)
{
    let digits= [];
    let temp_num = N;
 
    let cur_sum = 0, temp_cur_sum, index;
    while (temp_num > 0) {
        let digit = temp_num % 10;
        digits.push((digit));
        cur_sum += digit;
        temp_num = Math.floor(temp_num / 10);
    }
    temp_cur_sum = cur_sum;
    if (D == cur_sum)
        return N;
 
    else if (D < cur_sum) {
        /////////////
        let n1 = digits.slice();
        for (let index = 0; cur_sum - D >= n1[index]; index++) {
            cur_sum -= n1[index];
            n1[index] = 0;
        }
        n1[index] -= (cur_sum - D);
        ///////////
        let n2 = digits.slice();
        cur_sum = temp_cur_sum;
        for (let index = 0; cur_sum >= D; index++) {
            cur_sum -= n2[index];
            n2[index] = 0;
        }
        if (index < n2.length)
            ++n2[index];
        else
            n2.push(1);
        ++cur_sum;
        for (let i = index; i < n2.length && n2[i] > 9;
             i++) {
            n2[i] = 0;
            if (i == n2.length - 1)
                n2.push(1);
            else
                ++n2[i + 1];
            cur_sum -= 9;
        }
        for (index = 0; D - cur_sum + n2[index] >= 10;
             index++) {
            cur_sum += (9 - n2[index]);
            n2[index] = 9;
        }
        n2[index] += D - cur_sum;
        if (N - toInt(n1) <= toInt(n2) - N)
            return toInt(n1);
        else
            return toInt(n2);
    }
    else {
        ////////////////////
        let n1 = digits.slice();
        for (index = 0; D - cur_sum + n1[index] >= 10;
             index++) {
            if (index == n1.length)
                n1.push(0);
            cur_sum += (9 - n1[index]);
            n1[index] = 9;
        }
        if (index == n1.length)
            n1.push(0);
        n1[index] += D - cur_sum;
        let n2 = digits.slice();
          cur_sum = temp_cur_sum;
        for (index = 0; cur_sum < D && index < n2.length;
             index++) {
            cur_sum += (9 - n2[index]);
            n2[index] = 9;
        }
        --n2[index];
        --cur_sum;
        if (cur_sum < D)
            n2.clear;
        else {
            for (let i = index; i < n2.length && n2[i] < 0;
                 i++) {
                n2[i] = 9;
                if (i == n2.length - 1)
                    n2.pop();
                else
                    --n2[i + 1];
                cur_sum += 9;
            }
            for (index = 0; cur_sum - D >= n2[index];
                 index++) {
                cur_sum -= n2[index];
                n2[index] = 0;
            }
            n2[index] = 9 - (cur_sum - D);
        }
        if (n2.length > 0 && N - toInt(n2) <= toInt(n1) - N)
            return toInt(n2);
        else
            return toInt(n1);
    }
}
 
    let N = 87220000221835856;
    let D = 102;
 
    // Function call
    console.log(closest_number(N, D));
 
// This code is contributed by ksam24000.


Output

87219999999993000

Time Complexity: O(d) where d is the number of digits
Auxiliary Space: O(d)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads