diff --git a/src/input/21_test1 b/src/input/21_test1 new file mode 100644 index 0000000..9bee783 --- /dev/null +++ b/src/input/21_test1 @@ -0,0 +1 @@ +list1 = [1,2,4], list2 = [1,3,4] \ No newline at end of file diff --git a/src/input/21_test2 b/src/input/21_test2 new file mode 100644 index 0000000..6dbe363 --- /dev/null +++ b/src/input/21_test2 @@ -0,0 +1 @@ +list1 = [], list2 = [] \ No newline at end of file diff --git a/src/input/21_test3 b/src/input/21_test3 new file mode 100644 index 0000000..c0a2e69 --- /dev/null +++ b/src/input/21_test3 @@ -0,0 +1 @@ +list1 = [], list2 = [0] \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 71e74e5..f146ee4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,7 @@ use solutions::*; async fn main() -> Result<(), Box> { let problems: Vec> = vec![ Box::new(valid_parentheses::ValidParentheses {}), + Box::new(merge_sorted_lists::MergeSortedLists {}), Box::new(xx::XX {}), ]; diff --git a/src/solutions/merge_sorted_lists.rs b/src/solutions/merge_sorted_lists.rs new file mode 100644 index 0000000..44aa324 --- /dev/null +++ b/src/solutions/merge_sorted_lists.rs @@ -0,0 +1,112 @@ +use super::Solution; +use crate::utils::linked_list::ListNode; + +pub struct MergeSortedLists {} + +impl Solution for MergeSortedLists { + fn solution( + &self, + input: &mut Vec, + ) -> Result, Box> { + let lists = parse_input(input.first().unwrap()); + Ok(Box::new(self.merge_two_lists(lists.0, lists.1))) + } + + fn get_id(&self) -> u32 { + 21 + } +} + +impl MergeSortedLists { + pub fn merge_two_lists( + &self, + list1: Option>, + list2: Option>, + ) -> Option> { + match (list1, list2) { + (Some(l1), None) => Some(l1), + (None, Some(l2)) => Some(l2), + (None, None) => None, + (Some(l1), Some(l2)) => match l1.val <= l2.val { + true => Some(Box::new(ListNode { + val: l1.val, + next: self.merge_two_lists(l1.next, Some(l2)), + })), + false => Some(Box::new(ListNode { + val: l2.val, + next: self.merge_two_lists(Some(l1), l2.next), + })), + }, + } + } +} + +fn parse_input(input: &str) -> (Option>, Option>) { + let parts: Vec<&str> = input.split(",").collect(); + let list1_str = parts[0].split('=').nth(1).unwrap().trim(); + let list2_str = parts[1].split('=').nth(1).unwrap().trim(); + + let list1 = ListNode::from_vec(ListNode::parse_list(list1_str)); + let list2 = ListNode::from_vec(ListNode::parse_list(list2_str)); + + (list1, list2) +} + + +/// Test from puzzle input +#[cfg(test)] +mod test { + use super::*; + use crate::*; + + #[test] + fn test1() { + let solution = merge_sorted_lists::MergeSortedLists {}; + + //Complete the Challenge + let answer = solution + .solution( + utils::get_input(solution.get_id(), utils::InputType::Test1) + .unwrap() + .as_mut(), + ) + .unwrap() + .to_string(); + + assert_eq!(answer, "[1,1,2,3,4,4]"); + } + + #[test] + fn test2() { + let solution = merge_sorted_lists::MergeSortedLists {}; + + //Complete the Challenge + let answer = solution + .solution( + utils::get_input(solution.get_id(), utils::InputType::Test2) + .unwrap() + .as_mut(), + ) + .unwrap() + .to_string(); + + assert_eq!(answer, "[]"); + } + + #[test] + fn test3() { + let solution = merge_sorted_lists::MergeSortedLists {}; + + //Complete the Challenge + let answer = solution + .solution( + utils::get_input(solution.get_id(), utils::InputType::Test3) + .unwrap() + .as_mut(), + ) + .unwrap() + .to_string(); + + assert_eq!(answer, "[0]"); + } +} diff --git a/src/solutions/mod.rs b/src/solutions/mod.rs index 07a3d1c..61f2c9f 100644 --- a/src/solutions/mod.rs +++ b/src/solutions/mod.rs @@ -2,6 +2,7 @@ use crate::utils::{self, get_input}; use std::{error::Error, fmt::Display, time::SystemTime}; pub mod valid_parentheses; +pub mod merge_sorted_lists; pub mod xx; pub trait Solution { diff --git a/src/utils/linked_list.rs b/src/utils/linked_list.rs new file mode 100644 index 0000000..b87f502 --- /dev/null +++ b/src/utils/linked_list.rs @@ -0,0 +1,33 @@ +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option> +} + +impl ListNode { + #[inline] + pub fn new(val: i32) -> Self { + ListNode { + next: None, + val + } + } + + pub fn from_vec(vec: Vec) -> Option> { + let mut current = None; + for &v in vec.iter().rev() { + let mut new_node = Box::new(ListNode::new(v)); + new_node.next = current; + current = Some(new_node); + } + current + } + + pub fn parse_list(s: &str) -> Vec { + s.trim_matches(|c| c == '[' || c == ']') + .split(',') + .filter_map(|s| s.trim().parse().ok()) + .collect() + } +} diff --git a/src/utils.rs b/src/utils/mod.rs similarity index 98% rename from src/utils.rs rename to src/utils/mod.rs index 12224ca..4491813 100644 --- a/src/utils.rs +++ b/src/utils/mod.rs @@ -1,3 +1,5 @@ +pub mod linked_list; + use std::{ error::Error, fs::File,