Studying for exams I have been given a lot of code to manually compute. This question its throwing me for a loop.
public static int[] mystery(int x) {
int[] result = new int[x / 2];
for (int i = 0; i < x/2; i++) {
result[i] = (i * i) % x;
}
return result;
}
for:
mystery(5)
mystery(10)
What I computed was [0, 1] for mystery(5) and [0, 1, 4, 4, 1] for mystery(10); however, I believe that those answers are not correct.
When going about questions like these, what strategies may help lead me to the answer faster?
Also if you conclude to an answer what were the steps you took to arrive at the answer?
Your answer to mystery(5) is correct.
The array for mystery(10) should contain [0,1,4,9,6], since you're calculating square numbers mod 10 in this case.
In my opinion there is really no strategy to get a result faster. It's all about experience in reading the code.
The steps I took for this particular answer were basically
look at the argument (x=10)
look where the argument appears and insert it
go through the code step by step
look at first line -> int division -> array has size 5
look at for loop, insert argument and work with concrete numbers -> for(int i = 0; i < 5; i++) => so i goes from 0 to 4
look at expression and decide, which values are changing and which ones are fixed -> result[i] = (i*i)%10;
Think, what loop does => ith square number mod 10 goes into array at index i
So result should be [0,1,4,9,6]
The key thing you should observe when reading this method is that the iterations of the loop are data-flow independent; the effect of iteration i can be analyzed in isolation, without needing to know what happened at any other iterations.
Thus there's really only one fact you need to be thinking about: resulti = i2 mod x. Then you can forget about the code and just do the math.
Where x = 10:
result0 = 02 mod 10 = 0
result1 = 12 mod 10 = 1
result2 = 22 mod 10 = 4
result3 = 32 mod 10 = 9
result4 = 42 mod 10 = 6
Related
I've been trying to figure out the most efficient way where many threads are altering a very big byte array on bit level. For ease of explaining I'll base the question around a multithreaded Sieve of Eratosthenes to ease explaining the question. The code though should not be expected to fully completed as I'll omit certain parts that aren't directly related. The sieve also wont be fully optimised as thats not the direct question. The sieve will work in such a way that it saves which values are primes in a byte array, where each byte contains 7 numbers (we can't alter the first bit due to all things being signed).
Lets say our goal is to find all the primes below 1 000 000 000 (1 billion). As a result we would need an byte array of length 1 000 000 000 / 7 +1 or 142 857 143 (About 143 million).
class Prime {
int max = 1000000000;
byte[] b = new byte[(max/7)+1];
Prime() {
for(int i = 0; i < b.length; i++) {
b[i] = (byte)127; //Setting all values to 1 at start
}
findPrimes();
}
/*
* Calling remove will set the bit value associated with the number
* to 0 signaling that isn't an prime
*/
void remove(int i) {
int j = i/7; //gets which array index to access
b[j] = (byte) (b[j] & ~(1 << (i%7)));
}
void findPrimes() {
remove(1); //1 is not a prime and we wanna remove it from the start
int prime = 2;
while (prime*prime < max) {
for(int i = prime*2; i < max; i = prime + i) {
remove(i);
}
prime = nextPrime(prime); //This returns the next prime from the list
}
}
... //Omitting code, not relevant to question
}
Now we got a basic outline where something runs through all numbers for a certain mulitplication table and calls remove to remove numbers set bits that fits the number to 9 if we found out they aren't primes.
Now to up the ante we create threads that do the checking for us. We split the work so that each takes a part of the removing from the table. So for example if we got 4 threads and we are running through the multiplication table for the prime 2, we would assign thread 1 all in the 8 times tables with an starting offset of 2, that is 4, 10, 18, ...., the second thread gets an offset of 4, so it goes through 6, 14, 22... and so on. They then call remove on the ones they want.
Now to the real question. As most can see that while the prime is less than 7 we will have multiple threads accessing the same array index. While running through 2 for example we will have thread 1, thread 2 and thread 3 will all try to access b[0] to alter the byte which causes an race condition which we don't want.
The question therefore is, whats the best way of optimising access to the byte array.
So far the thoughts I've had for it are:
Putting synchronized on the remove method. This obviously would be very easy to implement but an horrible ideas as it would remove any type of gain from having threads.
Create an mutex array equal in size to the byte array. To enter an index one would need the mutex on the same index. This Would be fairly fast but would require another very big array in memory which might not be the best way to do it
Limit the numbers stored in the byte to prime number we start running on. So if we start on 2 we would have numbers per array. This would however increase our array length to 500 000 000 (500 million).
Are there other ways of doing this in a fast and optimal way without overusing the memory?
(This is my first question here so I tried to be as detailed and thorough as possible but I would accept any comments on how I can improve the question - to much detail, needs more detail etc.)
You can use an array of atomic integers for this. Unfortunately there isn't a getAndAND, which would be ideal for your remove() function, but you can CAS in a loop:
java.util.concurrent.atomic.AtomicIntegerArray aia;
....
void remove(int i) {
int j = i/32; //gets which array index to access
do {
int oldVal = aia.get(j);
int newVal = oldVal & ~(1 << (i%32));
boolean updated = aia.weakCompareAndSet(j, oldVal, newVal);
} while(!updated);
}
Basically you keep trying to adjust the slot to remove that bit, but you only succeed if nobody else modifies it out from under you. Safe, and likely to be very efficient. weakCompareAndSet is basically an abstracted Load-link/Store conditional instruction.
BTW, there's no reason not to use the sign bit.
I think you could avoid synchronizing threads...
For example, this task:
for(int i = prime*2; i < max; i = prime + i) {
remove(i);
}
it could be partitioned in small tasks.
for (int i =0; i < thread_poll; i++){
int totalPos = max/8; // dividing virtual array in bytes
int partitionSize = totalPos /thread_poll; // dividing bytes by thread poll
removeAll(prime, partitionSize*i*8, (i + 1)* partitionSize*8);
}
....
// no colisions!!!
void removeAll(int prime, int initial; int max){
k = initial / prime;
if (k < 2) k = 2;
for(int i = k * prime; i < max; i = i + prime) {
remove(i);
}
}
We've got 2 pieces of code:
int a = 3;
while (a <= n) {
a = a * a;
}
And:
public void foo(int n, int m) {
int i = m;
while (i > 100)
i = i / 3;
for (int k = i ; k >= 0; k--) {
for (int j = 1; j < n; j*=2)
System.out.print(k + "\t" + j);
System.out.println();
}
}
What is the time complexity of them?
I think that the first one is: O(logn), because it's progressing to N with power of 2.
So maybe it's O(log2n) ?
And the second one I believe is: O(nlog2n), because it's progressing with jumps of 2, and also running on the outer loop.
Am I right?
I believe, that first code will run in O(Log(LogN)) time. It's simple to understand in this way
Before first iteration you have 3 in power 1
After first iteration you have 3 in power 2
After second iteration you have 3 in power 4
After third iteration you have 3 in power 8
After fourth iteration you have 3 in power 16
and so on.
In the second code first piece of code will work in O(LogM) time, because you divide i by 3 every time. The second piece of code C times (C equals 100 in your case) will perform O(LogN) operations, because you multiply j by 2 every time, so it runs in O(CLogN), and you have complexity O(LogM + CLogN)
For the first one, it is indeed O(log(log(n))). Thanks to #MarounMaroun for the hint, I could find this:
l(k) = l(k-1)^2
l(0) = 3
Solving this system yields:
l(k) = 3^(2^k)
So, we are looking for such a k that satisfies l(k) = n. So simply solve that:
This means we found:
The second code is seems misleading. It looks like O(nlog(n)), but the outer loop limited to 100. So, if m < 100, then it obviously is O(mlog(n)). Otherwise, it kind of depends on where exactly m is. Consider these two:
m: 305 -> 101 -> 33
m: 300 -> 100
In the first case, the outer loop would run 33 times. Whereas the second case would cause 100 iterations. I'm not sure, but I think you can write this as being O(log(n)).
I am trying to write a program that accepts an array of five four digit numbers and sorts the array based off the least significant digit. For example if the numbers were 1234, 5432, 4567, and 8978, the array would be sorted first by the last digit so the nest sort would be 5432, 1224, 4597, 8978. Then after it would be 1224, 5432, 8978, 4597. And so on until it is fully sorted.
I have wrote the code for displaying the array and part of it for sorting. I am not sure how to write the equations I need to compare each digit. This is my code for sorting by each digit so far:
public static void sortByDigit(int[] array, int size)
{
for(int i = 0; i < size; i++)
{
for(int j = 0; j < size; j++)
{
}
for(i = 0; i < size; i++)
{
System.out.println(array[i]);
}
}
}
I am not sure what to put in the nested for loop. I think I need to use the modulus.
I just wrote this to separate the digits but I don't know how to swap the numbers or compare them.
int first = array[i]%10;
int second = (array[i]%100)/10;
int third = (array[i]%1000)/10;
int fourth = (array[i]%10000)/10;
Would this would go in the for loop?
It seems like your problem is mainly just getting the value of a digit at a certain index. Once you can do that, you should be able to formulate a solution.
Your hunch that you need modulus is absolutely correct. The modulo operator (%) returns the remainder on a given division operation. This means that saying 10 % 2 would equal 0, as there is no remainder. 10 % 3, however, would yield 1, as the remainder is one.
Given that quick background on modulus, we just need to figure out how to make a method that can grab a digit. Let's start with a general signature:
public int getValueAtIdx(int value, int idx){
}
So, if we call getValueAtIdx(145, 2), it should return 1 (assuming that the index starts at the least significant digit). If we call getValueAtIdx(562354, 3), it should return 2. You get the idea.
Alright, so let's start by using figuring out how to do this on a simple case. Let's say we call getValueAtIdx(27, 0). Using modulus, we should be able to grab that 7. Our equation is 27 % x = 7, and we just need to determine x. So 27 divided by what will give us a remainder of 7? 10, of course! That makes our equation 27 % 10 = 7.
Now that's all find and dandy, but how does 10 relate to 0? Well, let's try and grab the value at index 1 this time (2), and see if we can't figure it out. With what we did last time, we should have something like 27 % x = 27 (WARNING: There is a rabbit-hole here where you could think x should be 5, but upon further examination it can be found that only works in this case). What if we take the 10 we used earlier, but square it (index+1)? That would give us 27 % 100 = 27. Then all we have to do is divide by 10 and we're good.
So what would that look like in the function we are making?
public int getValueAtIdx(int value, int idx){
int modDivisor = (int) Math.pow(10, (idx+1));
int remainder = value % modDivisor;
int digit = remainder / (modDivisor / 10);
return digit;
}
Ok, so let's to back to the more complicated example: getValueAtIdx(562354, 3).
In the first step, modDivisor becomes 10^4, which equals 10000.
In the second step, remainder is set to 562354 % 10000, which equals 2354.
In the third and final step, digit is set to remainder / (10000 / 10). Breaking that down, we get remainder / 1000, which (using integer division) is equal to 2.
Our final step is return the digit we have acquired.
EDIT: As for the sort logic itself, you may want to look here for a good idea.
The general process is to compare the two digits, and if they are equal move on to their next digit. If they are not equal, put them in the bucket and move on.
so i'm creating a program in java where you enter scores and it classifies them into deciles (0-9, 10-19, 20-29, ... 80-89, 90-100) and I've got a grasp on how the program is supposed to work but I'm missing one key element. I create an array with 10 elements (one for each decile range). Once the user inputs their score it divides by 10 and then needs to put the score into it's appropriate spot in the array, but that's where I'm lost. It has to do a bunch of things after that, that I understand but how am I supposed to tell the code when someone enters 55 to increase the 50-59 part of the array by 1 and so on?
Um, it sounds like you just want:
bucketedScores[score / 10]++;
Don't you? Or possibly clearer:
bucketedScores[score / 10] = roughScores[score / 10] + 1;
int index = value / 10;
myArray[index] += 1;
FYI, given what you said, you will get an IndexOutOfBoundsException with a score of 100. May need to deal with that.
Try it this way....
bucketedScores[score / 10] = roughScores[score / 10] + 1;
Sounds like
int[] myarray = new int[10];
// Divide and increase the number returned (like 84/10 = 8 in integer division)
myarray[num/10]++
Though 100 would throw it off, you would need a special case for that one.
According to the Question
get into loops say for example i hope you're dividing 100 values 10-10 each. Use for loops and check and categorize it by assigning the input to a temporary variable for each iteration of inputs.
for(int i=0; i<=100; i++)
{
if(a[i] >= 0 && a[i] < 10)
your desired o/p(execution)
else if(a[i] > 10 && a[i] < 20)
your desired o/p(execution)
}
As the range is has 101 values from 0 to 101 you need to do more than divide by 10.
Do you mean like?
int[] scores = new int[10];
int decile = ...
int score = ....
scores[Math.min(9, decile/10)] += score;
This ensures that 100 is mapped to 9. Another solutions is to use (int)(decile/10.1) which would maps 0 to 10 to the first decile.
This might be stupid, but I'm want to know if it's possible, lets start with 5x5 a matrix
int[][] x = new int[5][5];
Random rg = new Random();
now let's fill it with Pseudo Random information
for(int i=0;i<5;i++){
for(int j =0; j<5;j++){
x[i][j] = rg.nextInt();
}
}
but how can I do this right with one Single for?
for(int i=0, j=0; i<5; (j==5?i++, j=0:j++){
x[i][j] = rg.nextInt();
}
this is not working :(
You need to compute the row and column from a single index, then:
for(int i = 0; i < 5 * 5; i++)
{
int row = i / 5;
int column = i % 5;
x[row][column] = rg.nextInt();
}
The use of / and % is classic, here: as you iterate over the indices of the matrix, the division is used to figure out which row you're on. The remainder (%) is then the column.
This gorgeous ASCII art shows how the 1-dimensional indices are located in the 2D matrix:
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
It should be clear that for any value in the first row, that value divided by 5 is the row index itself, i.e. they're all 0.
You really will not gain anything from doing that. keep your code readable. it's actually more intensive to do the multiplications and divisions unwind suggested then to just to a loop. (multiply divide and mod are actually a complex set of instructions in an ALU)
Another way to do it would be:
int i,j;
for (i=0,j=0; i<5 && j<5; i = (i==4 ? 0 : i+1), j = (i==4 ? j+1 : j))
{
x[i][j] = rg.nextInt();
}
Although, I prefer unwind's solution.
I got curious and did a benchmark.
For Suns HotSpot 64 server jvm on Linux, both nested loops and unwrapped loops were more or less equally fast, and almost as fast as iterating over a linear array of [size*size]. The unwrapped loop where infact slowe than the nested loop, probably because it does some more math.
However, On IBMs jdk 1.5 32 bit on Windows, the nested loop is more than 10x slower.
Though, I am not sure if its the compiler or the jvm that matters in this case, the slower test was compiled using IBMs RAD wich is some year older than eclipse 3.4
So the only reason to mess up your code with these optimizations would be if you are stuck on an "enterprisy" platform with an old jvm and and compiler, and it's really really time critical.
the nested loops will be extremely fast once the hotspot compiler runs them a few times..
see this excellent article for an explanation.
Shortest solution
int i = 0,j=0;
for(;j<5;j+=i==4?1:0,i++){
if(i==5)
i=0;
x[j][i] = rg.nextInt();
}
int q = 5, r= 5;
int [][] x = new int [q][r]
for(int i = 0; i < q * r; i++)
{
int xaxis = i / q;
int yaxis = i / r;
x[xaxis][yaxis] = rg.nextInt();
}
Though I don't know why you'd want to... you still have the same number of iterations
and this is IMHO more difficult to read and requires more mathematical calculations to run, so it's probably slower if you profile it