So I decided to try out Codility. The first task - FrogJmp was ridiculous easy, however to my surprise I scored 44%. Solution, even if correct was obviously unacceptable in terms of performance.
Original solution:
public int solution2(int X, int Y, int D) {
return (int) Math.ceil((float)(Y -X)/D);
}
So I decided to try it with different code, without floating point arithmetic.
public int solution(int X, int Y, int D) {
int diff = Y - X;
if (diff % D == 0)
return diff /D;
else
return diff/D + 1;
}
This time I got 100%. So I wanted to check the performance myself and wrote simple test:
class Solution {
public int solution(int X, int Y, int D) {
int diff = Y - X;
if (diff % D == 0)
return diff /D;
else
return diff/D + 1;
}
public int solution2(int X, int Y, int D) {
return (int) Math.ceil((float)(Y -X)/D);
}
private static Random ran = new Random(System.currentTimeMillis());
public static int getRandom(int a, int b){
return ran.nextInt(b - a + 1) + a;
}
public static void main(String[] args) {
int size = 1000_000;
int max = 1000_000_000;
int[] xs = new int[size];
int[] ys = new int[size];
int[] ds = new int[size];
for (int i = 0; i < size; i++) {
int y = getRandom(1, max);
int x = getRandom(1, y);
int d = getRandom(1, max);
xs[i] = x;
ys[i] = y;
ds[i] = d;
}
long start = System.nanoTime();
Solution sol = new Solution();
for (int i = 0; i < size; i++) {
sol.solution2(xs[i], ys[i], ds[i]);
}
long diff = System.nanoTime() - start;
System.out.println("took: " + diff/1000000 + "ms");
}
}
To my surprise, on my machine the solution 1 takes on average 13ms and solution 2 (the one reported as absolutely ineffective) 10 ms.
What am I missing?
Maybe it has to do something with expected time and space complexity of the tasks.
expected worst-case time complexity is O(1); expected worst-case space
complexity is O(1).
Does not solution 2 have constant time & space complexity?
Also I cannot make sense of this results report for 44% solution:
What does it mean??
100/100 solution in C# I just
using System;
class Solution {
public int solution(int X, int Y, int D) {
return ((Y - X) + D - 1)/D;
}
}
Solution in Java 100/100 and O(1) time complexity.
public int solution(int X, int Y, int D) {
return Double.valueOf(Math.ceil((Y - X) / (double) D)).intValue();
}
Both solutions have O(1) time complexity. The problem is that the first solution is returning wrong answers. The performance tests test the answer as well as the time. Your solution failed probably because of precision issues with the use of floats.
For x = 1, y = 1000000000, d = 1, your first solution gives 1000000000 as an answer, and the second gives
999999999. Changing from (float) to (double) corrects this result.
In these algorithm tests, it's usually a good idea to avoid floating point arithmetic as much as possible to make it easier to get the exact answers for all cases.
OBJECTIVE-C SOLUTION O(1)
Results given by Codility
Task Score: 100%
Correctness: 100%
Performance: 100%
Time Complexity
The worst case time complexity is O(1)
Xcode Solution Here
+(int)solution:(int)x y:(int)y d:(int)d {
/******** Algorithm Explanation ********/
// FACTS
// I realized that the formula: [x+(n*d)] >= y satisfies the required frog jumps
// then, the formula to find the 'n' required jumps is the following:
// n = (y-x)/d
// STEP 1
// Implement the formula in code
// Be careful dealing with the floating point, it should be double
// use the function 'ceil' as a resource to round to the next integer.
double n = ((double)y - (double)x) / (double)d; // O(1)
n = ceil(n);
return (int)n;
}
Solution in Java 100/100 and O(1) time complexity:
public int solution(int X, int Y, int D) {
int diff = Y - X;
int count = diff / D;
if (diff % D > 0) {
count++;
}
return count;
}
JS Solution
Task Score: 100%
Correctness: 100%
Performance: 100%
function solution(X, Y, D) {
return Math.ceil((Y - X) / D);
}
Solution in C#
double result = (Y - X) / (D * 1.0);
return Convert.ToInt32(Math.Ceiling(result));
public static int solution(int X, int Y, int D) {
// write your code in Java SE 8
return (int)Math.round((Y-X)/(double)D);
}
This will also fetch 100%
Tried this one for 100/100
public static int frogJmp(int X, int Y, int D) {
return (int) Math.ceil( (Y-X) / (double)D );
}
Simple O(1) solution in Java:
class Solution {
public int solution(int X, int Y, int D) {
return (Y-X) % D == 0 ? (Y-X) / D : (Y-X) / D + 1;
}
}
Count minimal number of jumps from position X to Y.
public int solution(int X, int Y, int D) {
if (X == Y)
return 0;
else if ((Y - X) % D == 0)
return ((Y - X) / D);
else
return ((Y - X) / D) + 1;
}
First, you should pay attention to divisor which can not be 0 in your case "diff / D", D can not be 0.
Second, in your case "diff = Y - X", if ( diff <= 0 ) then you don't to jump anymore.
Frogjump solution in C
int solution(int X, int Y, int D) {
// write your code in C90
int r=0;
if(Y>X)
{
r=(Y-X)/D;
if((X+(r*D)) < Y) r++;
}
return r;
}
public int solution(int X, int Y, int D) {
// write your code in C# 6.0 with .NET 4.5 (Mono)
double divAll = (Y-X) / (D * 1.0);
double finalRes = (Y-X) % (D * 1.0) > 0 ? (divAll + 1) : divAll;
return (int) finalRes;
}
Here is my 100% / 100% solution
public int solution(int X, int Y, int D) {
double d = D;
return (int) Math.ceil( (Y-X) / d );
}
I just resolved it with perfect score, So this is my answer (java):
static int solution(int X, int Y, int D){
double count=((double)Y-(double)X)/(double) D;
return (int)Math.ceil(count);
}
For the first time i thought it could be rdone by using "While loops" but i got zero performance..
Here is my simple code with detected time complexity of O(1) in Codility.
public int solution(int X, int Y, int D) {
int dev = (Y - X) % D;
if (X == Y)
return 0;
else if (dev == 0)
return (Y - X) / D;
else
return ((Y - X) / D) + 1;
}
Solution 100% in JS
function solution(X, Y, D) {
const distance = Y - X;
if (distance % D === 0) {
return Math.round(distance/D);
}
return Math.floor(distance/D +1);
}
Related
I have the task of doing a recursive pow function with complexity of O(logn) and then do the same algorithm in iterative way. The first one I think that I have it but, I'm having trouble in doing the exact same on a iterative way. I have one that is O(logn) but it's not the same one.
public static BigInteger powV2(int x, int y) {
if (y == 0) {
return BigInteger.ONE;
}
BigInteger powerOfHalfX = powV2(x, y / 2);
if (y % 2 == 0) {
return powerOfHalfX.multiply(powerOfHalfX);
} else {
return BigInteger.valueOf(x).multiply(powerOfHalfX).multiply(powerOfHalfX);
//x * powerOfHalfX * powerOfHalfX;
}
}
this is the iterative one:
public static BigInteger iterativePowV2(int x, int y) {
BigInteger result = BigInteger.ONE;
while (y > 0) {
if (y % 2 == 1) {
result = result.multiply(BigInteger.valueOf(x));
}
y = y >> 1; //y = y/2
x = x * x; //
}
return result;
}
You're very close. It appears to me that you have the correct method in both pieces of code, but slipped up slightly in the loop body of the iterative version:
x = x * x;
should be:
result = result.multiply(result)
because you want to square your running total, not the input variable. Test that out on a few small inputs to see if it works correctly!
EDIT: still didn't work, found a solution here: Iterative logarithmic exponentiation
Suppose there is a method int Multiply(int x,int y). Is it possible for this method to return product of all the integers between x and y without using loop.
For example if the method is called with 3 and 5 : Multiply(3,5) then it should return the product : 3*4*5 = 60.
Interesting question. Please find my attempt to solve this below, The assumption is x is less than or equal to y
public static int multiply(int x, int y){
if(x==y){
return x;
}
if(x == y-1){
return x*y;
}
int product = x*y;
product = product*multiply(x+1,y-1);
return product;
}
With Java 8's streams:
public static int foo (int x, int y){
int high = x > y ? x : y;
int low = x > y ? y : x;
return IntStream.rangeClosed(low, high).reduce(1, Math::multiplyExact);
}
Technically, there are no loops : )
I've having some trouble with recursion. At the moment, this code gives me an error message "missing return statement". Any way to get this working the way I want it to? I want it to calculate for xn and then return "count" when n reaches zero.
public class Question6p2 {
public static void main(String[] args){
int n = -6;
int x = 2;
int count = x;
power2(n, x, count);
System.out.println(power2(n, x, count));
}
public static int power2(int n, int x, int count){
if (n != 0){
if (n>0){
count = count * x;
n = n - 1;
}
else if (n<0) {
count = count * -x;
n = n + 1;
}
power2(n, x, count);
}
else if (n == 0){
return count;
}
}
}
Maybe I'm coming about this all wrong. Anyone care to help?
Currently, you have this statement:
power2(n, x, count);
... which ignores the result completely. In that branch, we never return anything from the method call. I suspect these two issues are linked.
I suspect you just want:
return power2(n, x, count);
Currently you are getting an error about not having a return statement because your return statement is within an if statement, so if that if statement doesn't run you will not return anything which is a problem.
Also I think you are going about recursion fundamentally wrong, as you are never calling back to your method recursively.
What you probably want to do within your power method is to accept n as the number of time to call your method, then lower it by 1 with each recursion. Then on every recursion multiply x by the original value.
Here is what I mean:
public static double power2(int n, int x,int xOriginal){
if(n == 0){
return 1;
}
if(n < 0){
return 1 / power2(n*-1, x, x);
}
if(n <= 1){
return x;
}
return power2(n -1, x * xOriginal, xOriginal);
}
Edit: Works with negative n now.
There are a few things wrong with your algorithm:
What does it mean to have a negative exponent?
You should understand that x-n can be written 1 / xn. This is not what was reflected in your algorithm.
All possible cases
There are 4 basic cases when calculating exponents.
There is any value x0 = 1.
Any x1 = x
Any negative exponent x-n = 1 / xn
Any positive exponent greater than one: xn where n > 1
Your algorithm should return 1 when x has an exponent of zero. Return x when the exponent is 1 or recursively call the algorithm when n > 1.
In the special case where n < 0 (ie you have a negative exponent) You can simply return the reciprocal 1 / method() as long as you change the sign of n before calling the method.
The line:
else if (n < 0){
n = -n;
return(1 / power2(n, x, count));
}
Checks for negative exponents, and returns 1 / xn Take note that the sign of n changed here, and now this is operating like any other method call with positive exponents.
public class TestCode {
public static void main(String[] args){
int n = 4;
int x = 5;
double count = x;
System.out.println(power2(n, x, count));
}
public static double power2(int n, int x, double count){
if (n == 0)
return 1;
else{
if (n > 1){
count = count * x;
n = n - 1;
}
else if (n < 0){
n = -n;
return(1 / power2(n, x, count));
}
else if (n == 1) {
return count;
}
return power2(n, x, count);
}
}
}
I've been trying to write a simple function in Java that can calculate a number to the nth power without using loops.
I then found the Math.pow(a, b) class... or method still can't distinguish the two am not so good with theory. So i wrote this..
public static void main(String[] args) {
int a = 2;
int b = 31;
System.out.println(Math.pow(a, b));
}
Then i wanted to make my own Math.pow without using loops i wanted it to look more simple than loops, like using some type of Repeat I made a lot of research till i came across the commons-lang3 package i tried using StringUtils.repeat
So far I think this is the Syntax:-
public static String repeat(String str, int repeat)
StringUtils.repeat("ab", 2);
The problem i've been facing the past 24hrs or more is that StringUtils.repeat(String str, int 2); repeats strings not out puts or numbers or calculations.
Is there anything i can do to overcome this or is there any other better approach to creating a function that calculates powers?
without using loops or Math.pow
This might be funny but it took me while to figure out that StringUtils.repeat only repeats strings this is how i tried to overcome it. incase it helps
public static int repeat(int cal, int repeat){
cal = 2+2;
int result = StringUtils.repeat(cal,2);
return result;
}
can i not use recursion maybe some thing like this
public static RepeatThis(String a)
{
System.out.println(a);
RepeatThis(a);
}
just trying to understand java in dept thanks for all your comments even if there were syntax errors as long as the logic was understood that was good for me :)
Another implementation with O(Log(n)) complexity
public static long pow(long base, long exp){
if(exp ==0){
return 1;
}
if(exp ==1){
return base;
}
if(exp % 2 == 0){
long half = pow(base, exp/2);
return half * half;
}else{
long half = pow(base, (exp -1)/2);
return base * half * half;
}
}
Try with recursion:
int pow(int base, int power){
if(power == 0) return 1;
return base * pow(base, --power);
}
Function to handle +/- exponents with O(log(n)) complexity.
double power(double x, int n){
if(n==0)
return 1;
if(n<0){
x = 1.0/x;
n = -n;
}
double ret = power(x,n/2);
ret = ret * ret;
if(n%2!=0)
ret = ret * x;
return ret;
}
This one handles negative exponential:
public static double pow(double base, int e) {
int inc;
if(e <= 0) {
base = 1.0 / base;
inc = 1;
}
else {
inc = -1;
}
return doPow(base, e, inc);
}
private static double doPow(double base, int e, int inc) {
if(e == 0) {
return 1;
}
return base * doPow(base, e + inc, inc);
}
I think in Production recursion just does not provide high end performance.
double power(double num, int exponent)
{
double value=1;
int Originalexpn=exponent;
double OriginalNumber=num;
if(exponent==0)
return value;
if(exponent<0)
{
num=1/num;
exponent=abs(exponent);
}
while(exponent>0)
{
value*=num;
--exponent;
}
cout << OriginalNumber << " Raised to " << Originalexpn << " is " << value << endl;
return value;
}
Use this code.
public int mypow(int a, int e){
if(e == 1) return a;
return a * mypow(a,e-1);
}
Sure, create your own recursive function:
public static int repeat(int base, int exp) {
if (exp == 1) {
return base;
}
return base * repeat(base, exp - 1);
}
Math.pow(a, b)
Math is the class, pow is the method, a and b are the parameters.
Here is a O(log(n)) code that calculates the power of a number. Algorithmic technique used is divide and conquer. It also accepts negative powers i.e., x^(-y)
import java.util.Scanner;
public class PowerOfANumber{
public static void main(String args[]){
float result=0, base;
int power;
PowerOfANumber calcPower = new PowerOfANumber();
/* Get the user input for the base and power */
Scanner input = new Scanner(System.in);
System.out.println("Enter the base");
base=input.nextFloat();
System.out.println("Enter the power");
power=input.nextInt();
result = calcPower.calculatePower(base,power);
System.out.println(base + "^" + power + " is " +result);
}
private float calculatePower(float x, int y){
float temporary;
/* Termination condition for recursion */
if(y==0)
return 1;
temporary=calculatePower(x,y/2);
/* Check if the power is even */
if(y%2==0)
return (temporary * temporary);
else{
if(y>0)
return (x * temporary * temporary);
else
return (temporary*temporary)/x;
}
}
}
Remembering the definition of the logarithm, this can be done with ln and exp if these functions are allowed. Works for any positive base and any real exponent (not necessarily integer):
x = 6.7^4.4
ln(x) = 4.4 * ln(6.7) = about 8.36
x = exp(8.36) = about 4312.5
You can read more here and also here. Java provides both ln and exp.
A recursive method would be the easiest for this :
int power(int base, int exp) {
if (exp != 1) {
return (base * power(base, exp - 1));
} else {
return base;
}
}
where base is the number and exp is the exponenet
This question already has answers here:
Calculate the power of any exponent (negative or positive)
(5 answers)
Closed 9 years ago.
I need to write a method named pow2 that accepts a real number base and an integer exponent as parameters. It should return the base raised to the given power. Your code should work for both positive and negative exponents. For example, the call pow2(2.0, -2) returns 0.25. Do not use Math.pow in your solution.
This is what I have so far:
public double pow2(double x,int y){
double total=1;
for(int i=1;i<=y;i++){
total*=x;
}
return total;
}
But the problem is when I try to call pow(2.0, -2), it returns me 1.0 instead. How do I implement this method?
You have to branch, depending if you have a negative or a positive value.
Here a version that works with recursion:
public double pow2(double x,int y){
return _pow2(1.0, x, y);
}
private double _pow2(double res, double x, int y) {
if (y < 0) return _pow2(res/x, x, y+1);
if (y > 0) return _pow2(res*x, x, y-1);
return res;
}
If y is too big or too small, then you'll run into a stack overflow, so changing it to a non-recursive function is left to the op.
Edit: about your last question, you set the result to 1.0, the body of the loop is never used because !(1 <= -2), so you return the unmodified result of 1.0
Well, finally if you want to do it in an iterative way, just check first if y is positive or negative.
public double pow2(double x, int y)
{
double total = 1.0;
if(y > 0)
{
for(int i = 1 ; i <= y ; i++)
{
total *= x;
}
}
else
{
for(int i = -1 ; i >= y ; i--)
{
total /= x;
}
}
return total;
}
public static void main(String[] args) {
System.out.println(pow2(2,3));
}
public static double pow2(double x,int y){
double total=1;
for(int i=1;i<=y;i++){
total*=x;
}
return total ;
}
public static double pow2(double x,int y){
double total=1;
if(y>0){
for(int i=1;i<=y;i++){
total*=x;
}
return total;
}
else if (y<0){
double temp=1/x;//this makes 2 as 1/2
y=y*-1; //to have a meaningful iteration if for loop
for(int i=1;i<=y;i++){
total*=temp;
}
return total;
}else
return 1;
}