Convert a given integer to another in minimum steps - c++

Given two numbers A and B of equal number of digits. Find the minimum number of steps to convert A to B by increasing or decreasing a single digit in A in every step.
For example: If A = 133 and B = 343, a possible solution is 133 -> 233 -> 333 -> 343. Minimum number of steps required is 3.
I tried a brute force approach. Here is my pseudo code
while(a!=b)
{
if(a<b)
{
find (b-a)
count number of digits in (b-a) keep it as n
add the power(10,n) to a
moves++;
}
else{
find (a-b)
count number of digits in (a-b) keep it as n
subtract the power(10,n) from a
moves++;
}
}
I was not able to get the correct answer on all test cases. Please suggest an efficient way to do this.

The solution to your problem would be
Traverse through a and b digit by digit, add the absolute value of the difference to a variable sum
sum would represent the number of digits needed to be changed
Time complexity O(number of digits)
function solve(a, b){
let sum = 0;
while(a>0 && b>0){
sum += Math.abs((a%10)-(b%10));
a = Math.floor(a/10);
b= Math.floor(b/10);
}
return sum;
}
console.log(solve(133, 343));
console.log(solve(1234, 1221));

Based on ideas from #K. Kirsz comment and #marvel308 answer, you can solve this problem via std::valarray, which is kind of an obscure standard container that does it's job here. You can run it here.
#include <iostream>
#include <valarray>
#include <string>
int solve(int a, int b)
{
std::valarray<char> va(std::to_string(a).data(), std::to_string(a).length());
std::valarray<char> vb(std::to_string(b).data(), std::to_string(b).length());
return (std::abs(va - vb)).sum();
}
int main()
{
int a, b;
std::cin >> a >> b;
std::cout << solve(a, b);
return 0;
}
Of course, the performance might drop here but if you want more readable code, this might be better.

Related

why do we iterate to root(n) to check if n is a perfect number

while checking if a number n is perfect or not why do we check till square root of (n)?
also can some body explain the if conditions in the following loop
for(int i=2;i<sqrt(n);i++)
{
if(n%i==0)
{
if(i==n/i)
{
sum+=i; //Initially ,sum=1
}
else
{
sum+=i+(n/i);
}
}
}
According to number theory, any number has at least 2 divisors (1, the number itself), and if the number A is a divisor of the number B, then the number B / A is also a divisor of the number B. Now consider a pair of numbers X, Y, such that X * Y == B. If X == Y == sqrt(B), then it is obvious that X, Y <= sqrt(B). If we try to increase Y, then we have to reduce X so that their product is still equal to B. So it turns out that among any pair of numbers X, Y, which in the product give B, at least one of the numbers will be <= sqrt(B). Therefore it is enough to find simply all divisors of number B which <= sqrt(B).
As for the loop condition, then sqrt(B) is a divisor of the number B, but we B / sqrt(B) is also a divisor, and it is equal to sqrt(B), and so as not to add this divisor twice, we wrote this if (but you have to understand that it will never be executed, because your loop is up to sqrt(n) exclusively).
It's pretty simple according to number theory:
If N has a factor i, it'll also has a factor n/i (1)
If we know all factors from 1 -> sqrt(n), the rest can be calculated by applying (1)
So that's why you only have to check from 1 -> sqrt(n). However, you code didn't reach the clause i==n/i which is the same as i == sqrt(n), so if N is a perfect square, sqrt(n) won't be calculated.
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int n; cin >> n;
int sum = 1;
for(int i=2;i<sqrt(n);i++)
{
if(n%i==0)
{
if(i==n/i) { sum+=i; }
else { sum+=i+(n/i); }
}
}
cout << sum;
}
Input : 9
Output : 1
As you can see, the factor 3 = sqrt(9) is missed completely. To avoid this, use i <= sqrt(n), or to avoid using sqrt(), use i <= n/i or i*i <= n.
Edit :
As #HansOlsson and #Bathsheba mentioned, there're no odd square which are perfect number (pretty easy to prove, there's even no known odd perfect number), and for even square, there's a proof here. So the sqrt(n) problem could be ignored in this particular case.
However, in other cases when you just need to iterate over the factors some error may occurred. It's better using the right method from the start, than trying to track bugs down afterward when using this for something else.
A related post : Why do we check up to the square root of a prime number to determine if it is prime?
The code uses the trick of finding two factors at once, since if i divides n then n/i divides n as well, and normally adds both of them (else-clause).
However, you are missing the error in the code: it loops while i<sqrt(n) but has code to handle i*i=n (the then-clause - and it should only add i once in that case), which doesn't make sense as both of these cannot be true at the same time.
So the loop should be to <=sqrt(n), even if there are no square perfect numbers. (At least I haven't seen any square perfect numbers, and I wouldn't be surprised if there's a simple proof that they don't exist at all.)

