How to solve timeout in this codes? - algorithm

I need a help. the problem is finding a symmetric numbers when shining in a mirror. (ex. 0, 1, 11, 101, 1521 (o) but 1221 & 1010 is not.)
enter image description here
Two numbers A and B are given with spaces between them.(input)
range is 0<=A, B<=10^18.
output is print symmetric numbers count from A to B.
ex) 0 100 (input)
7(output)
this is my codes in c++, but this codes occurred timeout because of wide number range. how solve this problem?
int main()
{
scanf("%d %d", &n,&m);
for(int i=n;i<=m;i++)
{
char s[19];
n=i;
int len=0;
do{
s[len++]=n%10;
n/=10;
} while(n>0);
len--;
int j = 0;
for(j=0;j<=len/2;j++)
{
if(s[j]==s[len-j] && (s[j]==1 || s[j]==8 || s[j]==0))
continue;
if( (s[j]==2 && s[len-j]==5) || (s[j]==5 && s[len-j]==2))
continue;
break;
}
if(j>len/2)
cnt++;
}
printf("%d\n",cnt);
return 0;
}

You've gone through a very painful process to see which of all the numbers are mirrors. Lukas Barth is on the right track, but it's even faster than that. You don't need to construct the numbers; just count how many there are.
First of all, you don't care at all about the second half of the number; by construction, given the left half, the right half is unique. Thus, all you have to do is to count left halves for each number length. This will solve all counting for powers of 10 that are entirely included in the range.
This makes it much easier. For the the ranges in which you have only part of the numbers (i.e. A and/or B is not a power of 10), you'll have to restrict leading digits on one end of the range or the other.
You're allowed leading zeros. Thus, you have five possibilities for each digit: 0, 1, 8, 2, 5. If you have an odd number of digits, then the middle digit must be its own mirror: 0, 1, 8.
So let's look at an example, 4-digit and 5-digit numbers. For the 4-digit numbers, you need only the first two. You have 5 possibilities for each of those digits. This yields 5*5, or 25 four-digit mirror numbers.
Now extend that for 5-digit numbers. You already know that there are exactly 25 two-digit starts. Add one of your three legal middle digits, and that gives 3*25, or 75 five-digit mirror numbers.
Extending this to the full solution is left as an exercise for the student.

Related

Minimum number of operations to make A and B equal simultaneously

