Incorrect output- Why? - java

Write a method named randomWalk that performs a random one-dimensional walk, reporting each position reached and the maximum position reached during the walk. The random walk should begin at position 0. On each step, you should either increase or decrease the position by 1 (with equal probability). The walk stops when 3 or -3 is hit. The output should look like this:
position = 0
position = 1
position = 0
position = -1
position = -2
position = -1
position = -2
position = -3
max position = 1
My code:
public static void randomWalk() {
Random rand = new Random();
int position = 0;
int max = 0;
System.out.println("position = " + position);
while (position != 3 && position != -3) {
int randomNumber = rand.nextInt(2) * 2 - 1;
position = position - randomNumber; //why the minus?
max = Math.max(max , position);
System.out.println("position = " + position);
}
System.out.println("max position = " + max);
}
I initially had the plus sign instead of the minus sign, and 3 out 4 outputs were incorrect (image attached). Is it something to do with the output console or is my code somewhere wrong?

I initially had the plus sign instead of the minus sign, and 3 out 4 outputs were incorrect (image attached). Is it something to do with the output console or is my code somewhere wrong?
It was not "incorrect", given the requirements that we know of. The max variable tracks the maximum value that was reached. It's inevitably a positive number. The highest positive number reached was 1 before reaching the -3 exit condition.
Your implementation works equally well regardless of plus or minus randomNumber. Just the direction of the walks will be flipped, that's all. You can observe this easily by initializing the Random instance with a seed, for example new Random(1), and then try a run with plus and minus. One of them will reach 3 and the other -3, taking opposite directions at every step.
On a second read I see now that you're probably running the program through some kind of judge system, and by "incorrect", you mean the printed values are opposites of what's expected by this judge. Changing the plus minus sign fixes that, for the reason I explained above. Whichever sign you use, I don't think your program is incorrect. The hidden requirement to use a specific sign is unreasonable and unnatural, as whether you plus or minus is irrelevant in terms of the principle of random walks.

Related

How to find the point that gives the maximum value fast? Java or c++ code please

