How can I find an overlap between two given ranges? [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
The community reviewed whether to reopen this question 5 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
Is there an effective way to find the overlap between two ranges?
Practically, the two ranges marked as (a - c), and (b - d), and I assume (c > a) && (d > b).
(b <= a <= d) which means if ((a >= b) && (d > a))
(b <= c <= d) which means if ((c >= b) && (d >= c))
(a <= b <= c) which means if ((b > a) && (c > b))
(a <= d <= c) which means if ((d > a) && (c > d))
But it never ends, because in this way I can find only one range at the time, and in each if I have to check the other cases as well.
For exemple, if the first condition (1) correct, I know what happening with the start of the range (a) I still need to check the others for the end of the range (c).
Not to mention that all this works in the case that (c > a) && (d > b), and not one of them is equal to another.

Two ranges overlap in one of two basic cases:
one range contains the other completely (i.e. both the start and end of one range are between the start and end of the other), or
the start or end of one range is contained within the other range
Conversely, they do not overlap only if neither endpoint of each range is contained within the other range (cases 11 and 12 in your diagram). We can check whether the low end of either range is past the high end of the other, to detect both those cases:
if (a > d || c < b) {
// no overlap
}
else {
// overlap
}
We can invert the condition and then use DeMorgan's laws to swap the order, if that's preferable:
if (a <= d && c >= b) {
// overlap
}
else {
// no overlap
}
To find the actual overlap range, you take the maximum of the two low ends, and the minimum of the two high ends:
int e = Math.max(a,b);
int f = Math.min(c,d);
// overlapping range is [e,f], and overlap exists if e <= f.
All above assumes that the ranges are inclusive, that is, the range defined by a and c includes both the value of a and the value of c. It is fairly trivial to adjust for exclusive ranges, however.

Use apache commons Range and its subclasses, especially the overlap method.

The check for an overlap (just true/false) is actually quite easy:
Assume the ranges [a,b] and [c,d].
You have an overlap if: a <= d and b => c. This also works for a = b and/or c = d.
If you have an overlap then the overlapping range is [max(a,c),min(b,d)].

You can detect the collision of two ranges by using a modified circular collision detection algorithm.
import java.util.Arrays;
public class RangeUtils {
public static void main(String[] args) {
int[] rangeA = { 10, 110 };
int[] rangeB = { 60, 160 };
int[] rangeC = intersectingRange(rangeA, rangeB);
System.out.println("Range: " + Arrays.toString(rangeC)); // Range: [60, 110]
}
// Based on circular collision detection.
public static boolean collisionDetected(int[] rangeA, int[] rangeB) {
int distA = Math.abs(rangeA[1] - rangeA[0]) / 2;
int distB = Math.abs(rangeB[1] - rangeB[0]) / 2;
int midA = (rangeA[0] + rangeA[1]) / 2;
int midB = (rangeB[0] + rangeB[1]) / 2;
return Math.sqrt((midB - midA) * (midB - midA)) < (distA + distB);
}
public static int[] intersectingRange(int[] rangeA, int[] rangeB) {
if (collisionDetected(rangeA, rangeB)) {
return new int[] {
Math.max(rangeA[0], rangeB[0]),
Math.min(rangeA[1], rangeB[1])
};
}
return null;
}
}
Here is a visual example of the code; ported to JavaScript.
var palette = ['#393A3F', '#E82863', '#F6A329', '#34B1E7', '#81C683'];
var canvas = document.getElementById('draw');
var ctx = canvas.getContext('2d');
var rangeA = [10, 110];
var rangeB = [60, 160];
var rangeC = intersectingRange(rangeA, rangeB);
var collisionText = 'Range: [' + rangeC + ']';
var leftOffset = 18;
var topOffset = 24;
drawLines(ctx, [rangeA, rangeB], topOffset);
drawText(ctx, collisionText, leftOffset, topOffset);
drawBoundry(ctx, rangeC, topOffset);
// Based on circular collision detection.
function collisionDetected(rangeA, rangeB) {
var distA = Math.abs(rangeA[1] - rangeA[0]) / 2;
var distB = Math.abs(rangeB[1] - rangeB[0]) / 2;
var midA = (rangeA[0] + rangeA[1]) / 2;
var midB = (rangeB[0] + rangeB[1]) / 2;
return Math.sqrt((midB - midA) * (midB - midA)) < (distA + distB);
}
function intersectingRange(rangeA, rangeB) {
if (collisionDetected(rangeA, rangeB)) {
return [Math.max(rangeA[0], rangeB[0]), Math.min(rangeA[1], rangeB[1])];
}
return null;
}
function drawText(ctx, text, x, y) {
ctx.save();
ctx.font = '18px Arial';
ctx.fillText(text, x, y);
ctx.restore();
}
function drawLines(ctx, lines, topOffset) {
topOffset = topOffset || 0;
var sizeWidth = ctx.canvas.clientWidth;
var sizeHeight = ctx.canvas.clientHeight - topOffset;
var yOffset = sizeHeight / (lines.length + 1);
for (var i = 0; i < lines.length; i++) {
var color = palette[i % palette.length];
var yPos = (i + 1) * yOffset + topOffset;
drawLine(ctx, lines[i], yPos, color)
}
}
function drawLine(ctx, range, index, color) {
ctx.save();
ctx.beginPath();
ctx.moveTo(range[0], index);
ctx.lineTo(range[1], index);
ctx.strokeStyle = color;
ctx.lineWidth = 4;
ctx.stroke();
ctx.restore();
}
function drawBoundry(ctx, bounds, topOffset) {
var sizeHeight = ctx.canvas.clientHeight - topOffset;
var padding = sizeHeight * 0.25;
var y1 = topOffset + padding;
var y2 = sizeHeight + topOffset - padding;
ctx.save();
ctx.beginPath();
ctx.strokeStyle = palette[4];
ctx.setLineDash([5, 5]);
ctx.lineWidth = 2;
ctx.rect(bounds[0], y1, bounds[1] - bounds[0], sizeHeight * 0.5);
ctx.stroke();
ctx.restore();
}
canvas#draw {
background: #FFFFFF;
border: thin solid #7F7F7F;
}
<canvas id="draw" width="180" height="160"></canvas>

