Skip to content

Commit b240ce0

Browse files
authored
Merge branch 'master' into adfgvx_improve
2 parents 9e836d3 + 7cf568c commit b240ce0

File tree

10 files changed

+293
-24
lines changed

10 files changed

+293
-24
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package com.thealgorithms.geometry;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collection;
5+
import java.util.List;
6+
7+
/**
8+
* Class to represent the Midpoint Circle Algorithm.
9+
* This algorithm calculates points on the circumference of a circle
10+
* using integer arithmetic for efficient computation.
11+
*/
12+
public final class MidpointCircle {
13+
14+
private MidpointCircle() {
15+
// Private Constructor to prevent instantiation.
16+
}
17+
18+
/**
19+
* Generates points on the circumference of a circle using the midpoint circle algorithm.
20+
*
21+
* @param centerX The x-coordinate of the circle's center.
22+
* @param centerY The y-coordinate of the circle's center.
23+
* @param radius The radius of the circle.
24+
* @return A list of points on the circle, each represented as an int[] with 2 elements [x, y].
25+
*/
26+
public static List<int[]> generateCirclePoints(int centerX, int centerY, int radius) {
27+
List<int[]> points = new ArrayList<>();
28+
29+
// Special case for radius 0, only the center point should be added.
30+
if (radius == 0) {
31+
points.add(new int[] {centerX, centerY});
32+
return points;
33+
}
34+
35+
// Start at (radius, 0)
36+
int x = radius;
37+
int y = 0;
38+
39+
// Decision parameter
40+
int p = 1 - radius;
41+
42+
// Add the initial points in all octants
43+
addSymmetricPoints(points, centerX, centerY, x, y);
44+
45+
// Iterate while x > y
46+
while (x > y) {
47+
y++;
48+
49+
if (p <= 0) {
50+
// Midpoint is inside or on the circle
51+
p = p + 2 * y + 1;
52+
} else {
53+
// Midpoint is outside the circle
54+
x--;
55+
p = p + 2 * y - 2 * x + 1;
56+
}
57+
58+
// Add points for this (x, y)
59+
addSymmetricPoints(points, centerX, centerY, x, y);
60+
}
61+
62+
return points;
63+
}
64+
65+
/**
66+
* Adds the symmetric points in all octants of the circle based on the current x and y values.
67+
*
68+
* @param points The list to which symmetric points will be added.
69+
* @param centerX The x-coordinate of the circle's center.
70+
* @param centerY The y-coordinate of the circle's center.
71+
* @param x The current x-coordinate on the circumference.
72+
* @param y The current y-coordinate on the circumference.
73+
*/
74+
private static void addSymmetricPoints(Collection<int[]> points, int centerX, int centerY, int x, int y) {
75+
// Octant symmetry points
76+
points.add(new int[] {centerX + x, centerY + y});
77+
points.add(new int[] {centerX - x, centerY + y});
78+
points.add(new int[] {centerX + x, centerY - y});
79+
points.add(new int[] {centerX - x, centerY - y});
80+
points.add(new int[] {centerX + y, centerY + x});
81+
points.add(new int[] {centerX - y, centerY + x});
82+
points.add(new int[] {centerX + y, centerY - x});
83+
points.add(new int[] {centerX - y, centerY - x});
84+
}
85+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.thealgorithms.maths;
2+
3+
/**
4+
* Calculate Catalan Numbers
5+
*/
6+
public final class CatalanNumbers {
7+
private CatalanNumbers() {
8+
}
9+
10+
/**
11+
* Calculate the nth Catalan number using a recursive formula.
12+
*
13+
* @param n the index of the Catalan number to compute
14+
* @return the nth Catalan number
15+
*/
16+
public static long catalan(final int n) {
17+
if (n < 0) {
18+
throw new IllegalArgumentException("Index must be non-negative");
19+
}
20+
return factorial(2 * n) / (factorial(n + 1) * factorial(n));
21+
}
22+
23+
/**
24+
* Calculate the factorial of a number.
25+
*
26+
* @param n the number to compute the factorial for
27+
* @return the factorial of n
28+
*/
29+
private static long factorial(final int n) {
30+
if (n == 0 || n == 1) {
31+
return 1;
32+
}
33+
long result = 1;
34+
for (int i = 2; i <= n; i++) {
35+
result *= i;
36+
}
37+
return result;
38+
}
39+
}

src/main/java/com/thealgorithms/maths/FindKthNumber.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.thealgorithms.maths;
22

3+
import java.util.Collections;
4+
import java.util.PriorityQueue;
35
import java.util.Random;
46

57
/**
@@ -62,4 +64,19 @@ private static void swap(int[] array, int i, int j) {
6264
array[i] = array[j];
6365
array[j] = temp;
6466
}
67+
68+
public static int findKthMaxUsingHeap(int[] array, int k) {
69+
if (k <= 0 || k > array.length) {
70+
throw new IllegalArgumentException("k must be between 1 and the size of the array");
71+
}
72+
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder()); // using max-heap to store numbers.
73+
for (int num : array) {
74+
maxHeap.add(num);
75+
}
76+
while (k > 1) {
77+
maxHeap.poll(); // removing max number from heap
78+
k--;
79+
}
80+
return maxHeap.peek();
81+
}
6582
}

src/main/java/com/thealgorithms/maths/PerfectSquare.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,16 @@ public static boolean isPerfectSquare(final int number) {
1818
final int sqrt = (int) Math.sqrt(number);
1919
return sqrt * sqrt == number;
2020
}
21+
22+
/**
23+
* Check if a number is perfect square or not
24+
*
25+
* @param number number to be checked
26+
* @return {@code true} if {@code number} is perfect square, otherwise
27+
* {@code false}
28+
*/
29+
public static boolean isPerfectSquareUsingPow(long number) {
30+
long a = (long) Math.pow(number, 1.0 / 2);
31+
return a * a == number;
32+
}
2133
}

