diff --git a/leetcode/src/list.rs b/leetcode/src/list.rs index 9b887e6..f1363d1 100644 --- a/leetcode/src/list.rs +++ b/leetcode/src/list.rs @@ -1,13 +1,95 @@ // Definition for singly-linked list. #[derive(PartialEq, Eq, Clone, Debug)] -pub struct ListNode { - pub val: i32, - pub next: Option>, +pub struct ListNode { + pub val: T, + pub next: Option>>, } -impl ListNode { +impl ListNode { #[inline] - fn new(val: i32) -> Self { + fn new(val: T) -> Self { ListNode { next: None, val } } + + pub fn create_list(v: [T; N]) -> Option> { + let mut head = None; + + for item in v.into_iter().rev() { + head = Some(Box::new(ListNode { + val: item, + next: head, + })); + } + + head + } +} + +pub fn assert_eq_list( + l1: &Option>>, + l2: &Option>>, +) -> bool { + let mut p1 = l1; + let mut p2 = l2; + while let (Some(node1), Some(node2)) = (p1, p2) { + if node1.val != node2.val { + return false; + } + p1 = &node1.next; + p2 = &node2.next; + } + + p1.is_none() && p2.is_none() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_create_list() { + let v = [1, 3, 2]; + let list = ListNode::create_list(v.clone()); + + let mut head = &list; + let mut v = Vec::from(v); + while let Some(node) = head { + let item = v.remove(0); + assert_eq!(item, node.val); + head = &node.next; + } + } + + #[test] + fn test_assert_eq_list() { + let l1 = Some(Box::new(ListNode { + val: 0, + next: Some(Box::new(ListNode { + val: 1, + next: Some(Box::new(ListNode { val: 2, next: None })), + })), + })); + let l2 = Some(Box::new(ListNode { + val: 0, + next: Some(Box::new(ListNode { + val: 1, + next: Some(Box::new(ListNode { val: 2, next: None })), + })), + })); + let l3 = Some(Box::new(ListNode { + val: 0, + next: Some(Box::new(ListNode { + val: 1, + next: Some(Box::new(ListNode { val: 3, next: None })), + })), + })); + let l4 = Some(Box::new(ListNode { + val: 0, + next: Some(Box::new(ListNode { val: 1, next: None })), + })); + + assert!(assert_eq_list(&l1, &l2)); + assert!(!assert_eq_list(&l1, &l3)); + assert!(!assert_eq_list(&l1, &l4)); + } } diff --git a/leetcode/src/solutions.rs b/leetcode/src/solutions.rs index 19e4766..bed0d07 100644 --- a/leetcode/src/solutions.rs +++ b/leetcode/src/solutions.rs @@ -1,5 +1,6 @@ use anyhow::Result; +pub mod add_two_numbers; pub mod two_sum; pub trait Solution: Send + Sync { diff --git a/leetcode/src/solutions/add_two_numbers.rs b/leetcode/src/solutions/add_two_numbers.rs new file mode 100644 index 0000000..eb755f7 --- /dev/null +++ b/leetcode/src/solutions/add_two_numbers.rs @@ -0,0 +1,54 @@ +use super::Solution; +use crate::list::{assert_eq_list, ListNode}; + +pub struct AddTwoNumbers; + +impl Solution for AddTwoNumbers { + fn name(&self) -> String { + "Add Two Numbers Solution".into() + } + fn problem_id(&self) -> usize { + 2 + } + fn test(&self) -> anyhow::Result<()> { + let testcases = [ + ( + ListNode::create_list([2, 4, 3]), + ListNode::create_list([5, 6, 4]), + ListNode::create_list([7, 0, 8]), + ), + ( + ListNode::create_list([0]), + ListNode::create_list([0]), + ListNode::create_list([0]), + ), + ( + ListNode::create_list([9, 9, 9, 9, 9, 9, 9]), + ListNode::create_list([9, 9, 9, 9]), + ListNode::create_list([8, 9, 9, 9, 0, 0, 0, 1]), + ), + ]; + + for (l1, l2, expect) in testcases { + let output = Self::add_two_numbers(l1, l2); + + if !assert_eq_list(&expect, &output) { + // TODO: print link list + anyhow::bail!("test failed in AddTwoNumbers solution"); + } + } + Ok(()) + } + fn benchmark(&self) -> anyhow::Result { + anyhow::bail!("TODO"); + } +} + +impl AddTwoNumbers { + pub fn add_two_numbers( + l1: Option>>, + l2: Option>>, + ) -> Option>> { + todo!() + } +}