Cannot understand an answer to an algorithm - algorithm

I was doing this question today.
Basically, question asks for the largest 'Decent' Number having N digits where 'Decent' number is:
Only 3 and 5 as its digits.
Number of times 3 appears is divisible by 5.
Number of times 5 appears is divisible by 3.
Input Format
The 1st line will contain an integer T, the number of test cases,
followed by T lines, each line containing an integer N i.e. the number
of digits in the number
Output Format
Largest Decent number having N digits. If no such number exists, tell
Sherlock that he is wrong and print '-1'
Sample Input
4
1
3
5
11
Sample Output
-1
555
33333
55555533333
Explanation
For N=1 , there is no such number. For N=3, 555 is only possible
number. For N=5, 33333 is only possible number. For N=11 , 55555533333
and all of permutations of digits are valid numbers, among them, the
given number is the largest one.
I've solved it using normal method but saw this answer:
t = int(raw_input())
for _ in range(t):
n = int(raw_input())
c3 = 5*(2*n%3)
if c3 > n:
print -1
else:
print '5' * (n-c3) + '3'*c3
Can anyone explain the method please? Especially the line 'c3 = 5*(2*n%3)', thanks

We are looking for integer solutions of n = 5*x + 3*y where 5*x is the number of 3s and 3*y is the number of 5s. Both x and y must be >= 0 and x should be as small as possible since we can build larger numbers if we have more 5s.
Transforming this gives y = (n-5*x)/3. In order for y to be an integer n-5*x must be a multiple of 3 so we can calculate modulo 3 (I write == for is congruent modulo 3 from now on).
n-5*x == 0
n == 5*x == 2*x (because 5 == 2)
multiplying both sides by 2 gives
2*n == 4*x == x (because 4 == 1)
Since we want x small we take x = 2 * n % 3 and y = (n-5*x)/3
There is no solution if y < 0.

Related

Generate a random number which is far enough from another number

Let x, range, d be integers. We'd like to generate a number y, such that
1 <= y <= range
abs(x-y) >= d
One idea I came up with is to generate some smaller range and then make some adjustments to handle the numbers which too close to x. But that's really tedious.
Is there any better way to do it?
Here is a Python function that you should be able to adapt to the language of your choice:
import random
def distantRand(a,b,x,d):
#returns a random integer in range a ... b
#which is greater than or equal to d units from x
lb = max(a,x-d+1)
ub = min(b,x+d-1)
k = ub-lb+1 #number of numbers ruled out
if b-k < a:
return None
else:
y = random.randint(a,b-k)
if y > x - d:
y = y + k
return y
For example, distantRand(1,10,5,3) should return a number in the range 1 to 10 which is at least units away from 5. This rules out 3,4,5,6,7 as return values, leaving 10-5 = 5 valid numbers. The function picks one such in the range 1 to 5. If the number chosen is >2, 5 is added to it to make it a number which is >7 (but still <= 10). For example:
>>> for i in range(20):
print(distantRand(1,10,5,3))
1
1
1
8
2
9
10
8
1
10
10
2
8
10
8
8
8
2
1
2
I have done it like this in Python.
import random
range=100
d=20
x=115
while(True):
y=random.randint(1,range)
if abs(x-y)>=d:
print abs(x-y)
print y
break
And here it is as a def
import random
r=100
d=20
x=115
def yourandom (x,d,r):
while(True):
y=random.randint(1,r)
if abs(x-y)>=d:
print "abs(x-y)=",abs(x-y)
print "y=",y
break
yourandom(x,d,r)

How to find if the number is a multiple of 7 efficiently?