How to get rid of 2 numbers' common divisors

So I have a function that divides a pair of numbers until they no longer have any common divisors:
void simplify(int &x, int &y){
for (int i = 2;;++i){
if (x < i && y < i){
return;
}
while (1){
if (!(x % i) && !(y % i)){
x /= i;
y /= i;
} else {
break;
}
}
}
}
How can I make it more efficient? I know one problem in this solution is that it tests for divisibility with compound numbers, when it wouldn't have any of it's factors by the time it gets to them, so it's just wasted calculations. Can I do this without the program knowing a set of primes beforehand/compute them during the function's runtime?
Use the Euclidean algorithm1:
Let a be the larger of two given positive integers and b be the smaller.
Let r be the remainder of a divided by b.
If r is zero, we are done, and b is the greatest common divisor.
Otherwise, let a take the value of b, let b take the value of r, and go to step 2.
Once you have the greatest common divisor, you can divide the original two numbers by it, which will yield two numbers with the same ratio but without any common factors greater than one.
Citation
1 Euclid, Elements, book VII, propositions 1 and 2, circa 300 BCE.
Notes
Euclid used subtraction, which has been changed here to remainder.
Once this algorithm is working, you might consider the slightly more intricate Binary GCD, which replaces division (which is slow on some processors) with subtraction and bit operations.
Sounds like a job for the C++17 library feature gcd.
#include <numeric>
void simplify(int &x, int &y)
{
const auto d = std::gcd(x, y);
x /= d;
y /= d;
}
Compiler Explorer

Digit manipulation number conversion

I have 4 digit number from 0000 to 1440. I want to generate an equivalent four digit number. That means I can reverse the number from the equivalent number. Basic requirement is the equivalent number must be completely different from the original one. Is there a good equation to do this?
For example, each digit can be replaced by 10 - digit. Thus, 1440 becomes 9660, and 1254 becomes 9756.
Thanks.
You can use a Linear Congruential Generator with a period of 10000. This is a pseudo-random number generator that cycles through each number in the range of 0-9999 once and only once. To generate your number, just take the original number and calculate the next number in the LCG sequence.
An LCG generates random numbers using the following formula:
Xn+1 = ((Xn * a) + c) mod m
To generate 4-digit numbers m should be 10000 (range of 0-9999).
To guarantee no repeats (a "full period") you have to select values for a and c using the following criteria:
c and m are relatively prime
a - 1 is divisible by all prime factors of m
a - 1 is a multiple of 4 if m is a multiple of 4.
The prime factors of 10000 are 2 and 5, and it's also divisible by 4, so any multiple of 20 + 1 will work as a suitable value of a. For c just choose a reasonably large prime number.
e.g: m = 10000, a = 4781, c = 7621
To go the other way, you need to make the function reversible. See this answer for an explanation of the math behind that.
Here's a simple implementation:
#define M (10000)
#define A (4781)
#define C (7621)
int extendedEuclidY(int a, int b);
int extendedEuclidX(int a, int b)
{
return (b==0) ? 1 : extendedEuclidY(b, a-b*(a/b));
}
int extendedEuclidY(int a, int b)
{
return (b==0) ? 0 : extendedEuclidX(b, a-b*(a/b)) - (a/b) * extendedEuclidY(b, a-b*(a/b));
}
int forward(int x)
{
return ((x*A)+C)%M;
}
int backward(int x)
{
return ((extendedEuclidX(A, M)*(x-C)%M)+M)%M;
}
int main()
{
int x;
for(x=0; x<1440; x++)
{
printf("%d <-> %d\n", backward(forward(x)), forward(x));
}
return 0;
}
I've adapted the extendedEuclid functions from the linked answer.
forward(x) finds your equivalent number, backward(x) gets the original back.
This is, perhaps, more of a comment.
I think your question is rather vague, because you don't define "completely different". Typical "easy" ways are something like:
Reverse the number.
Substitute the digits for other digits (an easy way is to increment each digit by 1).
Substitute pairs of digits for other pairs.
And, you can of course combine these.
In your case, you are starting with a range of 1,441 and mapping to a much larger range (10,000). This actually gives you are larger range of possible mappings.
However, the key point is "how different is different"? You should modify your question to explain that point.

Code with prime numbers