I need a fast way to find maximum value when intervals are overlapping, unlike finding the point where got overlap the most, there is "order". I would have int[][] data that 2 values in int[], where the first number is the center, the second number is the radius, the closer to the center, the larger the value at that point is going to be. For example, if I am given data like:
int[][] data = new int[][]{
{1, 1},
{3, 3},
{2, 4}};
Then on a number line, this is how it's going to looks like:
x axis: -2 -1 0 1 2 3 4 5 6 7
1 1: 1 2 1
3 3: 1 2 3 4 3 2 1
2 4: 1 2 3 4 5 4 3 2 1
So for the value of my point to be as large as possible, I need to pick the point x = 2, which gives a total value of 1 + 3 + 5 = 9, the largest possible value. It there a way to do it fast? Like time complexity of O(n) or O(nlogn)
This can be done with a simple O(n log n) algorithm.
Consider the value function v(x), and then consider its discrete derivative dv(x)=v(x)-v(x-1). Suppose you only have one interval, say {3,3}. dv(x) is 0 from -infinity to -1, then 1 from 0 to 3, then -1 from 4 to 6, then 0 from 7 to infinity. That is, the derivative changes by 1 "just after" -1, by -2 just after 3, and by 1 just after 6.
For n intervals, there are 3*n derivative changes (some of which may occur at the same point). So find the list of all derivative changes (x,change), sort them by their x, and then just iterate through the set.
Behold:
intervals = [(1,1), (3,3), (2,4)]
events = []
for mid, width in intervals:
before_start = mid - width - 1
at_end = mid + width
events += [(before_start, 1), (mid, -2), (at_end, 1)]
events.sort()
prev_x = -1000
v = 0
dv = 0
best_v = -1000
best_x = None
for x, change in events:
dx = x - prev_x
v += dv * dx
if v > best_v:
best_v = v
best_x = x
dv += change
prev_x = x
print best_x, best_v
And also the java code:
TreeMap<Integer, Integer> ts = new TreeMap<Integer, Integer>();
for(int i = 0;i<cows.size();i++) {
int index = cows.get(i)[0] - cows.get(i)[1];
if(ts.containsKey(index)) {
ts.replace(index, ts.get(index) + 1);
}else {
ts.put(index, 1);
}
index = cows.get(i)[0] + 1;
if(ts.containsKey(index)) {
ts.replace(index, ts.get(index) - 2);
}else {
ts.put(index, -2);
}
index = cows.get(i)[0] + cows.get(i)[1] + 2;
if(ts.containsKey(index)) {
ts.replace(index, ts.get(index) + 1);
}else {
ts.put(index, 1);
}
}
int value = 0;
int best = 0;
int change = 0;
int indexBefore = -100000000;
while(ts.size() > 1) {
int index = ts.firstKey();
value += (ts.get(index) - indexBefore) * change;
best = Math.max(value, best);
change += ts.get(index);
ts.remove(index);
}
where cows is the data
Hmmm, a general O(n log n) or better would be tricky, probably solvable via linear programming, but that can get rather complex.
After a bit of wrangling, I think this can be solved via line intersections and summation of function (represented by line segment intersections). Basically, think of each as a triangle on top of a line. If the inputs are (C,R) The triangle is centered on C and has a radius of R. The points on the line are C-R (value 0), C (value R) and C+R (value 0). Each line segment of the triangle represents a value.
Consider any 2 such "triangles", the max value occurs in one of 2 places:
The peak of one of the triangle
The intersection point of the triangles or the point where the two triangles overall. Multiple triangles just mean more possible intersection points, sadly the number of possible intersections grows quadratically, so O(N log N) or better may be impossible with this method (unless some good optimizations are found), unless the number of intersections is O(N) or less.
To find all the intersection points, we can just use a standard algorithm for that, but we need to modify things in one specific way. We need to add a line that extends from each peak high enough so it would be higher than any line, so basically from (C,C) to (C,Max_R). We then run the algorithm, output sensitive intersection finding algorithms are O(N log N + k) where k is the number of intersections. Sadly this can be as high as O(N^2) (consider the case (1,100), (2,100),(3,100)... and so on to (50,100). Every line would intersect with every other line. Once you have the O(N + K) intersections. At every intersection, you can calculate the the value by summing the of all points within the queue. The running sum can be kept as a cached value so it only changes O(K) times, though that might not be posible, in which case it would O(N*K) instead. Making it it potentially O(N^3) (in the worst case for K) instead :(. Though that seems reasonable. For each intersection you need to sum up to O(N) lines to get the value for that point, though in practice, it would likely be better performance.
There are optimizations that could be done considering that you aim for the max and not just to find intersections. There are likely intersections not worth pursuing, however, I could also see a situation where it is so close you can't cut it down. Reminds me of convex hull. In many cases you can easily reduce 90% of the data, but there are cases where you see the worst case results (every point or almost every point is a hull point). For example, in practice there are certainly causes where you can be sure that the sum is going to be less than the current known max value.
Another optimization might be building an interval tree.

Validate if numbers are valid within a given range, depending on used pre-selection

I'm writing a program that generates n number of bonuses, it does well but when it comes to generate their id numbers i am stuck. The program at that point needs the user to tell the program a Min value and a Max value between 10000 and 10000, until there no problem all easy.
The part after it is making me scratch my head because the program needs to know how many numbers can be generated at a given position of the value generated so it's not a fixed range, the ids generated must and only include the numbers that the user specified for every x position and it has to know that so when it's reading the values that are going to be used for that purpose, they get verified for it's corresponding position.
I have tried to use some some conditions for some cases that i have identified within the working program, but i'm actually stuck because it seems like ill have to build a lot of if statements to contain all of the possible types of ids that can occur.
// from left to right the "positions"
int min = 1 0 0 0 0;
int max = 1 0 9 9 9;
int temp = max - min;
// tells how many different digits can be used from 1 to 10 for each position (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
// leftmost position aka first
delta[0] = temp / 10000;
// aka second position
delta[1] = (temp % 10000) / 1000;
// aka third position
delta[2] = ((temp % 10000) % 1000) / 100;
// aka fourth position
delta[3] = (((temp % 10000) % 1000) % 100) / 10;
// aka fifth position
delta[4] = ((((temp % 10000) % 1000) % 100) % 10);
these formulas work as expected, however when a given position resets there is no way for the formulas to say "you can include all 10 digits on this position because it's not just 0, it's 10000 to 10999".
[EDIT]
To clarify the question above, i am required by my teacher to do the following in order to generate the bonuses id numbers:
ask the user a range (inclusive) between 10000 and 99999. this means that i can only generate 5 digit ids for a given amount of bonuses, they should not repeat.
also ask the user numbers allowed for every position within that 5 digits range given, i.e. my range goes from 12000 to 22000, from left to right of the 5 digits that can be generated user says that he only wants the number 1 to appear so that now limits my ids to generate to values from 12000 to 19999... but he can also say that he only wants the number 2 to be at that particular position so the opposite might happen as well (from 20000 to 22000 ids are only possible to be used). this applies for all 5 digits that can be generated at any given range between min and max.
It would be much, much simpler to keep a List of numbers, generate your ids randomly, and compare, like so:
public class IdGenerator {
private static List<Integer> usedIds = new ArrayList<>();
... (other fields and methods here)
public int generateNumber() {
// Check if all ids are used. (Redesign your ID scheme to prevent this situation, otherwise you'll run out of IDs and your application will stop working.
if (usedIds.size() >= 1000) {
throw new IllegalStateException("All allowable IDs used, please free up an ID to continue generation.");
}
// Generate a random ID with a value between 10000 and 10999.
int idCandidate = ThreadLocalRandom.current().nextInt(10000, 10999 + 1);
// ID in use, try again with new number.
if (usedIds.contains(idCandidate) {
return generateNumber();
}
// ID is not taken and can therefore be saved.
usedIds.add(idCandidate);
return idCandidate;
}
}
Even better would to be to use UUIDs, since they are more or less guaranteed to be unique.

I want to generate four Different Random Numbers in android But Their total should not be Greater Than the Specified range like 0 to 69

This my Button OnClick() Method on Click of the button All Four random numbers will be Displayed on the Logcat
public void onClick(View v) {
/* the Code for Four Random Numbers*/
final Random random = new Random();
final Set<Integer> mySet = new HashSet<>();
while (mySet.size() < 4) {
mySet.add(random.nextInt(69) + 1);
}
// Now Adding it to the ArrayList
ArrayList<Integer> Elements = new ArrayList<>(mySet);
Log.i("Elements","A:" + Elements.get(0));
Log.i("Elements","B:" + Elements.get(1));
Log.i("Elements","C:" + Elements.get(2));
Log.i("Elements","D:" + Elements.get(3));
}
});
The Output Will be Look Like this (I just give an Example of one case It is Different in every case Whenever I run a App)
A : 11
B : 28
C : 57
D : 1
Now the Problem is :
The sum of all the numbers is greater than the specified range which is 0 to 69
When We Add A,B,C,D values which is equals to 97
Which is greater than the Specified Range 0 to 69
So I Want the Random Numbers in such a way that :
when we Add A,B,C,D the their Sum Should no Exceed the Range that is 69
So My Question is How can i Do That ?
Please Help!! I am Stuck in that part of the Code
and I find no Solution
In addition to what other people have suggested, you might want to read this: find all subsets that sum to a particular value
First, note that this bears some resemblance to the subset sum problem. Given the set of all numbers between 1 and 69, you're looking for a subset of 4 of them that adds up to 69. For any natural number, there are only a finite number of such sets (although it obviously eventually gets computationally infeasible to enumerate all of them). Either way, your answer is guaranteed to be one of these sets regardless of what algorithm you use.
The linked question shows code to find all of the subsets that add up to a particular value. Once you have this, just filter on all the subsets that have length 4 and randomly pick one of them.
There are two ways, depending on how you want to do it:
Rereoll the random numbers until a valid sum is achieved. This will be truly random.
Change the max value for the 2nd, 3rd, 4th, etc random number so that it can't be too big. However this will change it from every number being equally likely to smaller numbers being more likely.
This is a tricky question. These is no mention of a sample space, so one can assume it has to be valid integer of sorts. Generate any number of a number signed 32 bit integer. This would be –2147483648 and 2147483647 until you have four unique ones which sum is between 0 and 69.
Best of luck!
you can use this code :
final Random random = new Random();
final Set<Integer> mySet = new HashSet<>();
int thesum = 0 ;
while (mySet.size() < 4 && thesum< 69) {
int nmbr = random.nextInt(69) + 1 ;
thesum = thesum + nmbr ;
mySet.add(nmbr) ;
}
if( mySet.size() == 3)
{ArrayList<Integer> Elements = new ArrayList<>(mySet);
Log.i("Elements","A:" + Elements.get(0));
Log.i("Elements","B:" + Elements.get(1));
Log.i("Elements","C:" + Elements.get(2));
Log.i("Elements","D:" + Elements.get(3));}

Solving a challenge in JAVA. The challenge is mentioned below in the description. The logical bug I am facing is also in the description below

Lukáš really likes orienteering, a sport that requires locating control points in rough terrain. To entertain the NWERC participants Lukáš wants to organize an orienteering race. However, it would be too harsh for the participants to be outdoors in this cold Swedish November weather, so he decided to jump on the new trend of indoor races, and set the race inside the B building of Linköping University.
Lukáš has already decided on the locations of the control points. He has also decided on the exact length of the race, so the only thing remaining is to decide in which order the control points should be visited such that the length of the total race is as he wishes. Because this is not always possible, he asks you to write a program to help him.
Input Format
The input consists of:
one line with two integers n (2 ≤ n ≤ 14) and L (1 ≤ L ≤ 1015), the number of control points and the desired length of the race, respectively;
n lines with n integers each. The jth integer on the ith line, dij , denotes the distance between control point i and j (1 ≤ dij ≤ L for i 6= j, and dii = 0). For all 1 ≤ i, j, k ≤ N it is the case that dij = dji and dij ≤ dik + dkj .
Output Format
Output one line with “possible” if it is possible to visit all control points once in some order and directly return to the first one such that the total distance is exactly L, and “impossible” otherwise.
Sample Input
3 5
0 1 3
1 0 3
4 1 0
Sample Output
possible
The problem with the code is that the for loop in else loop of function checkscenario() only considers the first iteration and returns false as a result. It doesn't check the next iteration which will return true and thus give the proper solution.
Lets use the sample input for the explanation. Initially, the function gets value of the parameters as follows :-
controlptsleft = {0,1,2,3}
//These are the control pts which haven't been visited.
index = 0;
//This is the control pt that I am at.
controlmatrix =
0 1 3
1 0 3
4 1 0
L = 5
//The desired length.
sum = 0
//Till now we haven't trailed the control pts. So, sum = 0.
public static boolean checkscenario(ArrayList<Integer> controlptsleft, int index, int[][] controlmatrix, int L, int sum){
int row = controlptsleft.get(index);
//row stores the value in the ArrayList controlptsleft at the index.
controlptsleft.remove(index);
//The controlpt is removed. The first time 0 will be removed from arrayList controlptsleft.
if(controlptsleft.isEmpty()){
//When the ArrayList controlptsleft is empty, we have to go back to the first controlflag.
int temp = controlmatrix[row][0];
//temp stores the distance between the control flag where we are at and the starting control flag.
if(L == (sum + temp))
return true;
}
else{
for(int i=0;i<controlptsleft.size();i++){
int temp = controlmatrix[row][controlptsleft.get(i)];
//temp stores the distance between the control flag where we are at and the whatever controlflag we get during the iteration.
ArrayList<Integer> tempList = controlptsleft;
boolean finalres = checkscenario(tempList,i,controlmatrix,L,(sum + temp));
//Here, i is sent so that when it enters the function again the index i (along with the value) in ArrayList tempList will be deleted.
if(finalres)
return true;
}
}
return false;
}
Just in case someone out there wants to know, I figured out the answer for this challenge.
First of all, i would like to thank Hanno Binder for that comment. I realized where I went wrong.
Inside the else loop of the function checkscenario
else{
for(int i=0;i<controlptsleft.size();i++){
int temp = controlmatrix[row][controlptsleft.get(i)];
ArrayList<Integer> tempList = controlptsleft;
boolean finalres = checkscenario(tempList,i,controlmatrix,L,(sum + temp));
if(finalres)
return true;
}
What I did was, I directly copied the reference of controlptsleft to tempList. I realized the bug and I instead initialized tempList and used .addAll to put all the values from controlptsleft to tempList.
The following code illustrates what I meant above.
else{
for(int i=0;i<controlptsleft.size();i++){
int temp = controlmatrix[row][controlptsleft.get(i)];
ArrayList<Integer> tempList = new ArrayList<Integer>();
tempList.addAll(controlptsleft);
boolean finalres = checkscenario(tempList,i,controlmatrix,L,(sum + temp));
if(finalres)
return true;
}
}
If someone has a better solution in JAVA for the challenge mentioned above. Feel free to post their code, so I could learn how to code better.

Can someone please explain how this implementation works? Also, can it be made better? How?

public class Main {
public static void main(String args []){
long numberOfPrimes = 0; //Initialises variable numberOfPrimes to 0 (same for all other variables)
int number = 1;
int maxLimit = 10000000;
boolean[] sieve = new boolean[maxLimit]; //creates new boolean array called sieve and allocates space on the
//stack for this array which has maxLimit spaces in it
for ( int i = 2; i < maxLimit; i++ ) { //for statement cycling from 2 to 10000000, does not execute the rest
//of the block if the boolean value in the array is true
if ( sieve[i] == true ) continue;
numberOfPrimes++; //otherwise it increments the number of prime numbers found
if ( numberOfPrimes == 10001 ) { //if 10001st prime number is found, break from loop
number = i;
break;
}
for ( int j = i+i; j < maxLimit; j += i ) //do not understand the point of this loop logically
sieve[j] = true; //testing if the value in the array is true again?
}
System.out.println("10001st prime: "+ number);
}
}
I don't really understand what is going on in this program and was hoping somebody could explain it to me? I have commented the specific lines causing me trouble/what I understand lines to be doing. Thank you very much for all the help! :)
Make yourself familiar with Eratosthenes' Sieve algorithm. Wikipedia even has animated gif demonstrating the process. And your code is just a straightforward implementation of it.
Yes, this is your basic implementation of Eratosthenes' Sieve. There are quite a few ways in which you can improve it, but let's go over the basic principle first.
What you are doing is creating an array of boolean values. The INDEX in the array represents the number which we are testing to see if it is a prime or not.
Now you are going to start checking each number to see if it is a prime. First off, the definition of a prime is "all numbers divisible ONLY by itself and 1 without fractioning".
for ( int i = 2; i < maxLimit; i++ )
You start with the INDEX 2 (the number 3) because depending on your definition, 1 and 2 are always prime. (Some definitions say 1 is not a prime).
if ( sieve[i] == true ) continue;
If a number has been marked as a non-prime previously, we don't bother with the current iteration.
numberOfPrimes++;
if ( numberOfPrimes == 10001 ) {
number = i;
break;
}
If the INDEX we are at currently has not been marked as being a prime, it has to be one, so we increment the number of primes we have found. The next piece of code I'm assuming is part of the requirements of the program which states that if 10001 primes have been found, the program must exit. That part can be left out if you actually want to check for primes up to the maximum number defined in stead of for a specific number of primes.
for ( int j = i+i; j < maxLimit; j += i )
sieve[j] = true;
This is where the actual magic of the sieve starts. From the definition of a prime, a number cannot be a prime if it is divisible by anything other than itself and 1. Therefore, for any new number we find that is a prime, we can mark all it's factors as NOT being prime. For example, the first iteration of the for loop, we start with 3. Because sieve[2] is false (have not visited before), it is a prime (AND 3 IS A PRIME!). Then, all other factors of 3 CANNOT be primes. The above mentioned for loop goes through the entire sieve and marks all factors of 3 as false. So that loop will do: sieve[5] = true; sieve[8] = true ... up until the end of the sieve.
Now, when you reach the first number greater than the maximum defined initially, you can be certain that any number that has a factor has been marked as not being a prime. What you end up with is a boolean array, where each index marked as false, represents a prime number.
You can probably get a much better description on wikipedia, but this is the jist of it. Hope it helps!
for ( int j = i+i; j < maxLimit; j += i ) //dont understand the point of this loop logically
sieve[j] = true; //testing if the value in the array is true again ?
This is not a testing, but rather a setting. This loop is setting all the items in the array with indexes multiple of i to true. When i is 2, then the items 4, 6, 8 ... will be set to true. When i is 3, the items 6, 9, 12 ... will be set to true and so on.
And as you can deduce by the first if,
if ( sieve[i] == true ) continue;
... all the items that are true correspond to non-prime numbers.
I find the easiest way to understand something is to deconstruct it. Therefore, lets go through the loop a few times, shall we?
Dawn of the First Iteration
− 9999998 Values Remain −
i = 2
sieve[2] is false, so we keep going in the current iteration.
numberOfPrimes = 1 and thus we continue processing
Set every multiple of 2 to true in sieve[].
Dawn of the Second Iteration
− 9999997 Values Remain −
i = 3
sieve[3] is false, so we keep going in the current iteration.
numberOfPrimes = 2 and thus we continue processing
Set every multiple of 3 to true in sieve[].
Dawn of the Third Iteration
− 9999996 Values Remain −
i = 4
sieve[4] is true (from first iteration). Skip to next iteration.
etc... but in this case, the moon doesn't crash into Termina.
The loop in question isn't checking for true values, it's setting true values.
It's going through each multiple of the prime and marking it as non-prime up to maxLimit. You'll notice there's no other math in the code to determine what's prime and what's not.
This is the algorithm to find the prime numbers between 1 and the maximum limit given.
And the loop added 2nd is to make true for the number which is divisible by any other number. so for the first outer loop all the number divisible by two ll be set to true then divisible by 3 then by 4 and so on.. and the numbers for which the boolean array contains false are the prime numbers.

Categories