Given two non-negative integers A and B, find the minimum number of operations to make them equal simultaneously. In one operation, you can:
either change A to 2*A
or change B to 2*B
or change both A and B to A-1, B-1
For example: A = 7, B = 25
Sequence of operations would be:
6 24
12 24
24 24
We cannot make them equal in less than 3 operations
I was asked this coding question in a test a week ago. Cannot think of a solution, it is stuck in my head.The input A and B were somewhat over 10^12 so it is clear that I cannot use a loop else it will exceed time limit.
A slow but working solution:
If they are equal, stop.
If one of them is 0, stop with failure (there is no solution if negative numbers are not allowed).
While both are larger than 1, decrease both.
Now the smaller is 1, the other is larger.
While the smaller has a shorter binary representation, double the smaller.
Continue at step 1.
In step 4, the maximum decreases. In step 5, the absolute difference decreases. Thus eventually the algorithm terminates.
This should give the optimal solution. We have to compare a few different ways and take the best solution.
One working solution is to double the smaller number as many times as it stays below the larger number (can be zero times). Then calculate the difference between the double of the (possibly multiple times) doubled smaller number and the larger number. And decrease the numbers as many times. Then double the smaller number one more time. [If the numbers are equal from the beginning, the solution is trivial instead.] This gives an upper bound of the steps.
Now try out the following optimizations:
2a) Choose a number n between 0 and up to the number of steps of the best solution so far.
2b) Choose one number as A and one number as B (two possibilities).
2c) Now count the applied steps of the following procedure.
Double A n times.
Calculate the smallest power of 2 (=m), with which B * 2^m >= A. m should be at least 1.
Calculate the difference of A with the product from step 4 in a mixed base (correct term?) system with each digit having a positional value of 2^(n+1)-1, which is from the least significant right digit to the left: 1, 3, 7, 15, 31, 63, ... From all possible representations the number must have the smallest crosssum, e.g. 100 for 7 is correct, 021 not. Sidenote: For the least checksum there will mostly be digits 0 and 1 and at most one digit 2, no other digits. There will never be a digit 1 right of a 2.)
Represent the number as m digits by filling the left positions with zero. If the number does not fit, go back to step 2 for another selection.
Take the most significant not processed digit from step 6 and do as many decreasing steps.
Double B.
Repeat from 7. with the next digit; if there are no more digits left, the numbers are equal.
If the number of steps is less than the best solution so far, choose this as the proposed solution.
Go back to step 2 for another selection.
After doing all selections from 2 we should have the optimal solution with the minimum number of steps.
The following examples are from an earlier version of the answer, where A is always the larger number and n=0, so we test only one selection.
Example 17 and 65
Power of 2: 2^2=4; 4x17=68
Difference: 68-65=3
3 = 010=10 in base 7/3/1
Start => 17/65
Decrease. Double. => 32/64
Double. => 64/64
Example 18 and 67
Power of 2: 2^2=4; 4x18=72
Difference: 72-67=5
5 = 012=12 in base 7/3/1
Start => 18/67
Decrease. Double. => 34/66
Decrease. Decrease. Double. => 64/64
Example 10 and 137
Power of 2: 2^4=16; 16*10=160
Difference: 160-137=23
23 = 1101 in base 15/7/3/1
Start => 10/137
Decrease. Double. => 18/136
Decrease. Double. => 34/135
Double. => 68/135
Decrease. Double. => 134/134
Here's a breadth-first search that does return the correct answer but may not be an optimal method of finding it. Maybe it can help others detect a pattern.
JavasScript code:
function f(a, b) {
const q = [[a, b, [a, b]]];
while (true){
const [x, y, path] = q.shift();
if (x == y) {
return path;
}
if (x > 0 && y > 0) {
q.push([x-1, y-1, path.concat([x-1, y-1])]);
}
q.push([2*x, y, path.concat([2*x, y])]);
q.push([x, 2*y, path.concat([x, 2*y])]);
}
return [];
}
function showPath(path) {
let out1 = "";
let out2 = "";
for (let i = 0; i < path.length; i += 2) {
const s1 = path[i].toString(2);
const s2 = path[i+1].toString(2);
const len = Math.max(s1.length, s2.length);
out1 += s1.padStart(len, "0");
out2 += s2.padStart(len, "0");
if (i < path.length - 2) {
out1 += " --> ";
out2 += " --> ";
}
}
console.log(out1);
console.log(out2);
}
showPath(f(89, 7));

Check if number is multiple of 5 in most efficient way

Info
Hi everyone
I was searching an efficient way to check if a number is multiple of 5. So I searched on google and found this solution on geeksforgeeks.org.
There were 3 solutions of my problem.
First solution was to subtract 5 until reaching zero,
Second solution was to convert the number to string and check last character to be 5 or 0,
Third solution was by doing some interesting operations on bitwise level.
I'm interested in third solution as I can fully understand the first and the second.
Here's the code from geeksforgeeks.
bool isMultipleof5(int n)
{
// If n is a multiple of 5 then we
// make sure that last digit of n is 0
if ( (n & 1) == 1 )
n <<= 1;
float x = n;
x = ( (int)(x * 0.1) ) * 10;
// If last digit of n is 0 then n
// will be equal to (int)x
if ( (int)x == n )
return true;
return false;
}
I understand only some parts of the logic. I haven't even tested this code. So I need to understand it to use freely.
As said in mentioned article this function is multiplying number by 2 if last bit is set and then checking last bit to be 0 and returns true in that case. But after checking binary representations of numbers I got confused as last bit is 1 in case of any odd number and last bit is 0 in case of any even number. So...
Actual question is
What's the logic of this function?
Any answer is appreciated!
Thanks for all!
The most straightforward way to check if a number is a multiple of 5 is to simply
if (n % 5 == 0) {
// logic...
}
What the bit manipulation code does is:
If the number is odd, multiply it by two. Notice that for multiples of 5, the ones digit will end in either 0 or 5, and doubling the number will make it end in 0.
We create a number x that is set to n, but with a ones digit set to 0. (We do this by multiplying n by 0.1, which removes the ones digit, and then multiply by 10 in order to add a 0, which has a total effect of just changing the ones digit to 0).
We know that originally, if n was a multiple of 5, it would have a ones digit of 0 after step 1. So we check if x is equal to it, and if so, then we can say n was a multiple of 5.

Next Greater Even Number

