1
Fork 0

Compare commits

...

5 Commits

Author SHA1 Message Date
Bauke a688ae2cd8
Solve first-missing-positive. 2022-04-15 23:50:20 +02:00
Bauke 23f5b6b769
Solve valid-number. 2022-04-14 13:36:13 +02:00
Bauke 9512a94b6d
Solve fizz-buzz. 2022-04-13 19:49:19 +02:00
Bauke 0a065d259b
Solve set-mismatch. 2022-04-12 15:26:20 +02:00
Bauke e5fb926c91
Solve keyboard-row. 2022-04-11 14:32:59 +02:00
11 changed files with 207 additions and 0 deletions

View File

@ -0,0 +1,36 @@
pub fn first_missing_positive(mut numbers: Vec<i32>) -> i32 {
let numbers_length = numbers.len();
// Mark all numbers below 1 and above the maximum range as i32::MAX.
for index in 0..numbers_length {
if numbers[index] < 1 || numbers[index] > numbers_length as i32 {
numbers[index] = i32::MAX;
}
}
for index in 0..numbers_length {
// For each index get its number and subtract 1.
let index = numbers[index].abs() as usize - 1;
// If that index then isn't i32::MAX - 1 (ie. negative or above range).
if index as i32 != i32::MAX - 1 {
// Then mark the number for that index as negative.
numbers[index] = -numbers[index].abs();
}
}
// Then the first positive number we find, the index of that number will be
// the first missing positive. And if there are only negative numbers, then
// the next positive number is the total amount of numbers + 1.
numbers
.into_iter()
.enumerate()
.find_map(|(index, number)| {
if number.is_positive() {
Some(index + 1)
} else {
None
}
})
.unwrap_or_else(|| numbers_length + 1) as i32
}

16
source/fizz_buzz/mod.rs Normal file
View File

@ -0,0 +1,16 @@
pub fn fizz_buzz(number: i32) -> Vec<String> {
let mut result = vec![];
for index in 1..=number {
let string = match (index % 3 == 0, index % 5 == 0) {
(true, true) => "FizzBuzz".to_string(),
(true, false) => "Fizz".to_string(),
(false, true) => "Buzz".to_string(),
(false, false) => index.to_string(),
};
result.push(string);
}
result
}

View File

@ -0,0 +1,29 @@
pub fn find_words(words: Vec<String>) -> Vec<String> {
// Uncomment FromIterator in Leetcode since they're using Rust Edition 2018.
// Edition 2021 has this trait in its prelude.
// use std::iter::FromIterator;
use std::collections::HashSet;
fn hashset_from_str(string: &str) -> HashSet<char> {
std::collections::HashSet::<_>::from_iter(string.to_lowercase().chars())
}
let rows = [
hashset_from_str("qwertyuiop"),
hashset_from_str("asdfghjkl"),
hashset_from_str("zxcvbnm"),
];
let mut result = vec![];
for word in words {
let word_set = hashset_from_str(&word);
if rows.iter().any(|row| word_set.is_subset(row)) {
result.push(word);
}
}
result
}

View File

@ -3,9 +3,12 @@ pub mod contains_duplicate;
pub mod contains_duplicate_ii;
pub mod excel_sheet_column_number;
pub mod excel_sheet_column_title;
pub mod first_missing_positive;
pub mod fizz_buzz;
pub mod implement_strstr;
pub mod integer_to_roman;
pub mod isomorphic_strings;
pub mod keyboard_row;
pub mod length_of_last_word;
pub mod longest_common_prefix;
pub mod missing_number;
@ -13,8 +16,10 @@ pub mod palindrome_number;
pub mod plus_one;
pub mod reverse_integer;
pub mod roman_to_integer;
pub mod set_mismatch;
pub mod two_sum;
pub mod valid_anagram;
pub mod valid_number;
pub mod valid_palindrome;
pub mod valid_parenthesis;
pub mod word_pattern;

View File