Let's make the ranges clearer:
(start1, end1) and (start2, end2)
Double totalRange = Math.max(end1, end2) - Math.min(start1, start2);
Double sumOfRanges = (end1 - start1) + (end2 - start2);
Double overlappingInterval = 0D;
if (sumOfRanges > totalRange) { // means they overlap
overlappingInterval = Math.min(end1, end2) - Math.max(start1, start2);
}
return overlappingInterval;
Based on this answer

Set x=max(a,b), y=min(c,d). If x < y (or x≤y) then (x-y) is a common part of the two ranges (degenerate in case x=y), otherwise they don't overlap.

Based on some other answers to this question I composed the following two code samples:
The first will only return a Boolean indicating whether two ranges overlap:
// If just a boolean is needed
public static boolean overlap(int[] arr1, int[] arr2) {
if((arr1[0] <= arr2[arr2.length - 1]) && (arr2[arr1.length - 1] >= arr2[0])) {
return true;
} else {
return false;
}
}
The second will return an Integer array of the overlapping values in cases where an overlap exists. Otherwise it will return an empty array.
// To get overlapping values
public static int[] overlap(int[] arr1, int[] arr2) {
int[] overlappingValues = {};
if((arr1[0] <= arr2[arr2.length - 1]) && (arr2[arr1.length - 1] >= arr2[0])) {
int z = 0;
for(int a : arr1) {
for(int b : arr2) {
if(a == b) {
overlappingValues[z] = a;
z = z + 1;
}
}
}
} else {
return {};
}
}
Hope this helps.

Based on the updated question I did some research via Google and could find this posting:
Java, find intersection of two arrays
To what I understand at the moment it should match the given requirements. And the code snippet used is quite short and from what I know also looks quite well.
And to account for the remarks in terms of discrete and continuous values I wanted to add another potential solution I could find for continuous ranges:
https://community.oracle.com/thread/2088552?start=0&tstart=0
This solution does not directly return the overlapped ranges but provides an interesting class implementation to do range comparison.

Related

Understanding the strictMath java library

