Skip to content

Commit 19e1d0b

Browse files
authored
Merge branch 'master' into ipv6_new_algo
2 parents 5881845 + 009c2b3 commit 19e1d0b

File tree

145 files changed

+7186
-1350
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

145 files changed

+7186
-1350
lines changed

DIRECTORY.md

Lines changed: 69 additions & 1 deletion
Large diffs are not rendered by default.

pom.xml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<dependency>
2121
<groupId>org.junit</groupId>
2222
<artifactId>junit-bom</artifactId>
23-
<version>5.11.2</version>
23+
<version>5.11.3</version>
2424
<type>pom</type>
2525
<scope>import</scope>
2626
</dependency>
@@ -31,7 +31,7 @@
3131
<dependency>
3232
<groupId>org.junit.jupiter</groupId>
3333
<artifactId>junit-jupiter</artifactId>
34-
<version>5.11.2</version>
34+
<version>5.11.3</version>
3535
<scope>test</scope>
3636
</dependency>
3737
<dependency>
@@ -43,15 +43,15 @@
4343
<dependency>
4444
<groupId>org.mockito</groupId>
4545
<artifactId>mockito-core</artifactId>
46-
<version>5.14.1</version>
46+
<version>5.14.2</version>
4747
<scope>test</scope>
4848
</dependency>
4949

5050

5151
<dependency>
5252
<groupId>org.junit.jupiter</groupId>
5353
<artifactId>junit-jupiter-api</artifactId>
54-
<version>5.11.2</version>
54+
<version>5.11.3</version>
5555
<scope>test</scope>
5656
</dependency>
5757
<dependency>
@@ -132,7 +132,7 @@
132132
<plugin>
133133
<groupId>com.github.spotbugs</groupId>
134134
<artifactId>spotbugs-maven-plugin</artifactId>
135-
<version>4.8.6.4</version>
135+
<version>4.8.6.5</version>
136136
<configuration>
137137
<excludeFilterFile>spotbugs-exclude.xml</excludeFilterFile>
138138
<includeTests>true</includeTests>

src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,27 @@
11
package com.thealgorithms.bitmanipulation;
22

33
/**
4-
* Is number power of 2
4+
* Utility class for checking if a number is a power of two.
5+
* A power of two is a number that can be expressed as 2^n where n is a non-negative integer.
6+
* This class provides a method to determine if a given integer is a power of two using bit manipulation.
7+
*
58
* @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
69
*/
7-
810
public final class IsPowerTwo {
911
private IsPowerTwo() {
1012
}
13+
14+
/**
15+
* Checks if the given integer is a power of two.
16+
*
17+
* A number is considered a power of two if it is greater than zero and
18+
* has exactly one '1' bit in its binary representation. This method
19+
* uses the property that for any power of two (n), the expression
20+
* (n & (n - 1)) will be zero.
21+
*
22+
* @param number the integer to check
23+
* @return true if the number is a power of two, false otherwise
24+
*/
1125
public static boolean isPowerTwo(int number) {
1226
if (number <= 0) {
1327
return false;

src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,30 @@
11
package com.thealgorithms.bitmanipulation;
22

33
/**
4-
* Find Non Repeating Number
4+
* A utility class to find the non-repeating number in an array where every other number repeats.
5+
* This class contains a method to identify the single unique number using bit manipulation.
6+
*
7+
* The solution leverages the properties of the XOR operation, which states that:
8+
* - x ^ x = 0 for any integer x (a number XORed with itself is zero)
9+
* - x ^ 0 = x for any integer x (a number XORed with zero is the number itself)
10+
*
11+
* Using these properties, we can find the non-repeating number in linear time with constant space.
12+
*
13+
* Example:
14+
* Given the input array [2, 3, 5, 2, 3], the output will be 5 since it does not repeat.
15+
*
516
* @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
617
*/
7-
818
public final class NonRepeatingNumberFinder {
919
private NonRepeatingNumberFinder() {
1020
}
1121

22+
/**
23+
* Finds the non-repeating number in the given array.
24+
*
25+
* @param arr an array of integers where every number except one appears twice
26+
* @return the integer that appears only once in the array or 0 if the array is empty
27+
*/
1228
public static int findNonRepeatingNumber(int[] arr) {
1329
int result = 0;
1430
for (int num : arr) {
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.thealgorithms.ciphers;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
/**
7+
* The Baconian Cipher is a substitution cipher where each letter is represented
8+
* by a group of five binary digits (A's and B's). It can also be used to hide
9+
* messages within other texts, making it a simple form of steganography.
10+
* https://en.wikipedia.org/wiki/Bacon%27s_cipher
11+
*
12+
* @author Bennybebo
13+
*/
14+
public class BaconianCipher {
15+
16+
private static final Map<Character, String> BACONIAN_MAP = new HashMap<>();
17+
private static final Map<String, Character> REVERSE_BACONIAN_MAP = new HashMap<>();
18+
19+
static {
20+
// Initialize the Baconian cipher mappings
21+
String[] baconianAlphabet = {"AAAAA", "AAAAB", "AAABA", "AAABB", "AABAA", "AABAB", "AABBA", "AABBB", "ABAAA", "ABAAB", "ABABA", "ABABB", "ABBAA", "ABBAB", "ABBBA", "ABBBB", "BAAAA", "BAAAB", "BAABA", "BAABB", "BABAA", "BABAB", "BABBA", "BABBB", "BBAAA", "BBAAB"};
22+
char letter = 'A';
23+
for (String code : baconianAlphabet) {
24+
BACONIAN_MAP.put(letter, code);
25+
REVERSE_BACONIAN_MAP.put(code, letter);
26+
letter++;
27+
}
28+
29+
// Handle I/J as the same letter
30+
BACONIAN_MAP.put('I', BACONIAN_MAP.get('J'));
31+
REVERSE_BACONIAN_MAP.put(BACONIAN_MAP.get('I'), 'I');
32+
}
33+
34+
/**
35+
* Encrypts the given plaintext using the Baconian cipher.
36+
*
37+
* @param plaintext The plaintext message to encrypt.
38+
* @return The ciphertext as a binary (A/B) sequence.
39+
*/
40+
public String encrypt(String plaintext) {
41+
StringBuilder ciphertext = new StringBuilder();
42+
plaintext = plaintext.toUpperCase().replaceAll("[^A-Z]", ""); // Remove non-letter characters
43+
44+
for (char letter : plaintext.toCharArray()) {
45+
ciphertext.append(BACONIAN_MAP.get(letter));
46+
}
47+
48+
return ciphertext.toString();
49+
}
50+
51+
/**
52+
* Decrypts the given ciphertext encoded in binary (A/B) format using the Baconian cipher.
53+
*
54+
* @param ciphertext The ciphertext to decrypt.
55+
* @return The decrypted plaintext message.
56+
*/
57+
public String decrypt(String ciphertext) {
58+
StringBuilder plaintext = new StringBuilder();
59+
60+
for (int i = 0; i < ciphertext.length(); i += 5) {
61+
String code = ciphertext.substring(i, i + 5);
62+
if (REVERSE_BACONIAN_MAP.containsKey(code)) {
63+
plaintext.append(REVERSE_BACONIAN_MAP.get(code));
64+
} else {
65+
throw new IllegalArgumentException("Invalid Baconian code: " + code);
66+
}
67+
}
68+
69+
return plaintext.toString();
70+
}
71+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.thealgorithms.ciphers;
2+
3+
import java.math.BigInteger;
4+
5+
public final class DiffieHellman {
6+
7+
private final BigInteger base;
8+
private final BigInteger secret;
9+
private final BigInteger prime;
10+
11+
// Constructor to initialize base, secret, and prime
12+
public DiffieHellman(BigInteger base, BigInteger secret, BigInteger prime) {
13+
// Check for non-null and positive values
14+
if (base == null || secret == null || prime == null || base.signum() <= 0 || secret.signum() <= 0 || prime.signum() <= 0) {
15+
throw new IllegalArgumentException("Base, secret, and prime must be non-null and positive values.");
16+
}
17+
this.base = base;
18+
this.secret = secret;
19+
this.prime = prime;
20+
}
21+
22+
// Method to calculate public value (g^x mod p)
23+
public BigInteger calculatePublicValue() {
24+
// Returns g^x mod p
25+
return base.modPow(secret, prime);
26+
}
27+
28+
// Method to calculate the shared secret key (otherPublic^secret mod p)
29+
public BigInteger calculateSharedSecret(BigInteger otherPublicValue) {
30+
if (otherPublicValue == null || otherPublicValue.signum() <= 0) {
31+
throw new IllegalArgumentException("Other public value must be non-null and positive.");
32+
}
33+
// Returns b^x mod p or a^y mod p
34+
return otherPublicValue.modPow(secret, prime);
35+
}
36+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.thealgorithms.ciphers;
2+
3+
public final class MonoAlphabetic {
4+
5+
private MonoAlphabetic() {
6+
throw new UnsupportedOperationException("Utility class");
7+
}
8+
9+
// Encryption method
10+
public static String encrypt(String data, String key) {
11+
if (!data.matches("[A-Z]+")) {
12+
throw new IllegalArgumentException("Input data contains invalid characters. Only uppercase A-Z are allowed.");
13+
}
14+
StringBuilder sb = new StringBuilder();
15+
16+
// Encrypt each character
17+
for (char c : data.toCharArray()) {
18+
int idx = charToPos(c); // Get the index of the character
19+
sb.append(key.charAt(idx)); // Map to the corresponding character in the key
20+
}
21+
return sb.toString();
22+
}
23+
24+
// Decryption method
25+
public static String decrypt(String data, String key) {
26+
StringBuilder sb = new StringBuilder();
27+
28+
// Decrypt each character
29+
for (char c : data.toCharArray()) {
30+
int idx = key.indexOf(c); // Find the index of the character in the key
31+
if (idx == -1) {
32+
throw new IllegalArgumentException("Input data contains invalid characters.");
33+
}
34+
sb.append(posToChar(idx)); // Convert the index back to the original character
35+
}
36+
return sb.toString();
37+
}
38+
39+
// Helper method: Convert a character to its position in the alphabet
40+
private static int charToPos(char c) {
41+
return c - 'A'; // Subtract 'A' to get position (0 for A, 1 for B, etc.)
42+
}
43+
44+
// Helper method: Convert a position in the alphabet to a character
45+
private static char posToChar(int pos) {
46+
return (char) (pos + 'A'); // Add 'A' to convert position back to character
47+
}
48+
}

src/main/java/com/thealgorithms/conversions/IntegerToEnglish.java

Lines changed: 50 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,28 @@
22

33
import java.util.Map;
44

5+
/**
6+
* A utility class to convert integers to their English word representation.
7+
*
8+
* <p>The class supports conversion of numbers from 0 to 2,147,483,647
9+
* (the maximum value of a 32-bit signed integer). It divides the number
10+
* into groups of three digits (thousands, millions, billions, etc.) and
11+
* translates each group into words.</p>
12+
*
13+
* <h2>Example Usage</h2>
14+
* <pre>
15+
* IntegerToEnglish.integerToEnglishWords(12345);
16+
* // Output: "Twelve Thousand Three Hundred Forty Five"
17+
* </pre>
18+
*
19+
* <p>This class uses two maps:</p>
20+
* <ul>
21+
* <li>BASE_NUMBERS_MAP: Holds English words for numbers 0-20, multiples of 10 up to 90, and 100.</li>
22+
* <li>THOUSAND_POWER_MAP: Maps powers of 1000 (e.g., Thousand, Million, Billion).</li>
23+
* </ul>
24+
*/
525
public final class IntegerToEnglish {
26+
627
private static final Map<Integer, String> BASE_NUMBERS_MAP = Map.ofEntries(Map.entry(0, ""), Map.entry(1, "One"), Map.entry(2, "Two"), Map.entry(3, "Three"), Map.entry(4, "Four"), Map.entry(5, "Five"), Map.entry(6, "Six"), Map.entry(7, "Seven"), Map.entry(8, "Eight"), Map.entry(9, "Nine"),
728
Map.entry(10, "Ten"), Map.entry(11, "Eleven"), Map.entry(12, "Twelve"), Map.entry(13, "Thirteen"), Map.entry(14, "Fourteen"), Map.entry(15, "Fifteen"), Map.entry(16, "Sixteen"), Map.entry(17, "Seventeen"), Map.entry(18, "Eighteen"), Map.entry(19, "Nineteen"), Map.entry(20, "Twenty"),
829
Map.entry(30, "Thirty"), Map.entry(40, "Forty"), Map.entry(50, "Fifty"), Map.entry(60, "Sixty"), Map.entry(70, "Seventy"), Map.entry(80, "Eighty"), Map.entry(90, "Ninety"), Map.entry(100, "Hundred"));
@@ -13,43 +34,53 @@ private IntegerToEnglish() {
1334
}
1435

1536
/**
16-
converts numbers < 1000 to english words
37+
* Converts numbers less than 1000 into English words.
38+
*
39+
* @param number the integer value (0-999) to convert
40+
* @return the English word representation of the input number
1741
*/
1842
private static String convertToWords(int number) {
1943
int remainder = number % 100;
20-
21-
String result;
44+
StringBuilder result = new StringBuilder();
2245

2346
if (remainder <= 20) {
24-
result = BASE_NUMBERS_MAP.get(remainder);
47+
result.append(BASE_NUMBERS_MAP.get(remainder));
2548
} else if (BASE_NUMBERS_MAP.containsKey(remainder)) {
26-
result = BASE_NUMBERS_MAP.get(remainder);
49+
result.append(BASE_NUMBERS_MAP.get(remainder));
2750
} else {
2851
int tensDigit = remainder / 10;
2952
int onesDigit = remainder % 10;
30-
31-
result = String.format("%s %s", BASE_NUMBERS_MAP.get(tensDigit * 10), BASE_NUMBERS_MAP.get(onesDigit));
53+
String tens = BASE_NUMBERS_MAP.getOrDefault(tensDigit * 10, "");
54+
String ones = BASE_NUMBERS_MAP.getOrDefault(onesDigit, "");
55+
result.append(tens);
56+
if (ones != null && !ones.isEmpty()) {
57+
result.append(" ").append(ones);
58+
}
3259
}
3360

3461
int hundredsDigit = number / 100;
35-
3662
if (hundredsDigit > 0) {
37-
result = String.format("%s %s%s", BASE_NUMBERS_MAP.get(hundredsDigit), BASE_NUMBERS_MAP.get(100), result.isEmpty() ? "" : " " + result);
63+
if (result.length() > 0) {
64+
result.insert(0, " ");
65+
}
66+
result.insert(0, String.format("%s Hundred", BASE_NUMBERS_MAP.get(hundredsDigit)));
3867
}
3968

40-
return result;
69+
return result.toString().trim();
4170
}
4271

4372
/**
44-
Only convert groups of three digit if they are non-zero
73+
* Converts a non-negative integer to its English word representation.
74+
*
75+
* @param number the integer to convert (0-2,147,483,647)
76+
* @return the English word representation of the input number
4577
*/
4678
public static String integerToEnglishWords(int number) {
4779
if (number == 0) {
4880
return "Zero";
4981
}
5082

5183
StringBuilder result = new StringBuilder();
52-
5384
int index = 0;
5485

5586
while (number > 0) {
@@ -58,23 +89,20 @@ public static String integerToEnglishWords(int number) {
5889

5990
if (remainder > 0) {
6091
String subResult = convertToWords(remainder);
61-
6292
if (!subResult.isEmpty()) {
63-
if (!result.isEmpty()) {
64-
result.insert(0, subResult + " " + THOUSAND_POWER_MAP.get(index) + " ");
65-
} else {
66-
if (index > 0) {
67-
result = new StringBuilder(subResult + " " + THOUSAND_POWER_MAP.get(index));
68-
} else {
69-
result = new StringBuilder(subResult);
70-
}
93+
if (index > 0) {
94+
subResult += " " + THOUSAND_POWER_MAP.get(index);
95+
}
96+
if (result.length() > 0) {
97+
result.insert(0, " ");
7198
}
99+
result.insert(0, subResult);
72100
}
73101
}
74102

75103
index++;
76104
}
77105

78-
return result.toString();
106+
return result.toString().trim();
79107
}
80108
}

0 commit comments

Comments
 (0)