i am trying to make my algorithm more efficient but for some reason its not working correctly could someone tell me if my logic is correct. The general problem is that if u have a height of 'x', and you can jump 'u' distance but you fall 'd' distance if you havent cleared the height already. i have to calculate the number of jumps.
Initial code works correctly
while(x-u>0) {
x=x-u+d;
i++;
}
i++;
more efficient code (for some reason fails some cases, I don't know which cases though)
int k=u-d;
if(x-u<=0){
i++;
} else {
int z=x/k;
if (x-((z-1)*k)-u <= 0) {
i+=z;
} else {
i=i+z+1;
}
}
let me try and clarify the problem you have a wall of height X, you can jump up distance U but every time you jump you also slip down distance D.
so lets say if u have a wall of height x=4, u=4, d=1. Then you would only have to jump once because the first time you jump you have cleared the wall, so you dont slip down at all. now lets say x=6, u=4,d=1. Then you would have to jump twice because the first time you would jump up to 4 but fall 1 so you are at 3 then the next jump you clear the wall.
Okay, let's see. The last jump comes from the height of x - u or higher. The rest you have to cover in (u - d)-size steps, the number of such steps is of course (x - u)/(u - d).
After i-th step you are at height i * (u - d) + u (and falling down). So, in approx. (x - u)/(u - d) steps you are at height x - u + u = x. Recalling that the number of steps should be a whole number, we get the final result:
if (u >= x)
return 1;
if (u <= d)
throw "Impossible";
return ceil((x - u)/(u - d));
(ceil is a mathematical function returning the smallest integer not less than the given number.)
Related
I'm trying to write a Java program to calculate the square root of an integer x, without using in-built functions like Math.pow() . This is the approach I tried -
class Solution {
public int mySqrt(int x) {
if(x==0 || x==1)
return x;
// if(x>=2147395600)
// return 46340;
int i;
for(i=1 ; i*i<=x ; i++) {}
return i-1;
}
}
Without the commented part, I start getting errors if x is in the range 2147395600 <= x <= 2^31-1 (which is the upper limit of an int's value range in Java). For instance, for the input x=2147395600, the expected output is 46340 but the actual output is 289398. Why is this happening? Thanks to all in advance.
PS - I am aware there are other (better) methods to solve this problem, but I'd really like to know why this code behaves this way.
Since 46340 * 46340 = 2147395600, when i=46340, x=2147395600 and you reach the condition i*i<=x it evaluates to true since 2147395600 = 2147395600. So the loop counter will incremnet by 1 and in the next iteration we will get i=46341 and i * i will cause an overflow - 46341*46341 = -2147479015.
The loop condition will still be true, since -2147479015 <= 2147395600, and the loop will not stop.
You can replace the <= with =, and check for edge cases that may occur now.
I creating pacman game. I have array of size 15x15, total 225fields. When I move from 255 to i.e.256, I got ArrayIndexOutOfBoundsException, this makes sense. So I can catch it and do some operation, lets say I set new starting point of pacman. But if I go from field 75 to 74 nothing happened.
So I asking, can I somehow catch this and do some operation, like I mention above.
You should not rely on ArrayIndexOutOfBoundsException for normal logic. This exception is an indication of a programming error.
Instead, you should check the index before incrementing it:
if (currentIndex == 255) {
// "special logic"
} else {
// "usual logic"
}
This way you can also handle any "special" indexes, e.g.
if ((currentIndex + 1) % 15 == 0) {
// "special logic"
} else {
// "usual logic"
}
Another point: consider using two indexes - x and y - if you are programming a 2-D game.
Every move modifies x and/or y, which can easily "wrap around" like in pacman (e.g. 13 -> 14 -> 15 -> 1 -> 2 -> ...).
And convert the (x,y)-Pair to an index only when you need to access the field element:
// Assuming that x and y are 1-based, not 0-based:
public FieldElement getFieldElementAtPosition(final int x, final int y) {
final int index = (y - 1) * FIELD_WIDTH + x - 1;
return fieldArray[index];
}
I got a question in interview about a man who can take a step back or move double of his current distance . Considering each of them as a single move find minimum moves he can take to reach y from x.
import java.util.*;
import java.io.*;
public class Main
{
public static int Solve(int x,int y)
{
if(x==0)
{
return Integer.MAX_VALUE;
}
else if(x==y)
{
return 0;
}
else if(x==1)
{
return 1+Solve(x*2,y);
}
return Math.min(1+Solve(x*2,y),1+Solve(x-1,y));
}
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
int x=sc.nextInt();
int y=sc.nextInt();
int z=Solve(x,y);
System.out.print(z);
}
}
This is an infinite loop. At what place will Solve( x * 2, y) ever
stop ?
Assuming all this is in one axis only (1D), since you defined int x and int y. Let’s say we have x and y, if y-x is positive, that means we have to go forward. Now if y-x is odd, let’s say 7 that means we have to go 8 steps (4*2) ahead, then 1 (1 step) back. Giving us 5 steps. So we have to go
(((y-x) + 1)/2) + 1
So 7+1 = 8, we go 8 steps ahead taking double steps, then 1 more step to come back.
If it is even, then that means we can go straight ahead ! So
(y-x)/2
If y-x is negative, which means we have to go back. Only way is 1 step back (x-1), so that will just be
-(y-x) steps.
You can write the code. I like the recursion aspect for your code, but it’s an overkill if it is 1D.
Not sure if a recursion-based solution is needed here.
We have two subproblems here:
count moves back when from >= to
otherwise count moves forward taking into account a case when difference to - from is odd: then 1 extra move forward is needed and 1 step back.
This can be resolved with the help of a ternary operator:
public static int findMoveCount(int from, int to) {
return from >= to ? from - to : (to - from) % 2 * 2 + (to - from)/2;
}
I have a problem with sequentially searching, this is the exercise:
You are testing the physical endurance of a type of brick. The test is made to find the max height the brick can fall without breaking from and N stories building. You have k bricks and two cases:
Case 1. When k = 1 the tries begin from the current floor upwards, sequentially, until the brick breaks.
Case 2. For k > 1 one brick is dropped from floor N/2. If it breaks, case 2 is applied again between floors 1 and N/2 -1. If the brick does not break, case 2 is applied again between floors N/2 + 1 and N.
I have a problem with the CASE 1 cause as I don't know how to approach it:
Initially you call dropBricks(k,1,N); Being k, and N introduced by the User(Keyboard).
public static boolean breakingFloor(int floor){
boolean breaks;
Random r =new Random();
int breakingFloor= r.nextInt(floor)+1;
if(floor>=breakingFloor){
breaks=true;
}else{
breaks=false;
}
return breaks;
}
dropBricks receives k(number of remaining bricks, first (first floor),last (last floor = N)) and the output would be the breakingFloor
public static int dropBricks(int k,int first,int last){
int result=0;
if (k==1){//CASE 1
//I KNOW THIS CODE IS WRONG, IS JUST O NOT LEAVE IT IN EMPTY
do{
dropBricks(k,first,last);
first++;
}while(breakingFloor(first));
System.out.println("Floor brick broke "+floor);
}else{//CASE 2
if(last-first<=1){
if(last==first){
result=first;
System.out.println("Floor brick broke "+result);
}else{
if(breakingFloor(first)){
result=first;
k--;
System.out.println("Floor brick broke "+result);
}else{
result=last;
k--;
System.out.println("Floor brick broke "+result);
}
}
}else{
int mid=((first+last)/2);
if(breakingFloor(mid)){
result=dropBricks(k-1,first,mid);
System.out.println("Floor brick broke "+result);
}else{
result=dropBricks(k,mid,last);
System.out.println("Floor brick broke "+result);
}
}
}
return result;
}
Your issue - or at least one of them - is that every time you go around this loop...
do{
dropBricks(k,first,last);
first++;
} while( breakingFloor(first) );
... you are choosing a new random floor at which it will break (which happens in the breakingFloor method):
Random r =new Random();
int breakingFloor= r.nextInt(floor)+1;
This will definitely give you very inconsistent behaviour. It may actually work some of the time by a fluke.
You want to choose the floor at which it will break at the start and for it to remain constant.
A sensible way to test your application might be to hard-code a breaking floor to start with and then introduce the randomness later.
Your first issue is here:
int breakingFloor= r.nextInt(floor)+1;
That simply doesn't make sense. The floor number on which a brick will break is not random.
In other words: you want to assign a random number once for that brick. And then your algorithm has to find that number! Your code changes that "breaking floor number" while your algorithm tries to find that number. This makes the whole process useless (and of course; "random"; as all kinds of things can happen).
So the first step on your side: step back, and re-think the problem, and what "solving" the problem really asks you to do.
Problem: move an object along a straight line at a constant speed in the Cartesian coordinate system (x,y only). The rate of update is unstable. The movement speed must be close to exact and the object must arrive very close to the destination. The line's source and destination may be anywhere.
Given: the source and destination addresses (x0,x1,y0, y1), and a speed of arbitrary value.
An asside: There is an answer on the SO regarding this, and it's good, however it presumes that total time spend traveling is given.
Here's what I've got:
x0 = 127;
y0 = 127;
x1 = 257;
y1 = 188;
speed = 127;
ostrich.x=x0 //plus some distance along the line;
ostrich.y=y0 // plus some distance along the line;
//An arbitrarily large value so that each iteration increments the distance a minute amount
SPEED_VAR = 1000;
xDistPerIteration = (x1 - x0) / SPEED_VAR;
yDistPerIteration = (y1 - y0) / SPEED_VAR;
distanceToTravel = ;//Pythagorean theorum
limitX = limit1 = 0; //determines when to stop the while loop
//get called 40-60 times per second
void update(){
//Keep incrementing the ostrich' location
while (limitX < speed && limitY < speed) {
limitX += Math.abs(xDistPerIteration);
limitY += Math.abs(yDistPerIteration);
ostrich.x += xDistPerIteration;
ostrich.y += yDistPerIteration;
}
distanceTraveled -= Math.sqrt(Math.pow(limitX, 2) + Math.pow(limitY, 2));
if (distanceTraveled <=0)
//ostrich arrived safely at the factory
}
This code gets the job done, however it takes up exclusively 18% of program time in a CPU intensive program. It's garbage, programatically and in terms of performance. Any ideas on what to do here?
An asside: There is an answer on the
SO regarding this, and it's good,
however it presumes that total time
spend traveling is given.
basic physics to the rescue
total time spent traveling = distance/speed
btw Math.hypot(limitX,limitY) is faster than Math.sqrt(Math.pow(limitX, 2) + Math.pow(limitY, 2))
though really it's that while loop you should refactor out
One thing to improve is:
There is no need to compute the square root in each call to the update function. You may use the squared distanceTraveled instead.
Similarly, Math.abs(xDistPerIteration) and Math.abs(yDistPerIteration) do not change at each call to update, you may save those values and get rid of the calls to the absolute value function in order to bit a save a bit more computing time.
Update gets called 40-60 times per second, right? In other words, once per frame. So why is there a while loop inside it?
Also, doing sqrt once, and pow twice, per frame is unnecessary.
Just let d2 be the distance squared, and stop when limitX*limitX+limitY*limitY exceeds it.