I got bored and decided to dive into remaking the square root function without referencing any of the Math.java functions. I have gotten to this point:
package sqrt;
public class SquareRoot {
public static void main(String[] args) {
System.out.println(sqrtOf(8));
}
public static double sqrtOf(double n){
double x = log(n,2);
return powerOf(2, x/2);
}
public static double log(double n, double base)
{
return (Math.log(n)/Math.log(base));
}
public static double powerOf(double x, double y) {
return powerOf(e(),y * log(x, e()));
}
public static int factorial(int n){
if(n <= 1){
return 1;
}else{
return n * factorial((n-1));
}
}
public static double e(){
return 1/factorial(1);
}
public static double e(int precision){
return 1/factorial(precision);
}
}
As you may very well see, I came to the point in my powerOf() function that infinitely recalls itself. I could replace that and use Math.exp(y * log(x, e()), so I dived into the Math source code to see how it handled my problem, resulting in a goose chase.
public static double exp(double a) {
return StrictMath.exp(a); // default impl. delegates to StrictMath
}
which leads to:
public static double exp(double x)
{
if (x != x)
return x;
if (x > EXP_LIMIT_H)
return Double.POSITIVE_INFINITY;
if (x < EXP_LIMIT_L)
return 0;
// Argument reduction.
double hi;
double lo;
int k;
double t = abs(x);
if (t > 0.5 * LN2)
{
if (t < 1.5 * LN2)
{
hi = t - LN2_H;
lo = LN2_L;
k = 1;
}
else
{
k = (int) (INV_LN2 * t + 0.5);
hi = t - k * LN2_H;
lo = k * LN2_L;
}
if (x < 0)
{
hi = -hi;
lo = -lo;
k = -k;
}
x = hi - lo;
}
else if (t < 1 / TWO_28)
return 1;
else
lo = hi = k = 0;
// Now x is in primary range.
t = x * x;
double c = x - t * (P1 + t * (P2 + t * (P3 + t * (P4 + t * P5))));
if (k == 0)
return 1 - (x * c / (c - 2) - x);
double y = 1 - (lo - x * c / (2 - c) - hi);
return scale(y, k);
}
Values that are referenced:
LN2 = 0.6931471805599453, // Long bits 0x3fe62e42fefa39efL.
LN2_H = 0.6931471803691238, // Long bits 0x3fe62e42fee00000L.
LN2_L = 1.9082149292705877e-10, // Long bits 0x3dea39ef35793c76L.
INV_LN2 = 1.4426950408889634, // Long bits 0x3ff71547652b82feL.
INV_LN2_H = 1.4426950216293335, // Long bits 0x3ff7154760000000L.
INV_LN2_L = 1.9259629911266175e-8; // Long bits 0x3e54ae0bf85ddf44L.
P1 = 0.16666666666666602, // Long bits 0x3fc555555555553eL.
P2 = -2.7777777777015593e-3, // Long bits 0xbf66c16c16bebd93L.
P3 = 6.613756321437934e-5, // Long bits 0x3f11566aaf25de2cL.
P4 = -1.6533902205465252e-6, // Long bits 0xbebbbd41c5d26bf1L.
P5 = 4.1381367970572385e-8, // Long bits 0x3e66376972bea4d0L.
TWO_28 = 0x10000000, // Long bits 0x41b0000000000000L
Here is where I'm starting to get lost. But I can make a few assumptions that so far the answer is starting to become estimated. I then find myself here:
private static double scale(double x, int n)
{
if (Configuration.DEBUG && abs(n) >= 2048)
throw new InternalError("Assertion failure");
if (x == 0 || x == Double.NEGATIVE_INFINITY
|| ! (x < Double.POSITIVE_INFINITY) || n == 0)
return x;
long bits = Double.doubleToLongBits(x);
int exp = (int) (bits >> 52) & 0x7ff;
if (exp == 0) // Subnormal x.
{
x *= TWO_54;
exp = ((int) (Double.doubleToLongBits(x) >> 52) & 0x7ff) - 54;
}
exp += n;
if (exp > 0x7fe) // Overflow.
return Double.POSITIVE_INFINITY * x;
if (exp > 0) // Normal.
return Double.longBitsToDouble((bits & 0x800fffffffffffffL)
| ((long) exp << 52));
if (exp <= -54)
return 0 * x; // Underflow.
exp += 54; // Subnormal result.
x = Double.longBitsToDouble((bits & 0x800fffffffffffffL)
| ((long) exp << 52));
return x * (1 / TWO_54);
}
TWO_54 = 0x40000000000000L
While I am, I would say, very understanding of math and programming, I hit the point to where I find myself at a Frankenstein monster mix of the two. I noticed the intrinsic switch to bits (which I have little to no experience with), and I was hoping someone could explain to me the processes that are occurring "under the hood" so to speak. Specifically where I got lost is from "Now x is in primary range" in the exp() method on wards and what the values that are being referenced really represent. I'm was asking for someone to help me understand not only the methods themselves, but also how they arrive to the answer. Feel free to go as in depth as needed.
edit:
if someone could maybe make this tag: "strictMath" that would be great. I believe that its size and for the Math library deriving from it justifies its existence.
To the exponential function:
What happens is that
exp(x) = 2^k * exp(x-k*log(2))
is exploited for positive x. Some magic is used to get more consistent results for large x where the reduction x-k*log(2) will introduce cancellation errors.
On the reduced x a rational approximation with minimized maximal error over the interval 0.5..1.5 is used, see Pade approximations and similar. This is based on the symmetric formula
exp(x) = exp(x/2)/exp(-x/2) = (c(x²)+x)/(c(x²)-x)
(note that the c in the code is x+c(x)-2). When using Taylor series, approximations for c(x*x)=x*coth(x/2) are based on
c(u)=2 + 1/6*u - 1/360*u^2 + 1/15120*u^3 - 1/604800*u^4 + 1/23950080*u^5 - 691/653837184000*u^6
The scale(x,n) function implements the multiplication x*2^n by directly manipulating the exponent in the bit assembly of the double floating point format.
Computing square roots
To compute square roots it would be more advantageous to compute them directly. First reduce the interval of approximation arguments via
sqrt(x)=2^k*sqrt(x/4^k)
which can again be done efficiently by directly manipulating the bit format of double.
After x is reduced to the interval 0.5..2.0 one can then employ formulas of the form
u = (x-1)/(x+1)
y = (c(u*u)+u) / (c(u*u)-u)
based on
sqrt(x)=sqrt(1+u)/sqrt(1-u)
and
c(v) = 1+sqrt(1-v) = 2 - 1/2*v - 1/8*v^2 - 1/16*v^3 - 5/128*v^4 - 7/256*v^5 - 21/1024*v^6 - 33/2048*v^7 - ...
In a program without bit manipulations this could look like
double my_sqrt(double x) {
double c,u,v,y,scale=1;
int k=0;
if(x<0) return NaN;
while(x>2 ) { x/=4; scale *=2; k++; }
while(x<0.5) { x*=4; scale /=2; k--; }
// rational approximation of sqrt
u = (x-1)/(x+1);
v = u*u;
c = 2 - v/2*(1 + v/4*(1 + v/2));
y = 1 + 2*u/(c-u); // = (c+u)/(c-u);
// one Halley iteration
y = y*(1+8*x/(3*(3*y*y+x))) // = y*(y*y+3*x)/(3*y*y+x)
// reconstruct original scale
return y*scale;
}
One could replace the Halley step with two Newton steps, or
with a better uniform approximation in c one could replace the Halley step with one Newton step, or ...

Least Coin Used Algorithm Java

I am stuck on the coin denomination problem.
I am trying to find the lowest number of coins used to make up $5.70 (or 570 cents). For example, if the coin array is {100,5,2,5,1} (100 x 10c coins, 5 x 20c, 2 x 50c, 5 x $1, and 1 x $2 coin), then the result should be {0,1,1,3,1}
At the moment the coin array will consist of the same denominations ( $2, $1, 50c, 20c, 10c)
public static int[] makeChange(int change, int[] coins) {
// while you have coins of that denomination left and the total
// remaining amount exceeds that denomination, take a coin of that
// denomination (i.e add it to your result array, subtract it from the
// number of available coins, and update the total remainder). –
for(int i= 0; i< coins.length; i++){
while (coins[i] > 0) {
if (coins[i] > 0 & change - 200 >= 0) {
coins[4] = coins[4]--;
change = change - 200;
} else
if (coins[i] > 0 & change - 100 >= 0) {
coins[3] = coins[3]--;
change = change - 100;
} else
if (coins[i] > 0 & change - 50 >= 0) {
coins[2] = coins[2]--;
change = change - 50;
} else
if (coins[i] > 0 & change - 20 >= 0) {
coins[1] = coins[1]--;
change = change - 20;
} else
if (coins[i] > 0 & change - 10 >= 0) {
coins[0] = coins[0]--;
change = change - 10;
}
}
}
return coins;
}
I am stuck on how to deduct the values from coins array and return it.
EDIT: New code
The brute force solution is to try up to the available number of coins of the highest denomination (stopping when you run out or the amount would become negative) and for each of these recurse on solving the remaining amount with a shorter list that excludes that denomination, and pick the minimum of these. If the base case is 1c the problem can always be solved, and the base case is return n otherwise it is n/d0 (d0 representing the lowest denomination), but care must be taken to return a large value when not evenly divisible so the optimization can pick a different branch. Memoization is possible, and parameterized by the remaining amount and the next denomination to try. So the memo table size would be is O(n*d), where n is the starting amount and d is the number of denominations.
So the problem can be solved in pseudo-polynomial time.
The wikipedia link is sparse on details on how to decide if a greedy algorithm such as yours will work. A better reference is linked in this CS StackExchange question. Essentially, if the coin system is canonical, a greedy algorithm will provide an optimal solution. So, is [1, 2, 5, 10, 20] canonical? (using 10s of cents for units, so that the sequence starts in 1)
According to this article, a 5-coin system is non-canonical if and only if it satisfies exactly one of the following conditions:
[1, c2, c3] is non-canonical (false for [1, 2, 5])
it cannot be written as [1, 2, c3, c3+1, 2*c3] (true for [1, 2, 5, 10, 20])
the greedyAnswerSize((k+1) * c4) > k+1 with k*c4 < c5 < (k+1) * c4; in this case, this would require a k*10 < 20 < (k+1)*10; there is no integer k in that range, so this is false for [1, 2, 5, 10, 20].
Therefore, since the greedy algorithm will not provide optimal answers (and even if it did, I doubt that it would work with limited coins), you should try dynamic programming or some enlightened backtracking:
import java.util.HashSet;
import java.util.PriorityQueue;
public class Main {
public static class Answer implements Comparable<Answer> {
public static final int coins[] = {1, 2, 5, 10, 20};
private int availableCoins[] = new int[coins.length];
private int totalAvailable;
private int totalRemaining;
private int coinsUsed;
public Answer(int availableCoins[], int totalRemaining) {
for (int i=0; i<coins.length; i++) {
this.availableCoins[i] = availableCoins[i];
totalAvailable += coins[i] * availableCoins[i];
}
this.totalRemaining = totalRemaining;
}
public boolean hasCoin(int coinIndex) {
return availableCoins[coinIndex] > 0;
}
public boolean isPossibleBest(Answer oldBest) {
boolean r = totalRemaining >= 0
&& totalAvailable >= totalRemaining
&& (oldBest == null || oldBest.coinsUsed > coinsUsed);
return r;
}
public boolean isAnswer() {
return totalRemaining == 0;
}
public Answer useCoin(int coinIndex) {
Answer a = new Answer(availableCoins, totalRemaining - coins[coinIndex]);
a.availableCoins[coinIndex]--;
a.totalAvailable = totalAvailable - coins[coinIndex];
a.coinsUsed = coinsUsed+1;
return a;
}
public int getCoinsUsed() {
return coinsUsed;
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder("{");
for (int c : availableCoins) sb.append(c + ",");
sb.setCharAt(sb.length()-1, '}');
return sb.toString();
}
// try to be greedy first
#Override
public int compareTo(Answer a) {
int r = totalRemaining - a.totalRemaining;
return (r==0) ? coinsUsed - a.coinsUsed : r;
}
}
// returns an minimal set of coins to solve
public static int makeChange(int change, int[] availableCoins) {
PriorityQueue<Answer> queue = new PriorityQueue<Answer>();
queue.add(new Answer(availableCoins, change));
HashSet<String> known = new HashSet<String>();
Answer best = null;
int expansions = 0;
while ( ! queue.isEmpty()) {
Answer current = queue.remove();
expansions ++;
String s = current.toString();
if (current.isPossibleBest(best) && ! known.contains(s)) {
known.add(s);
if (current.isAnswer()) {
best = current;
} else {
for (int i=0; i<Answer.coins.length; i++) {
if (current.hasCoin(i)) {
queue.add(current.useCoin(i));
}
}
}
}
}
// debug
System.out.println("After " + expansions + " expansions");
return (best != null) ? best.getCoinsUsed() : -1;
}
public static void main(String[] args) {
for (int i=0; i<100; i++) {
System.out.println("Solving for " + i + ":"
+ makeChange(i, new int[]{100,5,2,5,1}));
}
}
}
You are in wrong direction. This program will not give you an optimal solution. To get optimal solution go with dynamic algorithms implemented and discussed here. Please visit these few links:
link 1
link 2
link 3

increasing code performance of codility

today i heard about this website called codility where a user can give various programming test to check their code's performance.
When I started, they presented me with this sample test,
Task description A small frog wants to get to the other side of the
road. The frog is currently located at position X and wants to get to
a position greater than or equal to Y. The small frog always jumps a
fixed distance, D. Count the minimal number of jumps that the small
frog must perform to reach its target.
Write a function:
class Solution { public int solution(int X, int Y, int D); }
that, given three integers X, Y and D, returns the minimal number of jumps from position X to a position equal to or greater than Y.
For example,
given:
X = 10
Y = 85
D = 30 the function should return 3,
because the frog will be positioned as follows:
after the first jump,
at position 10 + 30 = 40
after the second jump, at position 10 + 30 + 30 = 70
after the third jump, at position 10 + 30 + 30 + 30 = 100
Assume that: X, Y and D are integers within the range
[1..1,000,000,000]; X ≤ Y. Complexity: expected worst-case time
complexity is O(1); expected worst-case space complexity is O(1).
The question was pretty straight forward and it took me like 2 minutes to write the solution, which is following,
class Solution {
public int solution(int X, int Y, int D) {
int p = 0;
while (X < Y){
p++;
X = X + D;
}
return p;
}
}
However, the test result shows that the performance of my code is just 20% and I scored just 55%,
Here is the link to result, https://codility.com/demo/results/demo66WP2H-K25/
That was so simple code, where I have just used a single while loop, how could it possibly be make much faster ?
Basic math:
X + nD >= Y
nD >= Y - X
n >= (Y - X) / D
The minimum value for n will be the result of rounding up the division of (Y - X) by D.
Big O analysis for this operation:
Complexity: O(1). It's a difference, a division and a round up
Worst-case space complexity is O(1): you can have at most 3 more variables:
Difference for Y - X, let's assign this into Z.
Division between Z by D, let's assign this into E.
Rounding E up, let's assign this into R (from result).
Java(One Line), Correctness 100%, Performance 100%, Task score 100%
// you can also use imports, for example:
// import java.util.*;
// you can write to stdout for debugging purposes, e.g.
// System.out.println("this is a debug message");
class Solution {
public int solution(int X, int Y, int D) {
return (int) Math.ceil((double) (Y - X) / (double) D);
}
}
Here is the 100% total score Python solution:
def solution(X, Y, D):
# write your code in Python 3.6
s = (Y-X)/D
return int(-(-s // 1))
class Solution {
public int solution(int x, int y, int d) {
return (y - x + d - 1) / d;
}
}
class Solution {
public int solution(int x, int y, int d) {
// write your code in Java SE 8
System.out.println("this is a debug message"+(y-x)%d);
if((y-x)%d == 0)
return ((y-x)/d);
else
return (((y-x)/d)+1);
}
}
C# got 100 out of 100 points
using System;
// you can also use other imports, for example:
// using System.Collections.Generic;
// you can write to stdout for debugging purposes, e.g.
// Console.WriteLine("this is a debug message");
class Solution {
public int solution(int X, int Y, int D) {
int Len= Y-X;
if (Len%D==0)
{
return Len/D;
}
else
{
return (Len/D)+1;
}
}
}
Here's Scala solution:
def solution(X: Int, Y: Int, D: Int): Int = {
//divide distance (Y-X) with fixed jump distance. If there is reminder then add 1 to result to
// cover that part with one jump
val jumps = (Y-X) / D + (if(((Y-X) % D) >0 ) 1 else 0)
jumps
}
Performance: https://codility.com/demo/results/trainingTQS547-ZQW/
Javascript solution, 100/100, and shorter than the existing answer:
function solution(Y, Y, D) {
return Math.ceil((Y - X) / D);
}
Here is a solution that brings the test performance to 100%
class Solution {
public int solution(int X, int Y, int D) {
if (X >= Y) return 0;
if (D == 0) return -1;
int minJump = 0;
if ((Y - X) % D == 0) {
minJump = (Y - X) / D;
} else minJump= (Y - X) / D +1;
return minJump;
}
}
JavaScript solution 100/100
function solution (x,y,d) {
if ((y-x) % d === 0) {
return (y-x)/d;
} else {
return Math.ceil((y-x)/d);
}
}
Using Java perfect code
100 score code in Java
public int solution(int X, int Y, int D) {
if(X<0 && Y<0)
return 0;
if(X==Y)
return 0;
if((Y-X)%D==0)
return (Y-X)/D;
else
return (((Y-X)/D)+1);
}
this is corrected code using java giving 91% pass
int solution(int A[]) {
int len = A.length;
if (len == 2) {
return Math.abs(A[1] - A[0]);
}
int[] sumArray = new int[A.length];
int sum = 0;
for (int j = 0; j < A.length; j++) {
sum = sum + A[j];
sumArray[j] = sum;
}
int min = Integer.MAX_VALUE;
for (int j = 0; j < sumArray.length; j++) {
int difference = Math.abs(sum - 2 * sumArray[j]);
// System.out.println(difference);
if (difference < min)
min = difference;
}
return min;
}
This is my solution with 100% (C#):
int result = 0;
if (y <= x || d == 0)
{
result = 0;
}
else
{
result = (y - x + d - 1) / d;
}
return result;
Here is my solution in PHP, 100% performance.
function solution($X, $Y, $D) {
return (int)ceil(($Y-$X)/$D); //ceils returns a float and so we cast (int)
}
Y-X gives you the actual distance object has to be travel ,if that distance is directly divsible by object jump(D) then ans will be (sum/D) if some decimal value is there then we have to add 1 more into it i.e(sum/D)+1
int sum=Y-X;
if(X!=Y && X<Y){
if(sum%D==0){
return (int )(sum/D);
}
else{
return ((int)(sum/D)+1);
}}
else{
return 0;
}
I like all the rest of the solutions, especially "(y - x + d - 1) / d". That was awesome. This is what I came up with.
public int solution(int X, int Y, int D) {
if (X == Y || X > Y || D == 0) {
return 0;
}
int total = (Y - X) / D;
int left = (Y - X) - (D * total);
if (left > 0) {
total++;
}
return total;
}
// you can write to stdout for debugging purposes, e.g.
// console.log('this is a debug message');
function solution(X, Y, D) {
let jumps = 0
//If 0 -> 100 with 2 step
// Answer would be 100/2 = 50
//If 10 -> 100 with 2 step
//Answer would be (100 - 10) / 2 = 45
jumps = Math.ceil((Y - X) / D)
return jumps
}
swift solution 100% PASS - O(1) complexity
import Foundation
import Glibc
public func solution(_ X : Int, _ Y : Int, _ D : Int) -> Int {
if X == Y {
return 0
}
var jumps = (Y-X)/D
if jumps * D + X < Y {
jumps += 1
}
return jumps
}
import math
def solution(X, Y, D):
if (X >= Y): return 0
if (D == 0): return -1
minJump = 0
#if ((Y - X) % D == 0):
minJump = math.ceil((Y - X) / D)
#else:
#minJump = math.ceil((Y - X) / D) +1
return minJump
This solution worked for me in Java 11:
public int solution(int X, int Y, int D) {
return X == Y ? 0 : (Y - X - 1) / D + 1;
}
Correctness 100%, Performance 100%, Task score 100%
#Test
void solution() {
assertThat(task1.solution(0, 0, 30)).isEqualTo(0);
assertThat(task1.solution(10, 10, 10)).isEqualTo(0);
assertThat(task1.solution(10, 10, 30)).isEqualTo(0);
assertThat(task1.solution(10, 30, 30)).isEqualTo(1);
assertThat(task1.solution(10, 40, 30)).isEqualTo(1);
assertThat(task1.solution(10, 45, 30)).isEqualTo(2);
assertThat(task1.solution(10, 70, 30)).isEqualTo(2);
assertThat(task1.solution(10, 75, 30)).isEqualTo(3);
assertThat(task1.solution(10, 80, 30)).isEqualTo(3);
assertThat(task1.solution(10, 85, 30)).isEqualTo(3);
assertThat(task1.solution(10, 100, 30)).isEqualTo(3);
assertThat(task1.solution(10, 101, 30)).isEqualTo(4);
assertThat(task1.solution(10, 105, 30)).isEqualTo(4);
assertThat(task1.solution(10, 110, 30)).isEqualTo(4);
}
Here is the JS implementation
function frogJumbs(x, y, d) {
if ((y - x) % d == 0) {
return Math.floor((y - x) / d);
}
return Math.floor((y - x) / d + 1);
}
console.log(frogJumbs(0, 150, 30));
100% C# solution:
public int solution(int X, int Y, int D)
{
var result = Math.Ceiling((double)(Y - X) / D);
return Convert.ToInt32(result);
}
It divides the total distance by length of a jump and rounds up the result. It came after multiple attempts and some web searches.
Here is the solution in Python giving a score of 100 on Codility:
import math
return math.ceil((Y-X)/D)

Cut a polygon into 4 parts with equals area. java

I need to cut a convex not simple polygon by two perpendicular lines to divide it into 4 equal(area) parts.
I wrote a program, but it does not pass tests.
I think the reason is rounding errors or my function of calculating area.
Please check it, is it correct?
I use shoelace algorithm and heron's formula
Here is the code:
double calcArea() {
double result = 0;
if (size() > 4) {
int j = size() - 1;
for (int i = 0; i < size() - 1; i++) {
result += (points.get(i).getX() + points.get(j).getX())
*
(points.get(j).getY() - points.get(i).getY());
j = i;
}
result = result / (result >= 0 ? 2. : -2.);
} else if(size() == 3) {
double c,a,b, p;
c = Math.sqrt(Math.pow(points.get(0).getY()-points.get(1).getY(),2)+Math.pow(points.get(0).getX()-points.get(1).getX(),2));
a = Math.sqrt(Math.pow(points.get(1).getY()-points.get(2).getY(),2)+Math.pow(points.get(1).getX()-points.get(2).getX(),2));
b = Math.sqrt(Math.pow(points.get(0).getY()-points.get(2).getY(),2)+Math.pow(points.get(0).getX()-points.get(2).getX(),2));
p = (a + b + c) / 2.;
return Math.sqrt(p*(p-a)*(p-b)*(p-c));
}
return result;
}
What I do in:
finding of point(x, y) of cutting polygon.
I cut it by x = a in [ min(x), max(x)]
and calculate S'(part of polygon from x=min(x) to x=a)
if S' = S/2 , i take a for calculating value(a, *)
then the same with y = b whereb in [min(y), max(y)]
Is there more fast method?

Calculating direction based on point offsets

For my tile-based game, I need to calculate direction based on a given point offset (difference between two points). For example, let's say I'm standing at point (10, 4) and I want to move to point (8, 6). The direction I move at is north-west. What would be the best way to calculate this?
Here's me basic implementation in Java.
public int direction(int x, int y) {
if (x > 0) {
if (y > 0) {
return 0; // NE
} else if (y < 0) {
return 1; // SE
} else {
return 2; // E
}
} else if (x < 0) {
if (y > 0) {
return 3; // NW
} else if (y < 0) {
return 4; // SW
} else {
return 5; // W
}
} else {
if (y > 0) {
return 6; // N
} else if (y < 0) {
return 7; // S
} else {
return -1;
}
}
}
Surely it can be optimised or shortened. Any help? Thanks.
I think the easiest to understand way would be making a static array that contains the values for all cases.
// Won't say anything about how much these values make sense
static final int[][] directions = {
{3, 6, 0},
{5, -1, 2}, // -1 for "no direction", feel free to replace
{4, 7, 1}
};
public int direction(int x, int y) {
x = (x < 0) ? 0 : ((x > 0) ? 2 : 1);
y = (y < 0) ? 0 : ((y > 0) ? 2 : 1);
return directions[y][x];
}
Edit: Now it's correct (why are so many languages missing a proper sgn function?)
My answers with if conditions :).
public int direction(int x, int y) {
//0 NE, 1 SE, 2 E, 3 NW, 4 SW, 5 W, 6 N, 7 S, 8 (Same place / Not a direction)
int direction = 0;
if(x < 0){
direction = 3;
}else if(x == 0){
direction = 6;
}
if(y < 0){
direction = direction + 1;
}else if(y == 0){
direction = direction + 2;
}
return direction;
}
define a 2D array to hold all states.
convert x and y to 0, 1 or 2 based on their value (x>0 or x<0 or x ==0)
return the specific index of array.
This is about as short and clean as you can get, if you represent the eight cardinal directions this way, as separate enumerated values. You're choosing between eight distinct return values, so a decision tree with eight leaves is the best you can do.
You might get something a little tidier if you split direction into two components (N-S and E-W), but without knowing more about what you do with direction, we can't know whether that's worth the trouble.
You can receive and return your direction as a Point or something similar (anyway, an (x,y) tuple). So if you're standing in p0 = (10, 4) and want to move to p1 = (8, 6), the result would be (in pseudocode):
norm(p1 - p0) = norm((-2,2)) = (-1,1)
You can calculate the norm of an integer if you divide it by its absolute value. So for a point you calculate the norm of both members. Just bear in mind that (-1,1) is more expressive than 3 and you can operate in an easier fashion with it.
If you need specific operations, you can create your own Java Point class or extend the existing ones in the library.

Categories