Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions src/main/java/com/thealgorithms/maths/EvilNumber.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.thealgorithms.maths;

/**
* In number theory, an evil number is a non-negative integer that has an even number of 1s in its binary expansion.
* Non-negative integers that are not evil are called odious numbers.
*
* Evil Number Wiki: https://en.wikipedia.org/wiki/Evil_number
* Odious Number Wiki: https://en.wikipedia.org/wiki/Odious_number
*/
public final class EvilNumber {

private EvilNumber() {
}

// Function to count number of one bits in a number using bitwise operators
private static int countOneBits(int number) {
int oneBitCounter = 0;
while (number > 0) {
oneBitCounter += number & 1; // increment count if last bit is 1
number >>= 1; // right shift to next bit
}
return oneBitCounter;
}

/**
* Check either {@code number} is an Evil number or Odious number
*
* @param number the number
* @return {@code true} if {@code number} is an Evil number, otherwise false (in case of of Odious number)
*/
public static boolean isEvilNumber(int number) {
if (number < 0) {
throw new IllegalArgumentException("Negative numbers are not allowed.");
}

int noOfOneBits = countOneBits(number);
return noOfOneBits % 2 == 0;
}
}
28 changes: 28 additions & 0 deletions src/test/java/com/thealgorithms/maths/EvilNumberTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.thealgorithms.maths;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

class EvilNumberTest {
@ParameterizedTest
@CsvSource({"0", "3", "10", "129", "222", "500", "777", "1198"})
void evilNumbersTest(int n) {
assertTrue(EvilNumber.isEvilNumber(n));
}

@ParameterizedTest
@CsvSource({"1", "7", "100", "333", "555", "1199"})
void odiousNumbersTest(int n) {
assertFalse(EvilNumber.isEvilNumber(n));
}

@ParameterizedTest
@CsvSource({"-1"})
void throwsNegativeNumbersNotAllowed(int n) {
assertThrows(IllegalArgumentException.class, () -> EvilNumber.isEvilNumber(n));
}
}