We have a number N and the problem is to find the smallest even number E such that E > N and digits in N and E are same. Digits in N could be huge.
For example
1 -> 34722641 answer would be 34724126
111 -> no even number is possible just greater then it.
1123 -> output would be 1132
I have done it with brute force by making all the permutations of the digits of the number. I was thinking if a better approach is there for it? A code would be better.
Thanks.
You can use the following strategy in finding the next permutation:
Lets say your number = 12344875
To find the next permutations which is bigger, you start from the right and find the first number is smaller than the previous one.
In this case: number = 12344875, this is 4.
Now you start from the 4 moving right and find the smallest number there.
Which is the 5 -> 875. Now swap those 2 numbers resulting in 12345874.
After the swap sort the numbers after the 5 in ascending order. 12345874 --> 12345784.
This strategy will always lead to next permutations wich is bigger, only this gives both even and uneven numbers.
So for finding the next even permutations, you need to change this slightly.
If in last step you have an even number, permutate that part till its an even number.
Otherwise start again from the right. And find the first even number, which has a larger number to its right side. For example with the number = 123475531.
Now swap with smallest number to its right which is greater than 4.
Resulting in the following 123575431.
From this put the even number 4 at the end and put the numbers between
the swapped numbers in ascending order, 123575314 --> 123513574.
For the case were you have the following number 136531. There is no even number with a greater number to the right. So you look at the next number,
and see if to the right there is a number wich is greater (but not the first even number). Here it is for 136531 --> 136531 so swap those and put the even number at the back and finally put in ascending order. 136531 --> 156331 --> 153316 --> 151336.
There is no solution when the number is in descending order(for example 97654).
While making this explaination I realised that for an even number this gets more convoluted. Ill try to improve the answer later on.
I hope this was useful.
Cheers
Find the rightmost digit, i, that has a higher digit, j, to its right, where j is not the highest even digit to its right, e. Pick the smallest such j, switch i and j, place e as the rightmost digit, and sort (ascending) the digits to the right of where i was (excluding e).
Find the next greater number for a given number. For eg - for 1234, the next greater number is 1243 and for 534976 the next greater is 536479.
The algorithm can be found here. If the last digit is even then you've found the next greater even number.
Otherwise, repeat the above step until we find the even number.ie-find the next greater even
number than this with the now the new input number as the one that
we output in the previous step (even if we didn't find the desired
output(greater even number))
For eg - Input number - 21856521, running the first steps yields - 21861255(odd) so we again run step 1 on 21861255 which yields 21861525(again odd), running again yields 21861552
PS: C++ code:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int main(){
string s;cin>>s;
int n = s.length();
while(true){
int idx = -1;
for(int i=n-2;i>=0;--i){
if(s[i]<s[i+1]){
idx = i;
break;
}
}
if(idx==-1){
cout<<-1<<endl;
break;
}
int swapidx = -1;
for(int i=n-1;i>=idx+1;--i){
if(s[i]>s[idx]){
swapidx = i;
break;
}
}
swap(s[idx],s[swapidx]);
//swapidx will never remain -1 bcz. we will surely find an element greater than s[idx](the right next element to idx is greater than s[idx])
sort(s.begin()+idx+1,s.end());
if((s[n-1]-'0')%2==0){
cout<<s<<endl;
break;
}
}
return 0;
}
def getNextEven(self,x):
s,p,flag,r = [],0,0,int(x)
for i in x:
p +=int(i)
if int(i)%2==0:
flag=1
s.append(i)
if flag==0:
return -1
n,x = len(s),int(x)
while r%2!=0 or r<=x:
l,k = -1,-1
for i in range(n-2,-1,-1):
if s[i]<s[i+1]:
k = i
break
if k==-1:
return -1
for i in range(k+1,n):
if s[k]<s[i]:
l = i
s[k],s[l] = s[l],s[k]
s = s[:k+1]+s[k+1:][::-1]
r = int(''.join(s))
return r

Generate numbers where Each pair of adjacent digits also occurs in the original number

