Skip to content

[pull] master from TheAlgorithms:master #124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 27, 2023
Merged
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
1 change: 1 addition & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Please delete options that are not relevant.
- [ ] I ran `cargo clippy --all -- -D warnings` just before my last commit and fixed any issue that was found.
- [ ] I ran `cargo fmt` just before my last commit.
- [ ] I ran `cargo test` just before my last commit and all tests passed.
- [ ] I added my algorithm to the corresponding `mod.rs` file within its own folder, and in any parent folder(s).
- [ ] I added my algorithm to `DIRECTORY.md` with the correct link.
- [ ] I checked `COUNTRIBUTING.md` and my code follows its guidelines.

Expand Down
13 changes: 7 additions & 6 deletions src/ciphers/baconian_cipher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
// Bacon's cipher or the Baconian cipher is a method of steganographic message encoding devised by Francis Bacon in 1605.
// A message is concealed in the presentation of text, rather than its content. Bacon cipher is categorized as both a substitution cipher (in plain code) and a concealment cipher (using the two typefaces).


// Encode Baconian Cipher
fn baconian_encode(message: &str) -> String {
pub fn baconian_encode(message: &str) -> String {
let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let baconian = [
"AAAAA", "AAAAB", "AAABA", "AAABB", "AABAA", "AABAB", "AABBA", "AABBB", "ABAAA", "ABAAB",
Expand All @@ -18,17 +17,16 @@ fn baconian_encode(message: &str) -> String {
.chars()
.map(|c| {
if let Some(index) = alphabet.find(c.to_ascii_uppercase()) {
baconian[index as usize].to_string()
baconian[index].to_string()
} else {
c.to_string()
}
})
.collect()
}


// Decode Baconian Cipher
fn baconian_decode(encoded: &str) -> String {
pub fn baconian_decode(encoded: &str) -> String {
let baconian = [
"AAAAA", "AAAAB", "AAABA", "AAABB", "AABAA", "AABAB", "AABBA", "AABBB", "ABAAA", "ABAAB",
"ABABA", "ABABB", "ABBAA", "ABBAB", "ABBBA", "ABBBB", "BAAAA", "BAAAB", "BAABA", "BAABB",
Expand All @@ -40,7 +38,10 @@ fn baconian_decode(encoded: &str) -> String {
.as_bytes()
.chunks(5)
.map(|chunk| {
if let Some(index) = baconian.iter().position(|&x| x == String::from_utf8_lossy(chunk)) {
if let Some(index) = baconian
.iter()
.position(|&x| x == String::from_utf8_lossy(chunk))
{
alphabet.chars().nth(index).unwrap()
} else {
' '
Expand Down
2 changes: 2 additions & 0 deletions src/ciphers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod aes;
mod another_rot13;
mod baconian_cipher;
mod base64;
mod blake2b;
mod caesar;
Expand All @@ -21,6 +22,7 @@ mod vigenere;
mod xor;
pub use self::aes::{aes_decrypt, aes_encrypt, AesKey};
pub use self::another_rot13::another_rot13;
pub use self::baconian_cipher::{baconian_decode, baconian_encode};
pub use self::base64::{base64_decode, base64_encode};
pub use self::blake2b::blake2b;
pub use self::caesar::caesar;
Expand Down
18 changes: 11 additions & 7 deletions src/conversions/binary_to_hexadecimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ static BITS_TO_HEX: &[(u8, &str)] = &[
(0b1111, "f"),
];

fn bin_to_hexadecimal(binary_str: &str) -> String {
pub fn binary_to_hexadecimal(binary_str: &str) -> String {
let binary_str = binary_str.trim();

if binary_str.is_empty() {
Expand All @@ -41,7 +41,11 @@ fn bin_to_hexadecimal(binary_str: &str) -> String {
}

let padded_len = (4 - (binary_str.len() % 4)) % 4;
let binary_str = format!("{:0width$}", binary_str, width = binary_str.len() + padded_len);
let binary_str = format!(
"{:0width$}",
binary_str,
width = binary_str.len() + padded_len
);

// Convert binary to hexadecimal
let mut hexadecimal = String::with_capacity(binary_str.len() / 4 + 2);
Expand All @@ -50,7 +54,7 @@ fn bin_to_hexadecimal(binary_str: &str) -> String {
for chunk in binary_str.as_bytes().chunks(4) {
let mut nibble = 0;
for (i, &byte) in chunk.iter().enumerate() {
nibble |= ((byte - b'0') as u8) << (3 - i);
nibble |= (byte - b'0') << (3 - i);
}

let hex_char = BITS_TO_HEX
Expand All @@ -76,27 +80,27 @@ mod tests {
fn test_empty_string() {
let input = "";
let expected = "Invalid Input";
assert_eq!(bin_to_hexadecimal(input), expected);
assert_eq!(binary_to_hexadecimal(input), expected);
}

#[test]
fn test_invalid_binary() {
let input = "a";
let expected = "Invalid Input";
assert_eq!(bin_to_hexadecimal(input), expected);
assert_eq!(binary_to_hexadecimal(input), expected);
}

#[test]
fn test_binary() {
let input = "00110110";
let expected = "0x36";
assert_eq!(bin_to_hexadecimal(input), expected);
assert_eq!(binary_to_hexadecimal(input), expected);
}

#[test]
fn test_padded_binary() {
let input = " 1010 ";
let expected = "0xa";
assert_eq!(bin_to_hexadecimal(input), expected);
assert_eq!(binary_to_hexadecimal(input), expected);
}
}
2 changes: 1 addition & 1 deletion src/conversions/hexadecimal_to_binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// 2. https://en.wikipedia.org/wiki/Binary_number
// Other References for Testing : https://www.rapidtables.com/convert/number/hex-to-binary.html

fn hexadecimal_to_binary(hex_str: &str) -> Result<String, String> {
pub fn hexadecimal_to_binary(hex_str: &str) -> Result<String, String> {
let hex_chars = hex_str.chars().collect::<Vec<char>>();
let mut binary = String::new();

Expand Down
6 changes: 6 additions & 0 deletions src/conversions/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
mod binary_to_decimal;
mod binary_to_hexadecimal;
mod decimal_to_binary;
mod hexadecimal_to_binary;
mod octal_to_binary;
pub use self::binary_to_decimal::binary_to_decimal;
pub use self::binary_to_hexadecimal::binary_to_hexadecimal;
pub use self::decimal_to_binary::decimal_to_binary;
pub use self::hexadecimal_to_binary::hexadecimal_to_binary;
pub use self::octal_to_binary::octal_to_binary;
7 changes: 3 additions & 4 deletions src/conversions/octal_to_binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
// Wikipedia References : 1. https://en.wikipedia.org/wiki/Octal
// 2. https://en.wikipedia.org/wiki/Binary_number

fn octal_to_binary(octal_str: &str) -> Result<String, &'static str> {
pub fn octal_to_binary(octal_str: &str) -> Result<String, &'static str> {
let octal_str = octal_str.trim();

if octal_str.is_empty() {
return Err("Empty");
}

if !octal_str.chars().all(|c| c >= '0' && c <= '7') {
if !octal_str.chars().all(|c| ('0'..'7').contains(&c)) {
return Err("Non-octal Value");
}

Expand Down Expand Up @@ -54,8 +54,7 @@ mod tests {
#[test]
fn test_valid_octal() {
let input = "123";
let expected = Ok("001010011".to_string());
let expected = Ok("001010011".to_string());
assert_eq!(octal_to_binary(input), expected);
}

}
6 changes: 2 additions & 4 deletions src/data_structures/floyds_algorithm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,9 @@ pub fn has_cycle<T>(linked_list: &LinkedList<T>) -> bool {
}

if slow == fast {

return true; // Cycle detected
}
}

}
// println!("{}", flag);
false // No cycle detected
Expand All @@ -70,7 +68,7 @@ mod tests {
linked_list.insert_at_tail(2);
linked_list.insert_at_tail(3);

assert_eq!(has_cycle(&linked_list), false);
assert!(!has_cycle(&linked_list));

assert_eq!(detect_cycle(&mut linked_list), None);
}
Expand All @@ -91,7 +89,7 @@ mod tests {
}
}

assert_eq!(has_cycle(&linked_list), true);
assert!(has_cycle(&linked_list));
assert_eq!(detect_cycle(&mut linked_list), Some(3));
}
}
8 changes: 2 additions & 6 deletions src/data_structures/infix_to_postfix.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Function to convert infix expression to postfix expression
fn infix_to_postfix(infix: &str) -> String {
pub fn infix_to_postfix(infix: &str) -> String {
let mut postfix = String::new();
let mut stack: Vec<char> = Vec::new();

Expand Down Expand Up @@ -53,17 +53,13 @@ fn infix_to_postfix(infix: &str) -> String {
postfix
}


#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_infix_to_postfix() {
assert_eq!(
infix_to_postfix("a-b+c-d*e"),
"ab-c+de*-".to_string()
);
assert_eq!(infix_to_postfix("a-b+c-d*e"), "ab-c+de*-".to_string());
assert_eq!(
infix_to_postfix("a*(b+c)+d/(e+f)"),
"abc+*def+/+".to_string()
Expand Down
6 changes: 6 additions & 0 deletions src/data_structures/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ mod avl_tree;
mod b_tree;
mod binary_search_tree;
mod fenwick_tree;
mod floyds_algorithm;
mod graph;
mod heap;
mod infix_to_postfix;
mod lazy_segment_tree;
mod linked_list;
mod postfix_evaluation;
mod probabilistic;
mod queue;
mod rb_tree;
Expand All @@ -21,11 +24,14 @@ pub use self::avl_tree::AVLTree;
pub use self::b_tree::BTree;
pub use self::binary_search_tree::BinarySearchTree;
pub use self::fenwick_tree::FenwickTree;
pub use self::floyds_algorithm::{detect_cycle, has_cycle};
pub use self::graph::DirectedGraph;
pub use self::graph::UndirectedGraph;
pub use self::heap::Heap;
pub use self::infix_to_postfix::infix_to_postfix;
pub use self::lazy_segment_tree::LazySegmentTree;
pub use self::linked_list::LinkedList;
pub use self::postfix_evaluation::evaluate_postfix;
pub use self::probabilistic::bloom_filter;
pub use self::probabilistic::count_min_sketch;
pub use self::queue::Queue;
Expand Down
3 changes: 1 addition & 2 deletions src/data_structures/postfix_evaluation.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
fn evaluate_postfix(expression: &str) -> Result<i32, &'static str> {
pub fn evaluate_postfix(expression: &str) -> Result<i32, &'static str> {
let mut stack: Vec<i32> = Vec::new();

for token in expression.split_whitespace() {
Expand Down Expand Up @@ -56,4 +56,3 @@ mod tests {
assert_eq!(evaluate_postfix("5 0 /"), Err("Division by zero"));
}
}

10 changes: 5 additions & 5 deletions src/general/kadane_algorithm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,21 @@
* @param arr A slice of integers representing the array.
* @return The maximum subarray sum.
*/
fn max_sub_array(nums: Vec<i32>) -> i32 {
pub fn max_sub_array(nums: Vec<i32>) -> i32 {
if nums.is_empty() {
return 0;
}

let mut max_current = nums[0];
let mut max_global = nums[0];

for i in 1..nums.len() {
max_current = std::cmp::max(nums[i], max_current + nums[i]);
nums.iter().skip(1).for_each(|&item| {
max_current = std::cmp::max(item, max_current + item);
if max_current > max_global {
max_global = max_current;
}
}
return max_global;
});
max_global
}

#[cfg(test)]
Expand Down
2 changes: 2 additions & 0 deletions src/general/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod fisher_yates_shuffle;
mod genetic;
mod hanoi;
mod huffman_encoding;
mod kadane_algorithm;
mod kmeans;
mod mex;
mod permutations;
Expand All @@ -13,6 +14,7 @@ pub use self::fisher_yates_shuffle::fisher_yates_shuffle;
pub use self::genetic::GeneticAlgorithm;
pub use self::hanoi::hanoi;
pub use self::huffman_encoding::{HuffmanDictionary, HuffmanEncoding};
pub use self::kadane_algorithm::max_sub_array;
pub use self::kmeans::f32::kmeans as kmeans_f32;
pub use self::kmeans::f64::kmeans as kmeans_f64;
pub use self::mex::mex_using_set;
Expand Down
2 changes: 0 additions & 2 deletions src/machine_learning/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ mod loss_function;
mod optimization;

pub use self::linear_regression::linear_regression;

pub use self::loss_function::mae_loss;
pub use self::loss_function::mse_loss;

pub use self::optimization::gradient_descent;
pub use self::optimization::Adam;
3 changes: 1 addition & 2 deletions src/machine_learning/optimization/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
mod gradient_descent;

mod adam;
mod gradient_descent;

pub use self::adam::Adam;
pub use self::gradient_descent::gradient_descent;
10 changes: 5 additions & 5 deletions src/math/area_of_polygon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* @see [Wikipedia - Polygon](https://en.wikipedia.org/wiki/Polygon)
*/

struct Point {
pub struct Point {
x: f64,
y: f64,
}
Expand All @@ -25,7 +25,7 @@
* @return The area of the polygon.
*/

fn area(fig: &Vec<Point>) -> f64 {
pub fn area_of_polygon(fig: &Vec<Point>) -> f64 {
let mut res = 0.0;

for i in 0..fig.len() {
Expand Down Expand Up @@ -57,7 +57,7 @@ mod tests {
Point { x: 0.0, y: 1.0 },
];

assert_eq!(area(&points), 0.5);
assert_eq!(area_of_polygon(&points), 0.5);
}

/**
Expand All @@ -72,7 +72,7 @@ mod tests {
Point { x: 0.0, y: 1.0 },
];

assert_eq!(area(&points), 1.0);
assert_eq!(area_of_polygon(&points), 1.0);
}

/**
Expand All @@ -89,6 +89,6 @@ mod tests {
Point { x: -0.5, y: 0.866 },
];

assert_eq!(area(&points), 2.598);
assert_eq!(area_of_polygon(&points), 2.598);
}
}
2 changes: 1 addition & 1 deletion src/math/area_under_curve.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
fn area_under_curve(start: f64, end: f64, func: fn(f64) -> f64, step_count: usize) -> f64 {
pub fn area_under_curve(start: f64, end: f64, func: fn(f64) -> f64, step_count: usize) -> f64 {
assert!(step_count > 0);

let (start, end) = if start > end {
Expand Down
Loading