There are multiple ways to find out the same and I tried using bitwise operation as -
if(((n<<3) - n)%7 == 0 ) {
print "divide by 7";
}
Is there any other more efficient way?
As we can find if number is multiple of 3 using below algorithm -
If difference between count of odd set bits (Bits set at odd positions) and even set bits is multiple of 3 then so is the number.
Can we generalize the above algorithm for other numbers too?
So if your number is representable by a hardware-supported integer, and the hardware has a division or modulo operations, you should just use those. It is simpler, and probably faster than anything you will write. To even compete with the hardware, you must use an assembler and use other faster instructions better than the hardware manufacturers did, and without the advantage of undocumented tricks they could use but you can not.
Where this question becomes interesting is where arbitrarily large integers are involved. Modulo has some tricks for that. For instance, I can tell you that 100000000010000010000 is divisible by 3, even though my brain is a horribly slow math processor compared to a computer, because of these properties of the % modulo operator:
(a+b+c) % d = ( (a%d) + (b%d) + (c%d) ) %d
(n*a) % d = ( (a%d) + (a%d) + (a%d) +... (n times) ) %d = (n*(a%d)) %d
Now note that:
10 % 3 = 1
100 % 3 = (10 * (10%3)) % 3 = 10%3 = 1
1000 % 3 = (10 * (100%3)) %3 = 1
etc...
So that to tell if a base-10 number is divisible by 3, we simply sum the digits and see if the sum is divisible by 3
Now using the same trick with a large binary number expressed in octal or base-8 (also pointed out by #hropyatr above in comments), and using divisibility by 7, we have the special case:
8 % 7 = 1
and from that we can deduce that:
(8**N) % 7 = (8 * (8 * ( ... *( 8 * (8%7) % 7 ) % 7 ) ... %7 = 1
so that to "quickly" test divisibility by 7 of an arbitrarily large octal number, all we need to do is add up its octal base-8 digits and try dividing that by 7.
Finally, the bad news.
The code posted:
if ( (n<<3 - n) % 7 ==0 ) ... is not a good test for divisibility by 7.
because it is always yields true for any n (as pointed out by #Johnathan Leffler)
n<<3 is multiplication by 8, and will equal 8n
So for instance 6 is not divisible by 7,
but 6<<3 = 48 and 48 - 6 = 42, which is divisible by 7.
If you meant right shift if ( (n>>3 - n ) % 7 == 0 ) that doesn't work either. Test it with 49, 49//8 is 6, 6-49 is -43 and although 49 is divisible by 7, -43 is not.
The simplest test, if (n % 7 ) == 0 is your best shot until n overflows hardware, and at that point you can find a routine to represent n in octal, and sum the octal digits modulo 7.
I think if(n%7 == 0) is more efficient way to check divisibility by 7.
But if you are dealing with large numbers and can't directly do modulus operation then this might help:
A number of the form 10x + y is divisible by 7 if and only if x − 2y is divisible by 7. In other words, subtract twice the last digit from the number formed by the remaining digits. Continue to do this until a number known to be divisible by 7 is obtained. The original number is divisible by 7 if and only if the number obtained using this procedure is divisible by 7.
For example, the number 371: 37 − (2×1) = 37 − 2 = 35; 3 − (2 × 5) = 3 − 10 = −7; thus, since −7is divisible by 7, 371 is divisible by 7.
Another method is multiplication by 3. A number of the form 10x + y has the same remainder when divided by 7 as 3x + y. One must multiply the leftmost digit of the original number by 3, add the next digit, take the remainder when divided by 7, and continue from the beginning: multiply by 3, add the next digit, etc.
For example, the number 371: 3×3 + 7 = 16 remainder 2, and 2×3 + 1 = 7.
This method can be used to find the remainder of division by 7.
P.S: reference

the number of trailing zeros in a factorial of a given number - Ruby

Having a little trouble trying calculate the number of trailing zeros in a factorial of a given number. This is one of the challenges from Codewars- can't get mine to pass.
zeros(12) = 2 #=> 1 * 2 * 3 .. 12 = 479001600
I think I'm on the wrong path here and there is probably a more elegant ruby way. This is what I have down so far.
def zeros(n)
x = (1..n).reduce(:*).to_s.scan(/[^0]/)
return 0 if x == []
return x[-1].length if x != []
end
This is more of a math question. And you're right, you are off on a wrong path. (I mean the path you are on is going to lead to a very inefficient solution)
Try to reduce the problem mathematically first. (BTW you are shooting for a log N order algorithm.)
In my answer I will try to skip a few steps, because it seems like a homework question.
The number of trailing zeros is going to be equal to the total power of 5s in the multiplication of the series.
the numbers between 1 and n will have n/5, n/25, n/125 numbers which are multiples of 5s, 25s, 125s respectively... and so on.
Try to take these hints and come up with an algorithm to count how many powers of 10 will be crammed in to that factorial.
Spoilers Ahead
I've decided to explain in detail below so if you want to try and solve it yourself then stop reading, try to think about it and then come back here.
Here is a step by step reduction of the problem
1.
The number of trailing zeros in a number is equivalent to the power of 10 in the factor of that number
e.g.
40 = 4 * 10^1 and it has 1 trailing zero
12 = 3 * 4 * 10^0 so it has 0 trailing zeros
1500 = 3 * 5 * 10^2 so it has 2 trailing zeros
2.
The number power of 10 in the factors is the same as the minimum of the power of 2 and power of 5 in the factors
e.g.
50 = 2^1 * 5^2 so the minimum power is 1
300 = 3^1 * 2^2 * 5^2 so the minimum is 2 (we are only concerned with the minimum of the powers of 2 and 5, so ignore powers of 3 and all other prime factors)
3.
In any factorial there will be many more powers of 2 than the powers of 5
e.g.
5! = 2^3 * 3^1 * 5^1
10! = 2^8 * 3^4 * 5^2 * 7^1
As you can see the power of 2 is going to start increasing much faster so the power of 5 will be the minimum of the two.
Hence all we need to do is count the power of 5 in the factorial.
4.
Now lets focus on the power of 5 in any n!
4! ~ 5^0
5! ~ 5^1 (up to 9!)
10! ~ 5^2 (up to 14!)
15! ~ 5^3 (up to `19!)
20! ~ 5^4 (up to 24!)
25! ~ 5^6 (notice the jump from 5^4 to 5^6 because the number 25 adds two powers of 5)
5.
The way I'd like to count the total power of five in a factorial is... count all the multiples of 5, they all add one power of 5. Then count all the multiples of 25, they all add an extra power of 5. Notice how 25 added two powers of 5, so I can put that as, one power because it's a multiple of 5 and one extra power because it's a multiple of 25. Then count all the multiple of 125 (5^3) in the factorial multiplication, they add another extra power of 5... and so on.
6.
So how'd you put that as an algorithm ?
lets say the number is n. So...
pow1 = n/5 (rounded down to an integer)
pow2 = n/25
pow3 = n/125
and so on...
Now the total power pow = pow1 + pow2 + pow3 ...
7.
Now can you express that as a loop?
So, now that #Spunden has so artfully let the cat out of the bag, here's one way to implement it.
Code
def zeros(n)
return 0 if n.zero?
k = (Math.log(n)/Math.log(5)).to_i
m = 5**k
n*(m-1)/(4*m)
end
Examples
zeros(3) #=> 0
zeros(5) #=> 1
zeros(12) #=> 2
zeros(15) #=> 3
zeros(20) #=> 4
zeros(25) #=> 6
zeros(70) #=> 16
zeros(75) #=> 18
zeros(120) #=> 28
zeros(125) #=> 31
Explanation
Suppose n = 128.
Then each number between one and 128 (inclusive) that is divisible by 5^1=>5 provides at least one factor, and there are 128/5 => 25 such numbers. Of these, the only ones that provide more than one factor are those divisible by 5^2=>25, of which there are 128/25 => 5 (25, 50, 75, 100, 125). Of those, there is but 128/125 => 1 that provides more than two factors, and since 125/(5^4) => 0, no numbers contribute more than three divisors. Hence, the total number of five divisors is:
128/5 + 128/25 + 128/125 #=> 31
(Note that, for 125, which has three divisors of 5, one is counted in each of these three terms; for 25, 50, etc., which each have two factors of 5, one is counted in each of the first terms.)
For arbitrary n, we first compute the highest power k for which:
5**k <= n
which is:
k <= Math.log(n)/Math.log(5)
so the largest such value is:
k = (Math.log(n)/Math.log(5)).to_i
As #spundun noted, you could also calculate k by simply iterating, e.g.,
last = 1
(0..1.0/0).find { |i| (last *= 5) > n }
The total number of factors of five is therefore
(n/5) + (n/25) +...+ (n/5**k)
Defining:
r = 1/5,
this sum is seen to be:
n * s
where
s = r + r**2 +...+ r**k
The value of s is the sum of the terms of a geometric series. I forget the formula for that, but recall how it's derived:
s = r + r**2 +...+ r**k
sr = r**2 +...+ r**(k+1)
s-sr = r*(1-r**k)
s = r*(1-r**k)/(1-r)
I then did some rearrangement so that only only integer arithmetic would be used to calculate the result.
def zeros(n)
zeros = 0
zeros += n /= 5 while n >= 1
zeros
end
If N is a number then number of trailing zeroes in N! is
N/5 + N/5^2 + N/5^3 ..... N/5^(m-1) WHERE (N/5^m)<1
You can learn here how this formula comes.
Here's a solution that is easier to read:
def zeros(num)
char_array = num.to_s.split('')
count = 0
while char_array.pop == "0"
count += 1
end
count
end
Let me know what you think and feel free to edit if you see an improvement!
The article A Note on Factorial and its Trailing Zeros in GanitCharcha is insightful and has explained the Mathematics behind this well. Take a look.
http://www.ganitcharcha.com/view-article-A-Note-on-Factorial-and-it's-Trailing-Zeros.html
My solution
def zeros(n)
trailing_zeros = []
fact = (1..n).inject(:*)
fact.to_s.split('').reverse.select {|x| break if (x.to_i != 0); trailing_zeros << x}
return trailing_zeros.count
end
n = int (raw_input())
count = 0
num = 1
for i in xrange(n+1):
if i != 0:
num = num * i
while(num >= 10):
if num%10 == 0:
count+=1
num = num/10
else:
break
print count
As per the explanation given by #spundan and apart from #cary's code you can find number of trailing zero by just very simple and efficient way..see below code..
def zeros(n)
ret = 0
while n > 0 do
ret += n / 5
n = n/5
end
ret
end
For example zeros(100000000) this will give you output -> 24999999
With the time Time Elapsed -> 5.0453e-05(Just See 5.0453e-05 )
This is the part of even milliseconds.
n=int(input())
j=5
c=int(0)
while int(n/j)>0:
c=c+int(n/j)
j=j*5
print(c)
count = 0
i =5
n = 100
k = n
while(n/i!=0):
count+=(n/i)
i=i*5
n = k
print count
def zeros(n)
n < 5 ? 0 : (n / 5) + zeros(n / 5)
end

Fastest algorithm of getting precise answer (not approximated) when square-rooting

Sorry for unclear title, but I don't know how to state it properly (feel free to edit), so I will give example:
sqrt(108) ~ 10.39... BUT I want it to be like this sqrt(108)=6*sqrt(3) so it means expanding into two numbers
So that's my algorithm
i = floor(sqrt(number)) //just in case, floor returns lowest integer value :)
while (i > 0) //in given example number 108
if (number mod (i*i) == 0)
first = i //in given example first is 6
second = number / (i*i) //in given example second is 3
i = 0
i--
Maybe you know better algorithm?
If it matters I will use PHP and of course I will use appropriate syntax
There is no fast algorithm for this. It requires you to find all the square factors. This requires at least some factorizing.
But you can speed up your approach by quite a bit. For a start, you only need to find prime factors up to the cube root of n, and then test whether n itself is a perfect square using the advice from Fastest way to determine if an integer's square root is an integer.
Next speed up, work from the bottom factors up. Every time you find a prime factor, divide n by it repeatedly, accumulating out the squares. As you reduce the size of n, reduce your limit that you'll go to. This lets you take advantage of the fact that most numbers will be divisible by some small numbers, which quickly reduces the size of the number you have left to factor, and lets you cut off your search sooner.
Next performance improvement, start to become smarter about which numbers you do trial divisions by. For instance special case 2, then only test odd numbers. You've just doubled the speed of your algorithm again.
But be aware that, even with all of these speedups, you're just getting more efficient brute force. It is still brute force, and still won't be fast. (Though it will generally be much, much faster than your current idea.)
Here is some pseudocode to make this clear.
integer_sqrt = 1
remainder = 1
# First we special case 2.
while 0 == number % 4:
integer_sqrt *= 2
number /= 4
if 0 == number / 2:
number /= 2
remainder *= 2
# Now we run through the odd numbers up to the cube root.
# Note that beyond the cube root there is no way to factor this into
# prime * prime * product_of_bigger_factors
limit = floor(cube_root(number + 1))
i = 3
while i <= limit:
if 0 == number % i:
while 0 == number % (i*i):
integer_sqrt *= i
number /= i*i
if 0 == number % (i*i):
number /= i
remainder *= i
limit = floor(cube_root(number + 1))
i += 2
# And finally check whether we landed on the square of a prime.
possible_sqrt = floor(sqrt(number + 1))
if number == possible_sqrt * possible_sqrt:
integer_sqrt *= possible_sqrt
else:
remainder *= number
# And the answer is now integer_sqrt * sqrt(remainder)
Note that the various +1s are to avoid problems with the imprecision of floating point numbers.
Running through all of the steps of the algorithm for 2700, here is what happens:
number = 2700
integer_sqrt = 1
remainder = 1
enter while loop
number is divisible by 4
integer_sqrt *= 2 # now 2
number /= 4 # now 675
number is not divisible by 4
exit while loop
number is not divisible by 2
limit = floor(cube_root(number + 1)) # now 8
i = 3
enter while loop
i < =limit # 3 < 8
enter while loop
number is divisible by i*i # 9 divides 675
integer_sqrt *= 3 # now 6
number /= 9 # now 75
number is not divisible by i*i # 9 does not divide 75
exit while loop
i divides number # 3 divides 75
number /= 3 # now 25
remainder *= 3 # now 3
limit = floor(cube_root(number + 1)) # now 2
i += 2 # now 5
i is not <= limit # 5 > 2
exit while loop
possible_sqrt = floor(sqrt(number + 1)) # 5
number == possible_sqrt * possible_sqrt # 25 = 5 * 5
integer_sqrt *= possible_sqrt # now 30
# and now answer is integer_sqrt * sqrt(remainder) ie 30 * sqrt(3)
It's unlikely that there is a fast algorithm for this. See https://mathoverflow.net/questions/16098/complexity-of-testing-integer-square-freeness especially https://mathoverflow.net/questions/16098/complexity-of-testing-integer-square-freeness/16100#16100
List all prime divisors in increasing order e.g. 2700 = 2*2*3*3*3*5*5. This is the slowest step and requires sqrt(N) operations.
Create an accumulator (start with 1). Scan this list. For every pair of numbers, multiply the accumulator by (one of) them. So after scanning the list above, you get 2*3*5.
Accumulator is your multiplier. The rest remains under square root.

How to check divisibility of a number not in base 10 without converting?

Let's say I have a number of base 3, 1211. How could I check this number is divisible by 2 without converting it back to base 10?
Update
The original problem is from TopCoder
The digits 3 and 9 share an interesting property. If you take any multiple of 3 and sum its digits, you get another multiple of 3. For example, 118*3 = 354 and 3+5+4 = 12, which is a multiple of 3. Similarly, if you take any multiple of 9 and sum its digits, you get another multiple of 9. For example, 75*9 = 675 and 6+7+5 = 18, which is a multiple of 9. Call any digit for which this property holds interesting, except for 0 and 1, for which the property holds trivially.
A digit that is interesting in one base is not necessarily interesting in another base. For example, 3 is interesting in base 10 but uninteresting in base 5. Given an int base, your task is to return all the interesting digits for that base in increasing order. To determine whether a particular digit is interesting or not, you need not consider all multiples of the digit. You can be certain that, if the property holds for all multiples of the digit with fewer than four digits, then it also holds for multiples with more digits. For example, in base 10, you would not need to consider any multiples greater than 999.
Notes
- When base is greater than 10, digits may have a numeric value greater than 9. Because integers are displayed in base 10 by default, do not be alarmed when such digits appear on your screen as more than one decimal digit. For example, one of the interesting digits in base 16 is 15.
Constraints
- base is between 3 and 30, inclusive.
This is my solution:
class InterestingDigits {
public:
vector<int> digits( int base ) {
vector<int> temp;
for( int i = 2; i <= base; ++i )
if( base % i == 1 )
temp.push_back( i );
return temp;
}
};
The trick was well explained here : https://math.stackexchange.com/questions/17242/how-does-base-of-a-number-relate-to-modulos-of-its-each-individual-digit
Thanks,
Chan
If your number k is in base three, then you can write it as
k = a0 3^n + a1 3^{n-1} + a2 3^{n-2} + ... + an 3^0
where a0, a1, ..., an are the digits in the base-three representation.
To see if the number is divisible by two, you're interested in whether the number, modulo 2, is equal to zero. Well, k mod 2 is given by
k mod 2 = (a0 3^n + a1 3^{n-1} + a2 3^{n-2} + ... + an 3^0) mod 2
= (a0 3^n) mod 2 + (a1 3^{n-1}) mod 2 + ... + an (3^0) mod 2
= (a0 mod 2) (3^n mod 2) + ... + (an mod 2) (3^0 mod 2)
The trick here is that 3^i = 1 (mod 2), so this expression is
k mod 2 = (a0 mod 2) + (a1 mod 2) + ... + (an mod 2)
In other words, if you sum up the digits of the ternary representation and get that this value is divisible by two, then the number itself must be divisible by two. To make this even cooler, since the only ternary digits are 0, 1, and 2, this is equivalent to asking whether the number of 1s in the ternary representation is even!
More generally, though, if you have a number in base m, then that number is divisible by m - 1 iff the sum of the digits is divisible by m. This is why you can check if a number in base 10 is divisible by 9 by summing the digits and seeing if that value is divisible by nine.
You can always build a finite automaton for any base and any divisor:
Normally to compute the value n of a string of digits in base b
you iterate over the digits and do
n = (n * b) + d
for each digit d.
Now if you are interested in divisibility you do this modulo m instead:
n = ((n * b) + d) % m
Here n can take at most m different values. Take these as states of a finite automaton, and compute the transitions depending on the digit d according to that formula. The accepting state is the one where the remainder is 0.
For your specific case we have
n == 0, d == 0: n = ((0 * 3) + 0) % 2 = 0
n == 0, d == 1: n = ((0 * 3) + 1) % 2 = 1
n == 0, d == 2: n = ((0 * 3) + 2) % 2 = 0
n == 1, d == 0: n = ((1 * 3) + 0) % 2 = 1
n == 1, d == 1: n = ((1 * 3) + 1) % 2 = 0
n == 1, d == 2: n = ((1 * 3) + 2) % 2 = 1
which shows that you can just sum the digits 1 modulo 2 and ignore any digits 0 or 2.
Add all the digits together (or even just count the ones) - if the answer is odd, the number is odd; if it's even, the nmber is even.
How does that work? Each digit from the number contributes 0, 1 or 2 times (1, 3, 9, 27, ...). A 0 or a 2 adds an even number, so no effect on the oddness/evenness (parity) of the number as a whole. A 1 adds one of the powers of 3, which is always odd, and so flips the parity). And we start from 0 (even). So by counting whether the number of flips is odd or even we can tell whether the number itself is.
I'm not sure on what CPU you have a number in base-3, but the normal way to do this is to perform a modulus/remainder operation.
if (n % 2 == 0) {
// divisible by 2, so even
} else {
// odd
}
How to implement the modulus operator is going to depend on how you're storing your base-3 number. The simplest to code will probably be to implement normal pencil-and-paper long division, and get the remainder from that.
0 2 2 0
_______
2 ⟌ 1 2 1 1
0
---
1 2
1 1
-----
1 1
1 1
-----
0 1 <--- remainder = 1 (so odd)
(This works regardless of base, there are "tricks" for base-3 as others have mentioned)
Same as in base 10, for your example:
1. Find the multiple of 2 that's <= 1211, that's 1210 (see below how to achieve it)
2. Substract 1210 from 1211, you get 1
3. 1 is < 10, thus 1211 isn't divisible by 2
how to achieve 1210:
1. starts with 2
2. 2 + 2 = 11
3. 11 + 2 = 20
4. 20 + 2 = 22
5. 22 + 2 = 101
6. 101 + 2 = 110
7. 110 + 2 = 112
8. 112 + 2 = 121
9. 121 + 2 = 200
10. 200 + 2 = 202
... // repeat until you get the biggest number <= 1211
it's basically the same as base 10 it's just the round up happens on 3 instead of 10.

Resources