I am trying to solve one problem from on-line judging system. I have a solution which works, but not efficient enough. Here is the problem:
Which the least number n can we imagine in product n = a∙b like k ways? Products a∙b and b∙a is one of the way, where all numbers is natural (1≤ k ≤50).
Input One number k.
Output One number n.
My code did not pass four tests. It is too slow for k=31, 37, 47. I have been thinking on this problem 2 days,but no improvement. Here is my code, please share, if you have any ideas.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int prime[10000];
long x,j,i,flag,k,length,p,checker,count,number;
int main()
{
prime[0]=2;
scanf("%ld",&k);
//I find prime numbers between 1 and 1000. 1000 can be changed, just for testing
for (i=3;i<=1000;i=i+2)
{
flag=0;
for (j=2;j<=sqrt(i);j++)
{
if(i%j==0)
{
flag=1;
break;
}
}
if(flag==0)
{
x++;
prime[x]=i;
}
}
length=x;
//this loop is too big I know, again for testing. I suspect, there must be a way to make some changes to this for loop
for (i=1;i<10000000000;i++)
{
number=i;
p=1;
for(x=0;x<=length;x++)
{
if(prime[x]>sqrt(i))
break;
count=0;
while(number%prime[x]==0)
{
number=number/prime[x];
count++;
}
p=p*(count+1);
//I find prime factors of numbers and their powers, then calculate number of divisors
}
//printf("%d\n",p);
//number of ways is just number of divisors/2 or floor (divisors/2)+1
if(p%2==0)
checker=p/2;
else
checker=floor(p/2)+1;
if(checker==k)
{
printf("%ld\n",i);
break;
}
}
return 0;
}
If I understand the problem correctly it's asking you which is the least number n with exactly 2k divisors (should I consider 1 and n?)
in fact if a number has a divisor a, then n / a = b is an integer and n = a* b (counting only one time a and b, so you should divide by two the number of divisors)
edit
Doing that is time consuming indeed. So this is the idea;
for a number n in the form n = p1^(a1)*p2^(a2)...pn^(an) (this is the prime factorization of the number) the number of divisor is (a1 + 1)(a2+1)...(an+1)
Hence, if you want to find a number that has k divisor, factorize k. then assign the biggest factor to the smallest prime; eg if k = 2*5*7, then n should be 2^7*3^5*5^2
I know it is not since i didnt take into account that (a, b) is equal to (b, a) but play around it a little and it should work
example
take k = 37. Then double the number - (to consider the symmetry). You get 74.
Now, if you can imagine n as n = n * 1, then you just need to factor 74 (that is 2 * 37);
then give 36 to 2 and 1 to 3, leading n = 2^(36)*3 = 206158430208
if you can't, then you need to add 1 to the number you got previously (in this case, 74 + 1 = 75 = 25*3); this way you get n = 2^24 * 3^2 = 150994944
If it's none of the above, then I am probably wrong...

Optimization algorithm with numbers

Given a list of numbers in increasing order and a certain sum, I'm trying to implement the optimal way of finding the sum. Using the biggest number first
A sample input would be:
3
1
2
5
11
where the first line the number of numbers we are using and the last line is the desired sum
the output would be:
1 x 1
2 x 5
which equals 11
I'm trying to interpret this https://www.classle.net/book/c-program-making-change-using-greedy-method using stdard input
Here is what i got so far
#include <iostream>
using namespace std;
int main()
{
int sol = 0; int array[]; int m[10];
while (!cin.eof())
{
cin >> array[i]; // add inputs to an array
i++;
}
x = array[0]; // number of
for (int i; i < x ; i++) {
while(sol<array[x+1]){
// try to check all multiplications of the largest number until its over the sum
// save the multiplication number into the m[] before it goes over the sum;
//then do the same with the second highest number and check if they can add up to sum
}
cout << m[//multiplication number] << "x" << array[//correct index]
return 0;
}
if(sol!=array[x+1])
{
cout<<endl<<"Not Possible!";
}
}
Finding it hard to find an efficient way of doing this in terms of trying all possible combinations starting with the biggest number? Any suggestions would be greatly helpful, since i know im clearly off
The problem is a variation of the subset sum problem, which is NP-Hard.
An NP-Hard problem is a problem that (among other things) - there is no known polynomial solution for it, thus the greedy approach of "getting the highest first" fails for it.
However, for this NP-Hard problem, there is a pseudo-polynomial solution using dynamic programming. The problem where you can chose each number more then once is called the con change problem.
This page contains explanation and possible solutions for the problem.