diff --git a/src/exercises/easy_difficulty.rs b/src/exercises/easy_difficulty.rs new file mode 100644 index 0000000..1366055 --- /dev/null +++ b/src/exercises/easy_difficulty.rs @@ -0,0 +1,48 @@ +pub fn binary_search(list: &[T], value: T) -> Result +where + T: PartialOrd + Clone, +{ + if !is_sorted(list) { + return Err("Input list must be sorted"); + } + + let mut current_slice = list; + let mut original_index: Option = None; + while !current_slice.is_empty() { + let middle = current_slice.len() / 2; + + if current_slice[middle] == value { + let result = match original_index { + Some(i) => i + middle, + None => middle, + }; + return Ok(result); + } + if middle < 1 { + return Err("Not found"); + } + if current_slice[middle] > value { + current_slice = current_slice.split_at(middle).0; + } else { + current_slice = current_slice.split_at(middle).1; + if original_index.is_none() { + original_index = Some(middle); + } else { + original_index = Some(original_index.unwrap() + middle); + } + } + } + Err("Not found") +} + +pub fn is_sorted(list: &[T]) -> bool +where + T: PartialOrd, +{ + for index in 1..list.len() { + if list[index] < list[index - 1] { + return false; + } + } + true +} diff --git a/src/exercises/mod.rs b/src/exercises/mod.rs new file mode 100644 index 0000000..4564d48 --- /dev/null +++ b/src/exercises/mod.rs @@ -0,0 +1,30 @@ +mod easy_difficulty; +mod medium_difficulty; + +pub fn run_medium() { + println!("{}", medium_difficulty::longest_palindrome("asdffdas")); +} + +pub fn run_easy() { + let list = vec![5, 1, 8, 20, 4]; + // easy_difficulty::binary_search(list, 20); + // let list = easy_difficulty::slow_sort_list(list); + // println!("List ordered to {:?}", list); + println!( + "The vec {:?} is {} sorted, but [1,2,3,4] is {} sorted", + list, + easy_difficulty::is_sorted(&list), + easy_difficulty::is_sorted(&[1, 2, 3, 4]) + ); + + let sorted_list = vec![1, 10, 15, 20, 30]; + let searched = 40; + let position = easy_difficulty::binary_search(&sorted_list, searched); + match position { + Ok(pos) => println!( + "The element {searched} is indexed in {pos} at {:?}", + sorted_list + ), + Err(e) => println!("Error: {}", e), + } +} diff --git a/src/functions.rs b/src/functions.rs index 42c54bc..d015e31 100644 --- a/src/functions.rs +++ b/src/functions.rs @@ -12,6 +12,83 @@ fn fizzbuzz(n: i32) { } } +// Associated functions (without self) and Methods (with self) +// are the ways of connecting a function to a type. +struct Point { + x: i8, + y: i8, +} + +impl Point { + // Associated functions + fn origin() -> Point { + Point { x: 0, y: 0 } + } + + fn new(x: i8, y: i8) -> Point { + Point { x, y } + } + + // Methods + fn run(&mut self, x: i8, y: i8) { + self.x += x; + self.y += y; + } + + // bad practice, just for practice + fn to_string(&self) -> String { + format!("{} {}", self.x, self.y) + } +} + +// when used as a parameter in a function +// the closures complete type must be annotated using one of a few traits. +// In order to decrease restriction, they are: +// Fn: the closure uses the captured value by reference (&T) +// FnMut: the closure uses the captured value by mutable reference (&mut T) +// FnOnce: the closure uses the captured value by value (T) +// +// NOTE: this function could also take a normal function as a parameter, not only a closure +fn apply(f: F) +where + F: FnOnce(), +{ + println!("About to run a closure..."); + f(); +} + +fn create_fn() -> impl Fn() { + let text = "Fn".to_owned(); + move || println!("Info: {}", text) // move converts the used variables to variables captured by + // value; +} + pub fn functions_module() { fizzbuzz(10); + + println!("-- Associated functions and Methods --"); + + let mut my_point = Point::new(4, 5); + println!("My point: {}", my_point.to_string()); + + my_point.run(20, 1); + println!("My point: {}", my_point.to_string()); + + // Closures are made to allow access to the enclosing environment, + // similar to JS functions inside functions + let mut closure_run = |x: i8, y: i8| { + my_point.x += x; + my_point.y += y; + }; + + closure_run(10, 15); + println!("My point: {}", my_point.to_string()); + // closure_run(10, 15); + // println!("My point: {}", my_point.to_string()); + + // move keyword forces the closure to take ownership of captured variables + let mut closure_run = move |x: i8, y: i8| { + my_point.x += x; + my_point.y += y; + }; } diff --git a/src/main.rs b/src/main.rs index 819700f..e92736a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,8 @@ // mod controlflow; // mod traits; // mod str_types; -mod functions; +// mod functions; +mod exercises; fn main() { // helloworld::hello_world_module(); @@ -26,5 +27,6 @@ fn main() { // controlflow::control_flow_module(); //traits::traits_exercise(); // str_types::str_types_module(); - functions::functions_module(); + // functions::functions_module(); + exercises::run_easy(); }