I would like to output all similar numbers of a number, where:
Each pair of adjacent digits also occurs in the original number.
The new numbers has the same number of digits as the original
The order in which the numbers are generated doesn't matter
For example suppose I'm given a number 12314, then I have the pairs 12,23,31,14
I should generate [12314,31231,12312,23123].
If I'm given numbers like 52 or 11111 then I should get only 52/11111 respectively.
I have already written code that generates the pairs [12,23,31,14], and generate all possible permutations of this list of pairs. However, the permutations produce numbers that are longer than the original, and many of these permutations are invalid. For example, when 1214 appears in the permutation, the permutation is not valid since "21" is not in the original number.
I'd like to know how to proceed. It looks very inefficient to filter out the invalid ones from all permutations.
You could use recursion to generate the required numbers.
The idea is to maintain only valid numbers at any stage and to display when the original length and length of your number are equal.
// pairs[i][j] is true if j is immediately after i in the original number
bool pairs[10][10];
// curr_num is a valid number according to the constraint given
// curr_len is the number of digits in curr_num
// length is the number of digits in the number given
void generate(int curr_num, int curr_len, int length){
if(cur_len == length){
display curr_num;
} else {
// extract last digit & check what digits can follow that
int last = curr_num % 10;
for(int i = 0 ; i <= 9 ; i++)
if(pairs[last][i])
generate(curr_num * 10 + i , curr_len + 1, length);
}
}
for(digit in original_number)
generate(digit, 1, length);
You could optimize the code by making pairs an adjacency list than an adjacency matrix.

What's the best way to strip leading / trailing digits from a number?

If I have a number like 12345, and I want an output of 2345, is there a mathematical algorithm that does this? The hack in me wants to convert the number to a string, and substring it. I know this will work, but I'm sure there has to be a better way, and Google is failing me.
Likewise, for 12345, if I want 1234, is there another algorithm that will do that? The best I can come up with is Floor(x / 10^(n)), where x is the input and n is the number of digits to strip, but I feel like there has to be a better way, and I just can't see it.
In the first case, don't you just want
n % 10000
i.e. the modulus wrt. 10000 ?
For your second case, if you're using integer arithmetic, just divide by 10. You might want to do this in a more 'explicit' fashion by modding with 10 to get the last digit, subtract and then divide (think of a shift in base 10).
Yes, the modulus operator (%) which is present in most languages, can return the n last digits:
12345 % 10^4 = 12345 % 10000 = 2345
Integral division (/ in C/C++/Java) can return the first n digits:
12345 / 10^4 = 12345 / 10000 = 1
Python 3.0:
>>> import math
>>> def remove_most_significant_digit(n, base=10):
... return n % (base ** int(math.log(n, base)))
...
>>> def remove_least_significant_digit(n, base=10):
... return int(n // base)
...
>>> remove_most_significant_digit(12345)
2345
>>> remove_least_significant_digit(12345)
1234
Converting to a string, and then using a substring method will ultimately be the fastest and best way, since you can just strip characters instead of doing math.
If you really don't want to do that though, you should use modulus (%), which gives the remainder of a division. 11 % 3 = 2, because 3 can only go into 11 three times (9). The remainder is then 2. 41 % 10 = 1, because 10 can go into 41 four times (40). The remainder is then 1.
For stripping the first digits, all you would have to do is mod the tens value that you want to get rid of. For stripping two digits from 12345, you should modulus by 1000. 1000 goes into 12345 twelve times, then the remainder will be 345, which is your answer. You would just need to find a way to find the tens value of the last digit you were trying to strip. Use x % (10^(n)), where x is input, and n is the lowest digit you want to strip.
For stripping the last digits, your way works just fine. What's easier than a quick formula like that?
I don't think there's any other approach than division for removing trailing numbers. It might be more efficient to do repeated integral division than to cast to a float, perform an exponent, then floor and cast back to an integer, but the basic idea remains the same.
Keep in mind that the operation is nearly identical for any base. To remove one trailing decimal digit, you do / 10. If you had 0b0111 and you wanted to remove one digit, it would have to be /2. Or you could have 0xff / 16 to get 0x0f.
You have to realize that numbers don't have digits, only strings do, and how many (and which) digits they have depends entirely on the base (which numbers don't have either). Internally, computers use what amounts to binary strings. So in general, manipulating base 10 digits requires you to convert the number to a string first - or do calculations that are the same you would do when converting it to a string. However, for your specific task of removing leading and trailing digits, these calculations (modulo and integer division) are very simple and much faster than converting the entire number.
i think that converting to string and then remove the first char wont do the trick.
i believe that the alg for converting to string is doing the div-mod routine, for optimization you might as well do the div-mod alg by yourself and manipulate it to your needs
Here is C++ code ... It's not tested.
int myPow ( int n , int k ){
int ret = 1;
for (int i=0;i<k;++i) ret*=n;
return ret;
}
int countDigits (int n ){
int count = 0;
while ( n )++count, n/=10;
return count;
}
int getLastDigits (int number , int numDigits ){
int tmp = myPow ( 10 , numDigits );
return number % tmp;
}
int getFirstDigits (int number, numDigits ){
int tmp = myPow ( 10, countDigits ( number) - numDigits );
return nuber / tmp;
}

Resources