BAEL-7598 Check if a number is a perfect number (#16039)
* BAEL-7598 Check if a number is a perfect number * add stream based method. refactor UT * refactor UT using bdd style * removes public modifier * add jmh benchmark * use properties and remove uncessary configuration --------- Co-authored-by: alexyang <alexyang0623@gmail.com> Co-authored-by: travel2china <163321917+travel2china@users.noreply.github.com>
This commit is contained in:
parent
ee63f1c19d
commit
7edeb43ed1
|
@ -13,4 +13,22 @@
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<jmh.version>1.35</jmh.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
|
<artifactId>jmh-core</artifactId>
|
||||||
|
<version>${jmh.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
|
<artifactId>jmh-generator-annprocess</artifactId>
|
||||||
|
<version>${jmh.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.baeldung.algorithms.perfectnumber;
|
||||||
|
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
class PerfectNumber {
|
||||||
|
|
||||||
|
public static boolean isPerfectBruteForce(int number) {
|
||||||
|
int sum = 0;
|
||||||
|
for (int i = 1; i <= number / 2; i++) {
|
||||||
|
if (number % i == 0) {
|
||||||
|
sum += i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sum == number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isPerfectStream(int number) {
|
||||||
|
int sum = IntStream.rangeClosed(2, (int) Math.sqrt(number))
|
||||||
|
.filter(test -> number % test == 0)
|
||||||
|
.reduce(1, (s, test) -> s + test + (number / test));
|
||||||
|
return sum == number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isPerfectEuclidEuler(int number) {
|
||||||
|
int p = 2;
|
||||||
|
int perfectNumber = (int) (Math.pow(2, p - 1) * (Math.pow(2, p) - 1));
|
||||||
|
while (perfectNumber <= number) {
|
||||||
|
if (perfectNumber == number) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
perfectNumber = (int) (Math.pow(2, p - 1) * (Math.pow(2, p) - 1));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isPerfectEuclidEulerUsingShift(int number) {
|
||||||
|
int p = 2;
|
||||||
|
int perfectNumber = (2 << (p - 1)) * ((2 << p) - 1);
|
||||||
|
while (perfectNumber <= number) {
|
||||||
|
if (perfectNumber == number) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
perfectNumber = (2 << (p - 1)) * ((2 << p) - 1);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.baeldung.algorithms.perfectnumber;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
|
import org.openjdk.jmh.annotations.Scope;
|
||||||
|
import org.openjdk.jmh.annotations.State;
|
||||||
|
import org.openjdk.jmh.runner.Runner;
|
||||||
|
import org.openjdk.jmh.runner.options.Options;
|
||||||
|
import org.openjdk.jmh.runner.options.OptionsBuilder;
|
||||||
|
|
||||||
|
@State(Scope.Benchmark)
|
||||||
|
public class PerfectNumberBenchmark {
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public boolean bruteForceBenchmark() {
|
||||||
|
return PerfectNumber.isPerfectBruteForce(33550336);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public boolean streamBenchmark() {
|
||||||
|
return PerfectNumber.isPerfectStream(33550336);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public boolean euclidEulerBenchmark() {
|
||||||
|
return PerfectNumber.isPerfectEuclidEuler(33550336);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public boolean euclidEulerUsingShiftBenchmark() {
|
||||||
|
return PerfectNumber.isPerfectEuclidEulerUsingShift(33550336);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
Options options = new OptionsBuilder()
|
||||||
|
.include(PerfectNumberBenchmark.class.getSimpleName())
|
||||||
|
.forks(1)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
new Runner(options).run();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package com.baeldung.algorithms.perfectnumber;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
class PerfectNumberUnitTest {
|
||||||
|
@Test
|
||||||
|
void givenPerfectNumber_whenCheckingIsPerfectBruteForce_thenReturnTrue() {
|
||||||
|
assertTrue(PerfectNumber.isPerfectBruteForce(6));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenNonPerfectNumber_whenCheckingIsPerfectBruteForce_thenReturnFalse() {
|
||||||
|
assertFalse(PerfectNumber.isPerfectBruteForce(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenNegativeNumber_whenCheckingIsPerfectBruteForce_thenReturnFalse() {
|
||||||
|
assertFalse(PerfectNumber.isPerfectBruteForce(-28));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenPerfectNumber_whenCheckingIsPerfectStream_thenReturnTrue() {
|
||||||
|
assertTrue(PerfectNumber.isPerfectStream(28));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenNonPerfectNumber_whenCheckingIsPerfectStream_thenReturnFalse() {
|
||||||
|
assertFalse(PerfectNumber.isPerfectStream(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenNegativeNumber_whenCheckingIsPerfectStream_thenReturnFalse() {
|
||||||
|
assertFalse(PerfectNumber.isPerfectStream(-6));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenPerfectNumber_whenCheckingIsPerfectEuclidEuler_thenReturnTrue() {
|
||||||
|
assertTrue(PerfectNumber.isPerfectEuclidEuler(28));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenNonPerfectNumber_whenCheckingIsPerfectEuclidEuler_thenReturnFalse() {
|
||||||
|
assertFalse(PerfectNumber.isPerfectEuclidEuler(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenNegativeNumber_whenCheckingIsPerfectEuclidEuler_thenReturnFalse() {
|
||||||
|
assertFalse(PerfectNumber.isPerfectEuclidEuler(-6));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenPerfectNumber_whenCheckingIsPerfectEuclidEulerUsingShift_thenReturnTrue() {
|
||||||
|
assertTrue(PerfectNumber.isPerfectEuclidEulerUsingShift(28));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenNonPerfectNumber_whenCheckingIsPerfectEuclidEulerUsingShift_thenReturnFalse() {
|
||||||
|
assertFalse(PerfectNumber.isPerfectEuclidEulerUsingShift(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenNegativeNumber_whenCheckingIsPerfectEuclidEulerUsingShift_thenReturnFalse() {
|
||||||
|
assertFalse(PerfectNumber.isPerfectEuclidEulerUsingShift(-6));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue