diff --git a/README.md b/README.md
index d60d5104c385..6961106eb411 100644
--- a/README.md
+++ b/README.md
@@ -18,3 +18,7 @@ Please read our [Contribution Guidelines](CONTRIBUTING.md) before you contribute
## Algorithms
Our [directory](DIRECTORY.md) has the full list of applications.
+
+### Contribution
+- Added by Danielle Ihm for CIS175 GitHub fork assignment
+- Practiced cloning, editing, committing, and pull requests
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java b/src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java
index 624a4e2b858a..7cf1e43dabc1 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java
@@ -1,68 +1,68 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * A utility class for performing single-bit operations on integers.
- * These operations include flipping, setting, clearing, and getting
- * individual bits at specified positions.
- *
- * Bit positions are zero-indexed (i.e., the least significant bit is at position 0).
- * These methods leverage bitwise operations for optimal performance.
- *
- * Examples:
- * - `flipBit(3, 1)` flips the bit at index 1 in binary `11` (result: `1`).
- * - `setBit(4, 0)` sets the bit at index 0 in `100` (result: `101` or 5).
- * - `clearBit(7, 1)` clears the bit at index 1 in `111` (result: `101` or 5).
- * - `getBit(6, 0)` checks if the least significant bit is set (result: `0`).
- *
- * Time Complexity: O(1) for all operations.
- *
- * Author: lukasb1b (https://github.com/lukasb1b)
- */
-public final class SingleBitOperations {
- private SingleBitOperations() {
- }
-
- /**
- * Flips (toggles) the bit at the specified position.
- *
- * @param num the input number
- * @param bit the position of the bit to flip (0-indexed)
- * @return the new number after flipping the specified bit
- */
- public static int flipBit(final int num, final int bit) {
- return num ^ (1 << bit);
- }
-
- /**
- * Sets the bit at the specified position to 1.
- *
- * @param num the input number
- * @param bit the position of the bit to set (0-indexed)
- * @return the new number after setting the specified bit to 1
- */
- public static int setBit(final int num, final int bit) {
- return num | (1 << bit);
- }
-
- /**
- * Clears the bit at the specified position (sets it to 0).
- *
- * @param num the input number
- * @param bit the position of the bit to clear (0-indexed)
- * @return the new number after clearing the specified bit
- */
- public static int clearBit(final int num, final int bit) {
- return num & ~(1 << bit);
- }
-
- /**
- * Gets the bit value (0 or 1) at the specified position.
- *
- * @param num the input number
- * @param bit the position of the bit to retrieve (0-indexed)
- * @return 1 if the bit is set, 0 otherwise
- */
- public static int getBit(final int num, final int bit) {
- return (num >> bit) & 1;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * A utility class for performing single-bit operations on integers.
+ * These operations include flipping, setting, clearing, and getting
+ * individual bits at specified positions.
+ *
+ * Bit positions are zero-indexed (i.e., the least significant bit is at position 0).
+ * These methods leverage bitwise operations for optimal performance.
+ *
+ * Examples:
+ * - `flipBit(3, 1)` flips the bit at index 1 in binary `11` (result: `1`).
+ * - `setBit(4, 0)` sets the bit at index 0 in `100` (result: `101` or 5).
+ * - `clearBit(7, 1)` clears the bit at index 1 in `111` (result: `101` or 5).
+ * - `getBit(6, 0)` checks if the least significant bit is set (result: `0`).
+ *
+ * Time Complexity: O(1) for all operations.
+ *
+ * Author: lukasb1b (https://github.com/lukasb1b)
+ */
+public final class SingleBitOperations {
+ private SingleBitOperations() {
+ }
+
+ /**
+ * Flips (toggles) the bit at the specified position.
+ *
+ * @param num the input number
+ * @param bit the position of the bit to flip (0-indexed)
+ * @return the new number after flipping the specified bit
+ */
+ public static int flipBit(final int num, final int bit) {
+ return num ^ (1 << bit);
+ }
+
+ /**
+ * Sets the bit at the specified position to 1.
+ *
+ * @param num the input number
+ * @param bit the position of the bit to set (0-indexed)
+ * @return the new number after setting the specified bit to 1
+ */
+ public static int setBit(final int num, final int bit) {
+ return num | (1 << bit);
+ }
+
+ /**
+ * Clears the bit at the specified position (sets it to 0).
+ *
+ * @param num the input number
+ * @param bit the position of the bit to clear (0-indexed)
+ * @return the new number after clearing the specified bit
+ */
+ public static int clearBit(final int num, final int bit) {
+ return num & ~(1 << bit);
+ }
+
+ /**
+ * Gets the bit value (0 or 1) at the specified position.
+ *
+ * @param num the input number
+ * @param bit the position of the bit to retrieve (0-indexed)
+ * @return 1 if the bit is set, 0 otherwise
+ */
+ public static int getBit(final int num, final int bit) {
+ return (num >> bit) & 1;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java b/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java
index 9169aa82bd75..7e7baaa6f7d5 100644
--- a/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java
+++ b/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java
@@ -1,101 +1,101 @@
-package com.thealgorithms.ciphers;
-
-/**
- * The Atbash cipher is a classic substitution cipher that substitutes each letter
- * with its opposite letter in the alphabet.
- *
- * For example:
- * - 'A' becomes 'Z', 'B' becomes 'Y', 'C' becomes 'X', and so on.
- * - Similarly, 'a' becomes 'z', 'b' becomes 'y', and so on.
- *
- * The cipher works identically for both uppercase and lowercase letters.
- * Non-alphabetical characters remain unchanged in the output.
- *
- * This cipher is symmetric, meaning that applying the cipher twice will return
- * the original text. Therefore, the same function is used for both encryption and decryption.
- *
- *
Usage Example:
- *
- * AtbashCipher cipher = new AtbashCipher("Hello World!");
- * String encrypted = cipher.convert(); // Output: "Svool Dliow!"
- *
- *
- * @author Krounosity
- * @see Atbash Cipher (Wikipedia)
- */
-public class AtbashCipher {
-
- private String toConvert;
-
- public AtbashCipher() {
- }
-
- /**
- * Constructor with a string parameter.
- *
- * @param str The string to be converted using the Atbash cipher
- */
- public AtbashCipher(String str) {
- this.toConvert = str;
- }
-
- /**
- * Returns the current string set for conversion.
- *
- * @return The string to be converted
- */
- public String getString() {
- return toConvert;
- }
-
- /**
- * Sets the string to be converted using the Atbash cipher.
- *
- * @param str The new string to convert
- */
- public void setString(String str) {
- this.toConvert = str;
- }
-
- /**
- * Checks if a character is uppercase.
- *
- * @param ch The character to check
- * @return {@code true} if the character is uppercase, {@code false} otherwise
- */
- private boolean isCapital(char ch) {
- return ch >= 'A' && ch <= 'Z';
- }
-
- /**
- * Checks if a character is lowercase.
- *
- * @param ch The character to check
- * @return {@code true} if the character is lowercase, {@code false} otherwise
- */
- private boolean isSmall(char ch) {
- return ch >= 'a' && ch <= 'z';
- }
-
- /**
- * Converts the input string using the Atbash cipher.
- * Alphabetic characters are substituted with their opposite in the alphabet,
- * while non-alphabetic characters remain unchanged.
- *
- * @return The converted string after applying the Atbash cipher
- */
- public String convert() {
- StringBuilder convertedString = new StringBuilder();
-
- for (char ch : toConvert.toCharArray()) {
- if (isSmall(ch)) {
- convertedString.append((char) ('z' - (ch - 'a')));
- } else if (isCapital(ch)) {
- convertedString.append((char) ('Z' - (ch - 'A')));
- } else {
- convertedString.append(ch);
- }
- }
- return convertedString.toString();
- }
-}
+package com.thealgorithms.ciphers;
+
+/**
+ * The Atbash cipher is a classic substitution cipher that substitutes each letter
+ * with its opposite letter in the alphabet.
+ *
+ * For example:
+ * - 'A' becomes 'Z', 'B' becomes 'Y', 'C' becomes 'X', and so on.
+ * - Similarly, 'a' becomes 'z', 'b' becomes 'y', and so on.
+ *
+ * The cipher works identically for both uppercase and lowercase letters.
+ * Non-alphabetical characters remain unchanged in the output.
+ *
+ * This cipher is symmetric, meaning that applying the cipher twice will return
+ * the original text. Therefore, the same function is used for both encryption and decryption.
+ *
+ * Usage Example:
+ *
+ * AtbashCipher cipher = new AtbashCipher("Hello World!");
+ * String encrypted = cipher.convert(); // Output: "Svool Dliow!"
+ *
+ *
+ * @author Krounosity
+ * @see Atbash Cipher (Wikipedia)
+ */
+public class AtbashCipher {
+
+ private String toConvert;
+
+ public AtbashCipher() {
+ }
+
+ /**
+ * Constructor with a string parameter.
+ *
+ * @param str The string to be converted using the Atbash cipher
+ */
+ public AtbashCipher(String str) {
+ this.toConvert = str;
+ }
+
+ /**
+ * Returns the current string set for conversion.
+ *
+ * @return The string to be converted
+ */
+ public String getString() {
+ return toConvert;
+ }
+
+ /**
+ * Sets the string to be converted using the Atbash cipher.
+ *
+ * @param str The new string to convert
+ */
+ public void setString(String str) {
+ this.toConvert = str;
+ }
+
+ /**
+ * Checks if a character is uppercase.
+ *
+ * @param ch The character to check
+ * @return {@code true} if the character is uppercase, {@code false} otherwise
+ */
+ private boolean isCapital(char ch) {
+ return ch >= 'A' && ch <= 'Z';
+ }
+
+ /**
+ * Checks if a character is lowercase.
+ *
+ * @param ch The character to check
+ * @return {@code true} if the character is lowercase, {@code false} otherwise
+ */
+ private boolean isSmall(char ch) {
+ return ch >= 'a' && ch <= 'z';
+ }
+
+ /**
+ * Converts the input string using the Atbash cipher.
+ * Alphabetic characters are substituted with their opposite in the alphabet,
+ * while non-alphabetic characters remain unchanged.
+ *
+ * @return The converted string after applying the Atbash cipher
+ */
+ public String convert() {
+ StringBuilder convertedString = new StringBuilder();
+
+ for (char ch : toConvert.toCharArray()) {
+ if (isSmall(ch)) {
+ convertedString.append((char) ('z' - (ch - 'a')));
+ } else if (isCapital(ch)) {
+ convertedString.append((char) ('Z' - (ch - 'A')));
+ } else {
+ convertedString.append(ch);
+ }
+ }
+ return convertedString.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/PermutationCipher.java b/src/main/java/com/thealgorithms/ciphers/PermutationCipher.java
index ce443545db1d..26497f0f9955 100644
--- a/src/main/java/com/thealgorithms/ciphers/PermutationCipher.java
+++ b/src/main/java/com/thealgorithms/ciphers/PermutationCipher.java
@@ -1,194 +1,194 @@
-package com.thealgorithms.ciphers;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * A Java implementation of Permutation Cipher.
- * It is a type of transposition cipher in which the plaintext is divided into blocks
- * and the characters within each block are rearranged according to a fixed permutation key.
- *
- * For example, with key {3, 1, 2} and plaintext "HELLO", the text is divided into blocks
- * of 3 characters: "HEL" and "LO" (with padding). The characters are then rearranged
- * according to the key positions.
- *
- * @author GitHub Copilot
- */
-public class PermutationCipher {
-
- private static final char PADDING_CHAR = 'X';
-
- /**
- * Encrypts the given plaintext using the permutation cipher with the specified key.
- *
- * @param plaintext the text to encrypt
- * @param key the permutation key (array of integers representing positions)
- * @return the encrypted text
- * @throws IllegalArgumentException if the key is invalid
- */
- public String encrypt(String plaintext, int[] key) {
- validateKey(key);
-
- if (plaintext == null || plaintext.isEmpty()) {
- return plaintext;
- }
-
- // Remove spaces and convert to uppercase for consistent processing
- String cleanText = plaintext.replaceAll("\\s+", "").toUpperCase();
-
- // Pad the text to make it divisible by key length
- String paddedText = padText(cleanText, key.length);
-
- StringBuilder encrypted = new StringBuilder();
-
- // Process text in blocks of key length
- for (int i = 0; i < paddedText.length(); i += key.length) {
- String block = paddedText.substring(i, Math.min(i + key.length, paddedText.length()));
- encrypted.append(permuteBlock(block, key));
- }
-
- return encrypted.toString();
- }
-
- /**
- * Decrypts the given ciphertext using the permutation cipher with the specified key.
- *
- * @param ciphertext the text to decrypt
- * @param key the permutation key (array of integers representing positions)
- * @return the decrypted text
- * @throws IllegalArgumentException if the key is invalid
- */
- public String decrypt(String ciphertext, int[] key) {
- validateKey(key);
-
- if (ciphertext == null || ciphertext.isEmpty()) {
- return ciphertext;
- }
-
- // Create the inverse permutation
- int[] inverseKey = createInverseKey(key);
-
- StringBuilder decrypted = new StringBuilder();
-
- // Process text in blocks of key length
- for (int i = 0; i < ciphertext.length(); i += key.length) {
- String block = ciphertext.substring(i, Math.min(i + key.length, ciphertext.length()));
- decrypted.append(permuteBlock(block, inverseKey));
- }
-
- // Remove padding characters from the end
- return removePadding(decrypted.toString());
- }
- /**
- * Validates that the permutation key is valid.
- * A valid key must contain all integers from 1 to n exactly once, where n is the key length.
- *
- * @param key the permutation key to validate
- * @throws IllegalArgumentException if the key is invalid
- */
- private void validateKey(int[] key) {
- if (key == null || key.length == 0) {
- throw new IllegalArgumentException("Key cannot be null or empty");
- }
-
- Set keySet = new HashSet<>();
- for (int position : key) {
- if (position < 1 || position > key.length) {
- throw new IllegalArgumentException("Key must contain integers from 1 to " + key.length);
- }
- if (!keySet.add(position)) {
- throw new IllegalArgumentException("Key must contain each position exactly once");
- }
- }
- }
-
- /**
- * Pads the text with padding characters to make its length divisible by the block size.
- *
- * @param text the text to pad
- * @param blockSize the size of each block
- * @return the padded text
- */
- private String padText(String text, int blockSize) {
- int remainder = text.length() % blockSize;
- if (remainder == 0) {
- return text;
- }
-
- int paddingNeeded = blockSize - remainder;
- StringBuilder padded = new StringBuilder(text);
- for (int i = 0; i < paddingNeeded; i++) {
- padded.append(PADDING_CHAR);
- }
-
- return padded.toString();
- }
- /**
- * Applies the permutation to a single block of text.
- *
- * @param block the block to permute
- * @param key the permutation key
- * @return the permuted block
- */
- private String permuteBlock(String block, int[] key) {
- if (block.length() != key.length) {
- // Handle case where block is shorter than key (shouldn't happen with proper padding)
- block = padText(block, key.length);
- }
-
- char[] result = new char[key.length];
- char[] blockChars = block.toCharArray();
-
- for (int i = 0; i < key.length; i++) {
- // Key positions are 1-based, so subtract 1 for 0-based array indexing
- result[i] = blockChars[key[i] - 1];
- }
-
- return new String(result);
- }
-
- /**
- * Creates the inverse permutation key for decryption.
- *
- * @param key the original permutation key
- * @return the inverse key
- */
- private int[] createInverseKey(int[] key) {
- int[] inverse = new int[key.length];
-
- for (int i = 0; i < key.length; i++) {
- // The inverse key maps each position to where it should go
- inverse[key[i] - 1] = i + 1;
- }
-
- return inverse;
- }
-
- /**
- * Removes padding characters from the end of the decrypted text.
- *
- * @param text the text to remove padding from
- * @return the text without padding
- */
- private String removePadding(String text) {
- if (text.isEmpty()) {
- return text;
- }
-
- int i = text.length() - 1;
- while (i >= 0 && text.charAt(i) == PADDING_CHAR) {
- i--;
- }
-
- return text.substring(0, i + 1);
- }
-
- /**
- * Gets the padding character used by this cipher.
- *
- * @return the padding character
- */
- public char getPaddingChar() {
- return PADDING_CHAR;
- }
-}
+package com.thealgorithms.ciphers;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A Java implementation of Permutation Cipher.
+ * It is a type of transposition cipher in which the plaintext is divided into blocks
+ * and the characters within each block are rearranged according to a fixed permutation key.
+ *
+ * For example, with key {3, 1, 2} and plaintext "HELLO", the text is divided into blocks
+ * of 3 characters: "HEL" and "LO" (with padding). The characters are then rearranged
+ * according to the key positions.
+ *
+ * @author GitHub Copilot
+ */
+public class PermutationCipher {
+
+ private static final char PADDING_CHAR = 'X';
+
+ /**
+ * Encrypts the given plaintext using the permutation cipher with the specified key.
+ *
+ * @param plaintext the text to encrypt
+ * @param key the permutation key (array of integers representing positions)
+ * @return the encrypted text
+ * @throws IllegalArgumentException if the key is invalid
+ */
+ public String encrypt(String plaintext, int[] key) {
+ validateKey(key);
+
+ if (plaintext == null || plaintext.isEmpty()) {
+ return plaintext;
+ }
+
+ // Remove spaces and convert to uppercase for consistent processing
+ String cleanText = plaintext.replaceAll("\\s+", "").toUpperCase();
+
+ // Pad the text to make it divisible by key length
+ String paddedText = padText(cleanText, key.length);
+
+ StringBuilder encrypted = new StringBuilder();
+
+ // Process text in blocks of key length
+ for (int i = 0; i < paddedText.length(); i += key.length) {
+ String block = paddedText.substring(i, Math.min(i + key.length, paddedText.length()));
+ encrypted.append(permuteBlock(block, key));
+ }
+
+ return encrypted.toString();
+ }
+
+ /**
+ * Decrypts the given ciphertext using the permutation cipher with the specified key.
+ *
+ * @param ciphertext the text to decrypt
+ * @param key the permutation key (array of integers representing positions)
+ * @return the decrypted text
+ * @throws IllegalArgumentException if the key is invalid
+ */
+ public String decrypt(String ciphertext, int[] key) {
+ validateKey(key);
+
+ if (ciphertext == null || ciphertext.isEmpty()) {
+ return ciphertext;
+ }
+
+ // Create the inverse permutation
+ int[] inverseKey = createInverseKey(key);
+
+ StringBuilder decrypted = new StringBuilder();
+
+ // Process text in blocks of key length
+ for (int i = 0; i < ciphertext.length(); i += key.length) {
+ String block = ciphertext.substring(i, Math.min(i + key.length, ciphertext.length()));
+ decrypted.append(permuteBlock(block, inverseKey));
+ }
+
+ // Remove padding characters from the end
+ return removePadding(decrypted.toString());
+ }
+ /**
+ * Validates that the permutation key is valid.
+ * A valid key must contain all integers from 1 to n exactly once, where n is the key length.
+ *
+ * @param key the permutation key to validate
+ * @throws IllegalArgumentException if the key is invalid
+ */
+ private void validateKey(int[] key) {
+ if (key == null || key.length == 0) {
+ throw new IllegalArgumentException("Key cannot be null or empty");
+ }
+
+ Set keySet = new HashSet<>();
+ for (int position : key) {
+ if (position < 1 || position > key.length) {
+ throw new IllegalArgumentException("Key must contain integers from 1 to " + key.length);
+ }
+ if (!keySet.add(position)) {
+ throw new IllegalArgumentException("Key must contain each position exactly once");
+ }
+ }
+ }
+
+ /**
+ * Pads the text with padding characters to make its length divisible by the block size.
+ *
+ * @param text the text to pad
+ * @param blockSize the size of each block
+ * @return the padded text
+ */
+ private String padText(String text, int blockSize) {
+ int remainder = text.length() % blockSize;
+ if (remainder == 0) {
+ return text;
+ }
+
+ int paddingNeeded = blockSize - remainder;
+ StringBuilder padded = new StringBuilder(text);
+ for (int i = 0; i < paddingNeeded; i++) {
+ padded.append(PADDING_CHAR);
+ }
+
+ return padded.toString();
+ }
+ /**
+ * Applies the permutation to a single block of text.
+ *
+ * @param block the block to permute
+ * @param key the permutation key
+ * @return the permuted block
+ */
+ private String permuteBlock(String block, int[] key) {
+ if (block.length() != key.length) {
+ // Handle case where block is shorter than key (shouldn't happen with proper padding)
+ block = padText(block, key.length);
+ }
+
+ char[] result = new char[key.length];
+ char[] blockChars = block.toCharArray();
+
+ for (int i = 0; i < key.length; i++) {
+ // Key positions are 1-based, so subtract 1 for 0-based array indexing
+ result[i] = blockChars[key[i] - 1];
+ }
+
+ return new String(result);
+ }
+
+ /**
+ * Creates the inverse permutation key for decryption.
+ *
+ * @param key the original permutation key
+ * @return the inverse key
+ */
+ private int[] createInverseKey(int[] key) {
+ int[] inverse = new int[key.length];
+
+ for (int i = 0; i < key.length; i++) {
+ // The inverse key maps each position to where it should go
+ inverse[key[i] - 1] = i + 1;
+ }
+
+ return inverse;
+ }
+
+ /**
+ * Removes padding characters from the end of the decrypted text.
+ *
+ * @param text the text to remove padding from
+ * @return the text without padding
+ */
+ private String removePadding(String text) {
+ if (text.isEmpty()) {
+ return text;
+ }
+
+ int i = text.length() - 1;
+ while (i >= 0 && text.charAt(i) == PADDING_CHAR) {
+ i--;
+ }
+
+ return text.substring(0, i + 1);
+ }
+
+ /**
+ * Gets the padding character used by this cipher.
+ *
+ * @return the padding character
+ */
+ public char getPaddingChar() {
+ return PADDING_CHAR;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/RailFenceCipher.java b/src/main/java/com/thealgorithms/ciphers/RailFenceCipher.java
index f81252980468..2ccdc866ad4c 100644
--- a/src/main/java/com/thealgorithms/ciphers/RailFenceCipher.java
+++ b/src/main/java/com/thealgorithms/ciphers/RailFenceCipher.java
@@ -1,147 +1,147 @@
-package com.thealgorithms.ciphers;
-
-import java.util.Arrays;
-
-/**
- * The rail fence cipher (also called a zigzag cipher) is a classical type of transposition cipher.
- * It derives its name from the manner in which encryption is performed, in analogy to a fence built with horizontal rails.
- * https://en.wikipedia.org/wiki/Rail_fence_cipher
- * @author https://github.com/Krounosity
- */
-
-public class RailFenceCipher {
-
- // Encrypts the input string using the rail fence cipher method with the given number of rails.
- public String encrypt(String str, int rails) {
-
- // Base case of single rail or rails are more than the number of characters in the string
- if (rails == 1 || rails >= str.length()) {
- return str;
- }
-
- // Boolean flag to determine if the movement is downward or upward in the rail matrix.
- boolean down = true;
- // Create a 2D array to represent the rails (rows) and the length of the string (columns).
- char[][] strRail = new char[rails][str.length()];
-
- // Initialize all positions in the rail matrix with a placeholder character ('\n').
- for (int i = 0; i < rails; i++) {
- Arrays.fill(strRail[i], '\n');
- }
-
- int row = 0; // Start at the first row
- int col = 0; // Start at the first column
-
- int i = 0;
-
- // Fill the rail matrix with characters from the string based on the rail pattern.
- while (col < str.length()) {
- // Change direction to down when at the first row.
- if (row == 0) {
- down = true;
- }
- // Change direction to up when at the last row.
- else if (row == rails - 1) {
- down = false;
- }
-
- // Place the character in the current position of the rail matrix.
- strRail[row][col] = str.charAt(i);
- col++; // Move to the next column.
- // Move to the next row based on the direction.
- if (down) {
- row++;
- } else {
- row--;
- }
-
- i++;
- }
-
- // Construct the encrypted string by reading characters row by row.
- StringBuilder encryptedString = new StringBuilder();
- for (char[] chRow : strRail) {
- for (char ch : chRow) {
- if (ch != '\n') {
- encryptedString.append(ch);
- }
- }
- }
- return encryptedString.toString();
- }
- // Decrypts the input string using the rail fence cipher method with the given number of rails.
- public String decrypt(String str, int rails) {
-
- // Base case of single rail or rails are more than the number of characters in the string
- if (rails == 1 || rails >= str.length()) {
- return str;
- }
- // Boolean flag to determine if the movement is downward or upward in the rail matrix.
- boolean down = true;
-
- // Create a 2D array to represent the rails (rows) and the length of the string (columns).
- char[][] strRail = new char[rails][str.length()];
-
- int row = 0; // Start at the first row
- int col = 0; // Start at the first column
-
- // Mark the pattern on the rail matrix using '*'.
- while (col < str.length()) {
- // Change direction to down when at the first row.
- if (row == 0) {
- down = true;
- }
- // Change direction to up when at the last row.
- else if (row == rails - 1) {
- down = false;
- }
-
- // Mark the current position in the rail matrix.
- strRail[row][col] = '*';
- col++; // Move to the next column.
- // Move to the next row based on the direction.
- if (down) {
- row++;
- } else {
- row--;
- }
- }
-
- int index = 0; // Index to track characters from the input string.
- // Fill the rail matrix with characters from the input string based on the marked pattern.
- for (int i = 0; i < rails; i++) {
- for (int j = 0; j < str.length(); j++) {
- if (strRail[i][j] == '*') {
- strRail[i][j] = str.charAt(index++);
- }
- }
- }
-
- // Construct the decrypted string by following the zigzag pattern.
- StringBuilder decryptedString = new StringBuilder();
- row = 0; // Reset to the first row
- col = 0; // Reset to the first column
-
- while (col < str.length()) {
- // Change direction to down when at the first row.
- if (row == 0) {
- down = true;
- }
- // Change direction to up when at the last row.
- else if (row == rails - 1) {
- down = false;
- }
- // Append the character from the rail matrix to the decrypted string.
- decryptedString.append(strRail[row][col]);
- col++; // Move to the next column.
- // Move to the next row based on the direction.
- if (down) {
- row++;
- } else {
- row--;
- }
- }
-
- return decryptedString.toString();
- }
-}
+package com.thealgorithms.ciphers;
+
+import java.util.Arrays;
+
+/**
+ * The rail fence cipher (also called a zigzag cipher) is a classical type of transposition cipher.
+ * It derives its name from the manner in which encryption is performed, in analogy to a fence built with horizontal rails.
+ * https://en.wikipedia.org/wiki/Rail_fence_cipher
+ * @author https://github.com/Krounosity
+ */
+
+public class RailFenceCipher {
+
+ // Encrypts the input string using the rail fence cipher method with the given number of rails.
+ public String encrypt(String str, int rails) {
+
+ // Base case of single rail or rails are more than the number of characters in the string
+ if (rails == 1 || rails >= str.length()) {
+ return str;
+ }
+
+ // Boolean flag to determine if the movement is downward or upward in the rail matrix.
+ boolean down = true;
+ // Create a 2D array to represent the rails (rows) and the length of the string (columns).
+ char[][] strRail = new char[rails][str.length()];
+
+ // Initialize all positions in the rail matrix with a placeholder character ('\n').
+ for (int i = 0; i < rails; i++) {
+ Arrays.fill(strRail[i], '\n');
+ }
+
+ int row = 0; // Start at the first row
+ int col = 0; // Start at the first column
+
+ int i = 0;
+
+ // Fill the rail matrix with characters from the string based on the rail pattern.
+ while (col < str.length()) {
+ // Change direction to down when at the first row.
+ if (row == 0) {
+ down = true;
+ }
+ // Change direction to up when at the last row.
+ else if (row == rails - 1) {
+ down = false;
+ }
+
+ // Place the character in the current position of the rail matrix.
+ strRail[row][col] = str.charAt(i);
+ col++; // Move to the next column.
+ // Move to the next row based on the direction.
+ if (down) {
+ row++;
+ } else {
+ row--;
+ }
+
+ i++;
+ }
+
+ // Construct the encrypted string by reading characters row by row.
+ StringBuilder encryptedString = new StringBuilder();
+ for (char[] chRow : strRail) {
+ for (char ch : chRow) {
+ if (ch != '\n') {
+ encryptedString.append(ch);
+ }
+ }
+ }
+ return encryptedString.toString();
+ }
+ // Decrypts the input string using the rail fence cipher method with the given number of rails.
+ public String decrypt(String str, int rails) {
+
+ // Base case of single rail or rails are more than the number of characters in the string
+ if (rails == 1 || rails >= str.length()) {
+ return str;
+ }
+ // Boolean flag to determine if the movement is downward or upward in the rail matrix.
+ boolean down = true;
+
+ // Create a 2D array to represent the rails (rows) and the length of the string (columns).
+ char[][] strRail = new char[rails][str.length()];
+
+ int row = 0; // Start at the first row
+ int col = 0; // Start at the first column
+
+ // Mark the pattern on the rail matrix using '*'.
+ while (col < str.length()) {
+ // Change direction to down when at the first row.
+ if (row == 0) {
+ down = true;
+ }
+ // Change direction to up when at the last row.
+ else if (row == rails - 1) {
+ down = false;
+ }
+
+ // Mark the current position in the rail matrix.
+ strRail[row][col] = '*';
+ col++; // Move to the next column.
+ // Move to the next row based on the direction.
+ if (down) {
+ row++;
+ } else {
+ row--;
+ }
+ }
+
+ int index = 0; // Index to track characters from the input string.
+ // Fill the rail matrix with characters from the input string based on the marked pattern.
+ for (int i = 0; i < rails; i++) {
+ for (int j = 0; j < str.length(); j++) {
+ if (strRail[i][j] == '*') {
+ strRail[i][j] = str.charAt(index++);
+ }
+ }
+ }
+
+ // Construct the decrypted string by following the zigzag pattern.
+ StringBuilder decryptedString = new StringBuilder();
+ row = 0; // Reset to the first row
+ col = 0; // Reset to the first column
+
+ while (col < str.length()) {
+ // Change direction to down when at the first row.
+ if (row == 0) {
+ down = true;
+ }
+ // Change direction to up when at the last row.
+ else if (row == rails - 1) {
+ down = false;
+ }
+ // Append the character from the rail matrix to the decrypted string.
+ decryptedString.append(strRail[row][col]);
+ col++; // Move to the next column.
+ // Move to the next row based on the direction.
+ if (down) {
+ row++;
+ } else {
+ row--;
+ }
+ }
+
+ return decryptedString.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/strings/WordLadder.java b/src/main/java/com/thealgorithms/strings/WordLadder.java
index 665e5ff3220d..d59b8c3d04c0 100644
--- a/src/main/java/com/thealgorithms/strings/WordLadder.java
+++ b/src/main/java/com/thealgorithms/strings/WordLadder.java
@@ -1,4 +1,5 @@
package com.thealgorithms.strings;
+ // Modified by Danielle Ihm for assignment
import java.util.Collection;
import java.util.HashSet;