Can someone please calculate the the no. of steps it will take to execute the above code?
And verify the solution, with some input values of n.
(found some relevant question, but not helping)
int count=0;
for(int i=1; i<=n ;i=i*2)
{
for(int j=1; j<=i; j=j*2)
{
count++;
}
}
We can make a table:
i = 1: j = 1 --> 1 count
i = 2: j = 1,2 --> 2 counts
i = 4: j = 1,2,4 --> 3 counts
i = 8: j = 1,2,4,8 --> 4 counts
The pattern should be clear from here. We can reimagine the pattern such that i = 1, 2, 3, 4, ..., and instead of going from 1 to n, let's just say it goes from 1 to log n. This means that the total count should be the sum from i = 1 to log (base 2) n of i. The sum from i = 1 to x of i is simply x(x+1)/2, so if x = log_2(n), then this sum is simply (log_2(n) * log_2(n)+1)/2
EDIT: It seems like I made a mistake somewhere, and what I wrote is actually f(n/2) based on empirical tests. Thus, the correct answer is actually (log_2(2n) * log_2(2n)+1)/2. Nevertheless, this is the logic I would follow to solve a problem like this
EDIT 2: Caught my mistake. Instead of saying "let's just say it goes from 1 to log n", I should have said "let's just say it goes from 0 to log n" (i.e., I need to take the log of every number in the series)
inner-loop
i = 1 --> log(1) = 0
i = 2 --> log(2) = 1
i = 4 --> log(4) = 2
i = 8 --> log(8) = 3
i = 16 -> log(16) = 4
i = 32 -> log(32) = 5
i = 64 -> log(64) = 6
.
.
.
i = n -> log(n) = log(n)
That is the amount of work and it will stop after log(n) iterations as i hits n.
1 + 2 + 3 + 4 +...+ log(n) = [(1+log(n))*log(n)]/2 = O(log^2(n))
Related
I am creating two methods - one that calculates the sum of the digits in a number recursively, and the other iteratively.
I have created the recursive method, and for the most part I understand the concept of finding the sum of digits, but I am not sure how to correctly put it into an iterative method. My code does not give me the correct output.
public static int iterativeDigitSum(long n) {
if(n < 0){
String err = "n must be positive. n = " + n;
throw new IllegalArgumentException(err);
}
if(n == 0){
return 0;
}
long sum = 0;
long i = 0;
while(n > 0){
i = n % 10;
sum = sum + n;
n = n / 10;
}
int inSum = (int)sum;
return inSum;
}
The number "n" is 10, meaning the expected output is 1. I am getting 11. Could you please explain to me what I am doing wrong, and possibly how to fix it? Thank you so much.
Basically, the algorithm consists of three steps:
Get the rightmost digit of the number. Since each digit in a number has a rank of units, tens, hundreds, thousands etc based on its position the rightmost digit is the remainder of dividing the number by 10:
digit = n % 10
Sum the digit up:
sum += digit
Move all the digits one place to the right by dividing the number by 10. The number becomes 10 times smaller:
n = n / 10
Effectively, this will "provide" the next rightmost digit for step 1.
The above three steps are repeated until the value of number becomes zero.
You can help yourself visualize the above explanation by adding some "debugging" information into your code:
public static int iterativeDigitSum(long n)
{
long sum = 0;
int i = 1;
System.out.println("i\tn\tdigit\tsum");
while(n > 0) {
long digit = n % 10;
sum += digit;
System.out.println(i + "\t" + n + "\t" + digit + "\t" + sum);
n = n / 10;
i++;
}
System.out.println("\t" + n + "\t\t" + sum);
return (int)sum;
}
Please note that the i variable is used to count the loop iterations and the digit variable holds the rightmost digit of the number in each iteration.
Given the number 10, the output to the BlueJ console is:
i n digit sum
1 10 0 0
2 1 1 1
0 1
and for the number 2019:
i n digit sum
1 2019 9 9
2 201 1 10
3 20 0 10
4 2 2 12
0 12
Hope it helps.
I try to calculate Big O complexity for this code but I always fail....
I tried to nest SUM's or to get the number of steps for each case like:
i=1 j=1 k=1 (1 step)
i=2 j=1,2 k=1,2,3,4 (4 steps)
. . . . . . . . . . . . . . .
i=n (i said n = 2^(log n) j = 1,2,4,8,16,.....,n k=1,2,3,4,.....n^2 (n^2 steps)
then sum all the steps together, I need help.
for (int i=1; i<=n; i*=2)
for (int j=1; j<=i; j*=2)
for(int k=1; k<=j*j; k++)
//code line with complexity code O(1)
Let's take a look at the number of times the inner loop runs: j2. But j steps along in powers of 2 up to i. i in turn steps in powers of 2 up to n. So let's "draw" a little graphic of the terms of the sum that would give us the total number of iterations:
---- 1
^ 1 4
| 1 4 16
log2(n) ...
| 1 4 16 ... n2/16
v 1 4 16 ... n2/16 n2/4
---- 1 4 16 ... n2/16 n2/4 n2
|<------log2(n)------>|
The graphic can be interpreted as follows: each value of i corresponds to a row. Each value of j is a column within that row. The number itself is the number of iterations k goes through. The values of j are the square roots of the numbers. The values of i are the square roots of the last element in each row. The sum of all the numbers is the total number of iterations.
Looking at the bottom row, the terms of the sum are (2z)2 = 22z for z = 1 ... log2(n). The number of times that the terms appear in the sum is modulated by the height of the column. The height for a given term is log2(n) + 1 - z (basically a count down from log2(n)).
So the final sum is
log2(n)
Σ 22z(log2(n) + 1 - z)
z = 1
Here is what Wolfram Alpha has to say about evaluating the sum: http://m.wolframalpha.com/input/?i=sum+%28%28log%5B2%2C+n%5D%29+%2B+1+-+z%29%282%5E%282z%29%29%2C+z%3D1+to+log%5B2%2C+n%5D:
C1n2 - C2log(n) - C3
Cutting out all the less significant terms and constants, the result is
O(n2)
For the outermost loop:
sum_{i in {1, 2, 4, 8, 16, ...}} 1, i <= n (+)
<=>
sum_{i in {2^0, 2^1, 2^2, ... }} 1, i <= n
Let 2^I = i:
2^I = i <=> e^{I log 2} = i <=> I log 2 = log i <=> I = (log i)/(log 2)
Thus, (+) is equivalent to
sum_{I in {0, 1, ... }} 1, I <= floor((log n)/(log 2)) ~= log n (*)
Second outermost loop:
sum_{j in {1, 2, 4, 8, 16, ...}} 1, j <= i (++)
As above, 2^I = i, and let 2^J = j. Similarly to above,
(++) is equivalent to:
sum_{J in {0, 1, ... }} 1, J <= floor((log (2^I))/(log 2)) = floor(I/(log 2)) ~= I (**)
To touch base, only the outermost and second outermost
have now been reduced to
sum_{I in {0, 1, ... }}^{log n} sum_{J in {0, 1, ...}}^{I} ...
Which is (if there would be no innermost loop) O((log n)^2)
Innermost loop is a trivial one if we can express the largest bound in terms of `n`.
sum_{k in {1, 2, 3, 4, ...}} 1, k <= j^2 (+)
As above, let 2^J = j and note that j^2 = 2^(2J)
sum_{k in {1, 2, 3, 4, ...}} 1, k <= 2^(2J)
Thus, k is bounded by 2^(2 max(J)) = 2^(2 max(I)) = 2^(2 log(n) ) = 2n^2 (***)
Combining (*), (**) and (***), the asymptotic complexity of the three nested loops is:
O(n^2 log^2 n) (or, O((n log n)^2)).
I decide to modify the following while loop and use it inside a function so that the loop can take any value instead of 6.
i = 0
numbers = []
while i < 6:
numbers.append(i)
i += 1
I created the following script so that I can use the variable(or more specifically argument ) instead of 6 .
def numbers(limit):
i = 0
numbers = []
while i < limit:
numbers.append(i)
i = i + 1
print numbers
user_limit = raw_input("Give me a limit ")
numbers(user_limit)
When I didn't use the raw_input() and simply put the arguments from the script it was working fine but now when I run it(in Microsoft Powershell) a cursor blinks continuously after the question in raw_input() is asked. Then i have to hit CTRL + C to abort it. Maybe the function is not getting called after raw_input().
Now it is giving a memory error like in the pic.
You need to convert user_limit to Int:
raw_input() return value is str and the statement is using i which is int
def numbers(limit):
i = 0
numbers = []
while i < limit:
numbers.append(i)
i = i + 1
print numbers
user_limit = int(raw_input("Give me a limit "))
numbers(user_limit)
Output:
Give me a limit 8
[0, 1, 2, 3, 4, 5, 6, 7]
I'd like to calculate a non-uniformly distributed random number in the range [0, n - 1]. So the min possible value is zero. The maximum possible value is n-1. I'd like the min-value to occur the most often and the max to occur relatively infrequently with an approximately linear curve between (Gaussian is fine too). How can I do this in Objective-C? (possibly using C-based APIs)
A very rough sketch of my current idea is:
// min value w/ p = 0.7
// some intermediate value w/ p = 0.2
// max value w/ p = 0.1
NSUInteger r = arc4random_uniform(10);
if (r <= 6)
result = 0;
else if (r <= 8)
result = (n - 1) / 2;
else
result = n - 1;
I think you're on basically the right track. There are possible precision or range issues but in general if you wanted to randomly pick, say, 3, 2, 1 or 0 and you wanted the probability of picking 3 to be four times as large as the probability of picking 0 then if it were a paper exercise you might right down a grid filled with:
3 3 3 3
2 2 2
1 1
0
Toss something onto it and read the number it lands on.
The number of options there are for your desired linear scale is:
- 1 if number of options, n, = 1
- 1 + 2 if n = 2
- 1 + 2 + 3 if n = 3
- ... etc ...
It's a simple sum of an arithmetic progression. You end up with n(n+1)/2 possible outcomes. E.g. for n = 1 that's 1 * 2 / 2 = 1. For n = 2 that's 2 * 3 /2 = 3. For n = 3 that's 3 * 4 / 2 = 6.
So you would immediately write something like:
NSUInteger random_linear(NSUInteger range)
{
NSUInteger numberOfOptions = (range * (range + 1)) / 2;
NSUInteger uniformRandom = arc4random_uniform(numberOfOptions);
... something ...
}
At that point you just have to decide which bin uniformRandom falls into. The simplest way is with the most obvious loop:
NSUInteger random_linear(NSUInteger range)
{
NSUInteger numberOfOptions = (range * (range + 1)) / 2;
NSUInteger uniformRandom = arc4random_uniform(numberOfOptions);
NSUInteger index = 0;
NSUInteger optionsToDate = 0;
while(1)
{
if(optionsToDate >= uniformRandom) return index;
index++;
optionsToDate += index;
}
}
Given that you can work out optionsToDate without iterating, an immediately obvious faster solution is a binary search.
An even smarter way to look at it is that uniformRandom is the sum of the boxes underneath a line from (0, 0) to (n, n). So it's the area underneath the graph, and the graph is a simple right-angled triangle. So you can work backwards from the area formula.
Specifically, the area underneath the graph from (0, 0) to (n, n) at position x is (x*x)/2. So you're looking for x, where:
(x-1)*(x-1)/2 <= uniformRandom < x*x/2
=> (x-1)*(x-1) <= uniformRandom*2 < x*x
=> x-1 <= sqrt(uniformRandom*2) < x
In that case you want to take x-1 as the result hadn't progressed to the next discrete column of the number grid. So you can get there with a square root operation simple integer truncation.
So, assuming I haven't muddled my exact inequalities along the way, and assuming all precisions fit:
NSUInteger random_linear(NSUInteger range)
{
NSUInteger numberOfOptions = (range * (range + 1)) / 2;
NSUInteger uniformRandom = arc4random_uniform(numberOfOptions);
return (NSUInteger)sqrtf((float)uniformRandom * 2.0f);
}
What if you try squaring the return value of arc4random_uniform() (or multiplying two of them)?
int rand_nonuniform(int max)
{
int r = arc4random_uniform(max) * arc4random_uniform(max + 1);
return r / max;
}
I've quickly written a sample program for testing it and it looks promising:
int main(int argc, char *argv[])
{
int arr[10] = { 0 };
int i;
for (i = 0; i < 10000; i++) {
arr[rand_nonuniform(10)]++;
}
for (i = 0; i < 10; i++) {
printf("%2d. = %2d\n", i, arr[i]);
}
return 0;
}
Result:
0. = 3656
1. = 1925
2. = 1273
3. = 909
4. = 728
5. = 574
6. = 359
7. = 276
8. = 187
9. = 113
I need to find whether a number is divisible by 3 without using %, / or *. The hint given was to use atoi() function. Any idea how to do it?
The current answers all focus on decimal digits, when applying the "add all digits and see if that divides by 3". That trick actually works in hex as well; e.g. 0x12 can be divided by 3 because 0x1 + 0x2 = 0x3. And "converting" to hex is a lot easier than converting to decimal.
Pseudo-code:
int reduce(int i) {
if (i > 0x10)
return reduce((i >> 4) + (i & 0x0F)); // Reduces 0x102 to 0x12 to 0x3.
else
return i; // Done.
}
bool isDiv3(int i) {
i = reduce(i);
return i==0 || i==3 || i==6 || i==9 || i==0xC || i == 0xF;
}
[edit]
Inspired by R, a faster version (O log log N):
int reduce(unsigned i) {
if (i >= 6)
return reduce((i >> 2) + (i & 0x03));
else
return i; // Done.
}
bool isDiv3(unsigned i) {
// Do a few big shifts first before recursing.
i = (i >> 16) + (i & 0xFFFF);
i = (i >> 8) + (i & 0xFF);
i = (i >> 4) + (i & 0xF);
// Because of additive overflow, it's possible that i > 0x10 here. No big deal.
i = reduce(i);
return i==0 || i==3;
}
Subtract 3 until you either
a) hit 0 - number was divisible by 3
b) get a number less than 0 - number wasn't divisible
-- edited version to fix noted problems
while n > 0:
n -= 3
while n < 0:
n += 3
return n == 0
Split the number into digits. Add the digits together. Repeat until you have only one digit left. If that digit is 3, 6, or 9, the number is divisible by 3. (And don't forget to handle 0 as a special case).
While the technique of converting to a string and then adding the decimal digits together is elegant, it either requires division or is inefficient in the conversion-to-a-string step. Is there a way to apply the idea directly to a binary number, without first converting to a string of decimal digits?
It turns out, there is:
Given a binary number, the sum of its odd bits minus the sum of its even bits is divisible by 3 iff the original number was divisible by 3.
As an example: take the number 3726, which is divisible by 3. In binary, this is 111010001110. So we take the odd digits, starting from the right and moving left, which are [1, 1, 0, 1, 1, 1]; the sum of these is 5. The even bits are [0, 1, 0, 0, 0, 1]; the sum of these is 2. 5 - 2 = 3, from which we can conclude that the original number is divisible by 3.
A number divisible by 3, iirc has a characteristic that the sum of its digit is divisible by 3. For example,
12 -> 1 + 2 = 3
144 -> 1 + 4 + 4 = 9
The interview question essentially asks you to come up with (or have already known) the divisibility rule shorthand with 3 as the divisor.
One of the divisibility rule for 3 is as follows:
Take any number and add together each digit in the number. Then take that sum and determine if it is divisible by 3 (repeating the same procedure as necessary). If the final number is divisible by 3, then the original number is divisible by 3.
Example:
16,499,205,854,376
=> 1+6+4+9+9+2+0+5+8+5+4+3+7+6 sums to 69
=> 6 + 9 = 15 => 1 + 5 = 6, which is clearly divisible by 3.
See also
Wikipedia/Divisibility rule - has many rules for many divisors
Given a number x.
Convert x to a string. Parse the string character by character. Convert each parsed character to a number (using atoi()) and add up all these numbers into a new number y.
Repeat the process until your final resultant number is one digit long. If that one digit is either 3,6 or 9, the origional number x is divisible by 3.
My solution in Java only works for 32-bit unsigned ints.
static boolean isDivisibleBy3(int n) {
int x = n;
x = (x >>> 16) + (x & 0xffff); // max 0x0001fffe
x = (x >>> 8) + (x & 0x00ff); // max 0x02fd
x = (x >>> 4) + (x & 0x000f); // max 0x003d (for 0x02ef)
x = (x >>> 4) + (x & 0x000f); // max 0x0011 (for 0x002f)
return ((011111111111 >> x) & 1) != 0;
}
It first reduces the number down to a number less than 32. The last step checks for divisibility by shifting the mask the appropriate number of times to the right.
You didn't tag this C, but since you mentioned atoi, I'm going to give a C solution:
int isdiv3(int x)
{
div_t d = div(x, 3);
return !d.rem;
}
bool isDiv3(unsigned int n)
{
unsigned int n_div_3 =
n * (unsigned int) 0xaaaaaaab;
return (n_div_3 < 0x55555556);//<=>n_div_3 <= 0x55555555
/*
because 3 * 0xaaaaaaab == 0x200000001 and
(uint32_t) 0x200000001 == 1
*/
}
bool isDiv5(unsigned int n)
{
unsigned int n_div_5 =
i * (unsigned int) 0xcccccccd;
return (n_div_5 < 0x33333334);//<=>n_div_5 <= 0x33333333
/*
because 5 * 0xcccccccd == 0x4 0000 0001 and
(uint32_t) 0x400000001 == 1
*/
}
Following the same rule, to obtain the result of divisibility test by 'n', we can :
multiply the number by 0x1 0000 0000 - (1/n)*0xFFFFFFFF
compare to (1/n) * 0xFFFFFFFF
The counterpart is that for some values, the test won't be able to return a correct result for all the 32bit numbers you want to test, for example, with divisibility by 7 :
we got 0x100000000- (1/n)*0xFFFFFFFF = 0xDB6DB6DC
and 7 * 0xDB6DB6DC = 0x6 0000 0004,
We will only test one quarter of the values, but we can certainly avoid that with substractions.
Other examples :
11 * 0xE8BA2E8C = A0000 0004, one quarter of the values
17 * 0xF0F0F0F1 = 10 0000 0000 1
comparing to 0xF0F0F0F
Every values !
Etc., we can even test every numbers by combining natural numbers between them.
A number is divisible by 3 if all the digits in the number when added gives a result 3, 6 or 9. For example 3693 is divisible by 3 as 3+6+9+3 = 21 and 2+1=3 and 3 is divisible by 3.
inline bool divisible3(uint32_t x) //inline is not a must, because latest compilers always optimize it as inline.
{
//1431655765 = (2^32 - 1) / 3
//2863311531 = (2^32) - 1431655765
return x * 2863311531u <= 1431655765u;
}
On some compilers this is even faster then regular way: x % 3. Read more here.
well a number is divisible by 3 if all the sum of digits of the number are divisible by 3. so you could get each digit as a substring of the input number and then add them up. you then would repeat this process until there is only a single digit result.
if this is 3, 6 or 9 the number is divisable by 3.
Here is a pseudo-algol i came up with .
Let us follow binary progress of multiples of 3
000 011
000 110
001 001
001 100
001 111
010 010
010 101
011 000
011 011
011 110
100 001
100 100
100 111
101 010
101 101
just have a remark that, for a binary multiple of 3 x=abcdef in following couples abc=(000,011),(001,100),(010,101) cde doest change , hence, my proposed algorithm:
divisible(x):
y = x&7
z = x>>3
if number_of_bits(z)<4
if z=000 or 011 or 110 , return (y==000 or 011 or 110) end
if z=001 or 100 or 111 , return (y==001 or 100 or 111) end
if z=010 or 101 , return (y==010 or 101) end
end
if divisible(z) , return (y==000 or 011 or 110) end
if divisible(z-1) , return (y==001 or 100 or 111) end
if divisible(z-2) , return (y==010 or 101) end
end
C# Solution for checking if a number is divisible by 3
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int num = 33;
bool flag = false;
while (true)
{
num = num - 7;
if (num == 0)
{
flag = true;
break;
}
else if (num < 0)
{
break;
}
else
{
flag = false;
}
}
if (flag)
Console.WriteLine("Divisible by 3");
else
Console.WriteLine("Not Divisible by 3");
Console.ReadLine();
}
}
}
Here is your optimized solution that every one should know.................
Source: http://www.geeksforgeeks.org/archives/511
#include<stdio.h>
int isMultiple(int n)
{
int o_count = 0;
int e_count = 0;
if(n < 0)
n = -n;
if(n == 0)
return 1;
if(n == 1)
return 0;
while(n)
{
if(n & 1)
o_count++;
n = n>>1;
if(n & 1)
e_count++;
n = n>>1;
}
return isMultiple(abs(o_count - e_count));
}
int main()
{
int num = 23;
if (isMultiple(num))
printf("multiple of 3");
else
printf(" not multiple of 3");
return 0;
}