@ -0,0 +1,31 @@
pub fn find_error_nums(numbers: Vec<i32>) -> Vec<i32> {
// Uncomment FromIterator in Leetcode since they're using Rust Edition 2018.
// Edition 2021 has this trait in its prelude.
// use std::iter::FromIterator;
use std::collections::HashSet;
let range = 1..=numbers.len() as i32;
let mut numbers_set = HashSet::<_>::new();
let mut duplicate = 0;
for number in numbers {
if numbers_set.insert(number) {
continue;
}
duplicate = number;
}
let mut missing = 0;
for number in range {
if !numbers_set.contains(&number) {
missing = number;
break;
}
}
vec![duplicate, missing]
}

View File

@ -0,0 +1,23 @@
pub fn is_number(string: String) -> bool {
let string = string.to_lowercase();
if string.contains("inf") || string.contains("nan") {
return false;
}
let mut parts = string.split("e");
let valid_significand = match parts.next() {
Some(part) => part.parse::<f64>().is_ok(),
None => unreachable!(),
};
let valid_exponent = match parts.next() {
Some(part) => part.parse::<isize>().is_ok(),
None => true,
};
let nothing_remaining = parts.next().is_none();
valid_significand && valid_exponent && nothing_remaining
}

View File

@ -0,0 +1,14 @@
use leetcode::first_missing_positive::first_missing_positive;
use test_case::test_case;
#[test_case(&[1, 2, 0], 3; "example 1")]
#[test_case(&[3, 4, -1, 1], 2; "example 2")]
#[test_case(&[7, 8, 9, 11, 12], 1; "example 3")]
#[test_case(&[1, 3, 2], 4; "maximum")]
#[test_case(&[1, 3, 3], 2; "duplicate")]
#[test_case(&[0], 1; "zero")]
#[test_case(&(0..=500000).into_iter().collect::<Vec<i32>>(), 500001; "massive")]
fn test_first_missing_positive(input: &[i32], expected: i32) {
assert_eq!(first_missing_positive(input.to_vec()), expected);
}

15
tests/fizz_buzz.rs Normal file
View File

@ -0,0 +1,15 @@
use leetcode::fizz_buzz::fizz_buzz;
use test_case::test_case;
const EXAMPLE_3: &[&str] = &[
"1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz", "11",
"Fizz", "13", "14", "FizzBuzz",
];
#[test_case(3, &["1", "2", "Fizz"]; "example 1")]
#[test_case(5, &["1", "2", "Fizz", "4", "Buzz"]; "example 2")]
#[test_case(15, EXAMPLE_3; "example 3")]
fn test_fizz_buzz(input: i32, expected: &[&str]) {
assert_eq!(fizz_buzz(input), expected);
}

13
tests/keyboard_row.rs Normal file
View File

@ -0,0 +1,13 @@
use leetcode::keyboard_row::find_words;
use test_case::test_case;
#[test_case(&["Hello", "Alaska", "Dad", "Peace"], &["Alaska", "Dad"]; "example 1")]
#[test_case(&["omk"], &[]; "example 2")]
#[test_case(&["adsdf", "sfd"], &["adsdf", "sfd"]; "example 3")]
fn test_keyboard_row(input: &[&str], expected: &[&str]) {
assert_eq!(
find_words(input.iter().map(ToString::to_string).collect()),
expected
);
}

12
tests/set_mismatch.rs Normal file
View File

@ -0,0 +1,12 @@
use leetcode::set_mismatch::find_error_nums;
use test_case::test_case;
#[test_case(&[1, 2, 2, 4], &[2, 3]; "example 1")]
#[test_case(&[1, 1], &[1, 2]; "example 2")]
#[test_case(&[2, 2], &[2, 1]; "edge 1")]
#[test_case(&[3, 2, 3, 4, 6, 5], &[3, 1]; "edge 2")]
#[test_case(&[3, 2, 2], &[2, 1]; "edge 3")]
fn test_set_mismatch(input: &[i32], expected: &[i32]) {
assert_eq!(find_error_nums(input.to_vec()), expected);
}

13
tests/valid_number.rs Normal file
View File

@ -0,0 +1,13 @@
use leetcode::valid_number::is_number;
use test_case::test_case;
#[test_case("0", true; "example 1")]
#[test_case("e", false; "example 2")]
#[test_case(".", false; "example 3")]
#[test_case("-inf", false; "infinity")]
#[test_case("NaN", false; "not a number")]
#[test_case("", false; "empty")]
fn test_valid_number(input: &str, expected: bool) {
assert_eq!(is_number(input.to_string()), expected);
}