Open In App

Closest number to N having the given digit sum

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:

Below is the implementation of the naive approach:




// 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;
}




/*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.




# 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# 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.




  <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:

Below is the implementation of the efficient approach:    




// 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 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




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


Article Tags :