src/main/java/com/thealgorithms/maths/PronicNumber.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ private PronicNumber() {
2121
* @return true if input number is a pronic number, false otherwise
2222
*/
2323
static boolean isPronic(int inputNumber) {
24+
if (inputNumber == 0) {
25+
return true;
26+
}
2427
// Iterating from 0 to input_number
2528
for (int i = 0; i <= inputNumber; i++) {
2629
// Checking if product of i and (i+1) is equals input_number
@@ -34,4 +37,15 @@ static boolean isPronic(int inputNumber) {
3437
// equals input_number
3538
return false;
3639
}
40+
41+
/**
42+
* This method checks if the given number is pronic number or non-pronic number using square root of number for finding divisors
43+
*
44+
* @param number Integer value which is to be checked if is a pronic number or not
45+
* @return true if input number is a pronic number, false otherwise
46+
*/
47+
public static boolean isPronicNumber(int number) {
48+
int squareRoot = (int) Math.sqrt(number); // finding just smaller divisor of the number than its square root.
49+
return squareRoot * (squareRoot + 1) == number;
50+
}
3751
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.thealgorithms.geometry;
2+
3+
import static org.junit.jupiter.api.Assertions.assertTrue;
4+
5+
import java.util.List;
6+
import org.junit.jupiter.api.Test;
7+
import org.junit.jupiter.params.ParameterizedTest;
8+
import org.junit.jupiter.params.provider.CsvSource;
9+
10+
/**
11+
* Test class for the {@code MidpointCircle} class
12+
*/
13+
class MidpointCircleTest {
14+
15+
/**
16+
* Parameterized test to check the generated points for different circles.
17+
* The points are checked based on the expected center and radius.
18+
*
19+
* @param centerX The x-coordinate of the circle's center.
20+
* @param centerY The y-coordinate of the circle's center.
21+
* @param radius The radius of the circle.
22+
*/
23+
@ParameterizedTest
24+
@CsvSource({
25+
"0, 0, 3", // Circle centered at (0, 0) with radius 3
26+
"10, 10, 2" // Circle centered at (10, 10) with radius 2
27+
})
28+
void
29+
testGenerateCirclePoints(int centerX, int centerY, int radius) {
30+
List<int[]> points = MidpointCircle.generateCirclePoints(centerX, centerY, radius);
31+
32+
// Ensure that all points satisfy the circle equation (x - centerX)^2 + (y - centerY)^2 = radius^2
33+
for (int[] point : points) {
34+
int x = point[0];
35+
int y = point[1];
36+
37+
int dx = x - centerX;
38+
int dy = y - centerY;
39+
int distanceSquared = dx * dx + dy * dy;
40+
41+
assertTrue(Math.abs(distanceSquared - radius * radius) <= 1, "Point (" + x + ", " + y + ") does not satisfy the circle equation.");
42+
}
43+
}
44+
45+
/**
46+
* Test to ensure the algorithm generates points for a zero-radius circle.
47+
*/
48+
@Test
49+
void testZeroRadiusCircle() {
50+
List<int[]> points = MidpointCircle.generateCirclePoints(0, 0, 0);
51+
52+
// A zero-radius circle should only have one point: (0, 0)
53+
assertTrue(points.size() == 1 && points.get(0)[0] == 0 && points.get(0)[1] == 0, "Zero-radius circle did not generate the correct point.");
54+
}
55+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.thealgorithms.maths;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertThrows;
5+
6+
import java.util.stream.Stream;
7+
import org.junit.jupiter.api.Test;
8+
import org.junit.jupiter.params.ParameterizedTest;
9+
import org.junit.jupiter.params.provider.MethodSource;
10+
11+
/**
12+
* Test class for CatalanNumbers
13+
*/
14+
class CatalanNumbersTest {
15+
16+
/**
17+
* Provides test data for the parameterized Catalan number test.
18+
* Each array contains two elements:
19+
* [input number, expected Catalan number for that input]
20+
*/
21+
static Stream<Object[]> catalanNumbersProvider() {
22+
return Stream.of(new Object[] {0, 1}, new Object[] {1, 1}, new Object[] {2, 2}, new Object[] {3, 5}, new Object[] {4, 14}, new Object[] {5, 42}, new Object[] {6, 132}, new Object[] {7, 429}, new Object[] {8, 1430}, new Object[] {9, 4862}, new Object[] {10, 16796});
23+
}
24+
25+
/**
26+
* Parameterized test for checking the correctness of Catalan numbers.
27+
* Uses the data from the provider method 'catalanNumbersProvider'.
28+
*/
29+
@ParameterizedTest
30+
@MethodSource("catalanNumbersProvider")
31+
void testCatalanNumbers(int input, int expected) {
32+
assertEquals(expected, CatalanNumbers.catalan(input), () -> String.format("Catalan number for input %d should be %d", input, expected));
33+
}
34+
35+
/**
36+
* Test for invalid inputs which should throw an IllegalArgumentException.
37+
*/
38+
@Test
39+
void testIllegalInput() {
40+
assertThrows(IllegalArgumentException.class, () -> CatalanNumbers.catalan(-1));
41+
assertThrows(IllegalArgumentException.class, () -> CatalanNumbers.catalan(-5));
42+
}
43+
}

src/test/java/com/thealgorithms/maths/FindKthNumberTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,37 +14,50 @@ public void testFindKthMaxTypicalCases() {
1414
assertEquals(3, FindKthNumber.findKthMax(array1, 3));
1515
assertEquals(4, FindKthNumber.findKthMax(array1, 2));
1616
assertEquals(5, FindKthNumber.findKthMax(array1, 1));
17+
assertEquals(3, FindKthNumber.findKthMaxUsingHeap(array1, 3));
18+
assertEquals(4, FindKthNumber.findKthMaxUsingHeap(array1, 2));
19+
assertEquals(5, FindKthNumber.findKthMaxUsingHeap(array1, 1));
1720

1821
int[] array2 = {7, 5, 8, 2, 1, 6};
1922
assertEquals(5, FindKthNumber.findKthMax(array2, 4));
2023
assertEquals(6, FindKthNumber.findKthMax(array2, 3));
2124
assertEquals(8, FindKthNumber.findKthMax(array2, 1));
25+
assertEquals(5, FindKthNumber.findKthMaxUsingHeap(array2, 4));
26+
assertEquals(6, FindKthNumber.findKthMaxUsingHeap(array2, 3));
27+
assertEquals(8, FindKthNumber.findKthMaxUsingHeap(array2, 1));
2228
}
2329

2430
@Test
2531
public void testFindKthMaxEdgeCases() {
2632
int[] array1 = {1};
2733
assertEquals(1, FindKthNumber.findKthMax(array1, 1));
34+
assertEquals(1, FindKthNumber.findKthMaxUsingHeap(array1, 1));
2835

2936
int[] array2 = {5, 3};
3037
assertEquals(5, FindKthNumber.findKthMax(array2, 1));
3138
assertEquals(3, FindKthNumber.findKthMax(array2, 2));
39+
assertEquals(5, FindKthNumber.findKthMaxUsingHeap(array2, 1));
40+
assertEquals(3, FindKthNumber.findKthMaxUsingHeap(array2, 2));
3241
}
3342

3443
@Test
3544
public void testFindKthMaxInvalidK() {
3645
int[] array = {1, 2, 3, 4, 5};
3746
assertThrows(IllegalArgumentException.class, () -> FindKthNumber.findKthMax(array, 0));
3847
assertThrows(IllegalArgumentException.class, () -> FindKthNumber.findKthMax(array, 6));
48+
assertThrows(IllegalArgumentException.class, () -> FindKthNumber.findKthMaxUsingHeap(array, 0));
49+
assertThrows(IllegalArgumentException.class, () -> FindKthNumber.findKthMaxUsingHeap(array, 6));
3950
}
4051

4152
@Test
4253
public void testFindKthMaxLargeArray() {
4354
int[] array = generateArray(1000);
4455
int k = new Random().nextInt(1, array.length);
4556
int result = FindKthNumber.findKthMax(array, k);
57+
int maxK = FindKthNumber.findKthMaxUsingHeap(array, k);
4658
Arrays.sort(array);
4759
assertEquals(array[array.length - k], result);
60+
assertEquals(array[array.length - k], maxK);
4861
}
4962

5063
public static int[] generateArray(int capacity) {

src/test/java/com/thealgorithms/maths/PerfectSquareTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ public class PerfectSquareTest {
99
@ValueSource(ints = {0, 1, 2 * 2, 3 * 3, 4 * 4, 5 * 5, 6 * 6, 7 * 7, 8 * 8, 9 * 9, 10 * 10, 11 * 11, 123 * 123})
1010
void positiveTest(final int number) {
1111
Assertions.assertTrue(PerfectSquare.isPerfectSquare(number));
12+
Assertions.assertTrue(PerfectSquare.isPerfectSquareUsingPow(number));
1213
}
1314

1415
@ParameterizedTest
1516
@ValueSource(ints = {-1, -2, -3, -4, -5, -100, 2, 3, 5, 6, 7, 8, 10, 11, 12, 13, 15, 17, 99, 101, 257, 999, 1001})
1617
void negativeTest(final int number) {
1718
Assertions.assertFalse(PerfectSquare.isPerfectSquare(number));
19+
Assertions.assertFalse(PerfectSquare.isPerfectSquareUsingPow(number));
1820
}
1921
}

0 commit comments

Comments
 (0)