From 70db8b57cd6fe7489867caf2fb8fd621051b4ed2 Mon Sep 17 00:00:00 2001 From: SKTT1Ryze Date: Wed, 11 Oct 2023 21:18:24 +0900 Subject: [PATCH 1/7] add rustfmt.toml in runtime --- runtime/rust-toolchain | 1 + runtime/rustfmt.toml | 9 +++++++++ runtime/src/container.rs | 9 +++++---- runtime/src/registration.rs | 3 +-- 4 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 runtime/rust-toolchain create mode 100644 runtime/rustfmt.toml diff --git a/runtime/rust-toolchain b/runtime/rust-toolchain new file mode 100644 index 0000000..bf867e0 --- /dev/null +++ b/runtime/rust-toolchain @@ -0,0 +1 @@ +nightly diff --git a/runtime/rustfmt.toml b/runtime/rustfmt.toml new file mode 100644 index 0000000..b4040e3 --- /dev/null +++ b/runtime/rustfmt.toml @@ -0,0 +1,9 @@ +error_on_line_overflow = false +format_strings = true +normalize_comments = true +imports_granularity = "Crate" +reorder_modules = true +# enum_discrim_align_threshold = 20 +use_try_shorthand = true +wrap_comments = true +edition = "2021" \ No newline at end of file diff --git a/runtime/src/container.rs b/runtime/src/container.rs index 7b1aca4..ef062a7 100644 --- a/runtime/src/container.rs +++ b/runtime/src/container.rs @@ -1,8 +1,9 @@ -use std::collections::HashMap; -use std::sync::{Arc, Mutex}; +use std::{ + collections::HashMap, + sync::{Arc, Mutex}, +}; -use leetcode::problems::Problem; -use leetcode::solutions::Solution; +use leetcode::{problems::Problem, solutions::Solution}; #[derive(Default)] pub struct Container { diff --git a/runtime/src/registration.rs b/runtime/src/registration.rs index 1a51042..7b552d6 100644 --- a/runtime/src/registration.rs +++ b/runtime/src/registration.rs @@ -1,7 +1,6 @@ use super::container::ContainerHandle; -use leetcode::problems; -use leetcode::solutions; +use leetcode::{problems, solutions}; pub fn register_all(handle: ContainerHandle) -> anyhow::Result<()> { handle.register_problem(|_| problems::two_sum::TwoSum)?; From 612c95d4e4e89c78d90904b1a19e9a4d4d28b15a Mon Sep 17 00:00:00 2001 From: SKTT1Ryze Date: Wed, 11 Oct 2023 21:20:33 +0900 Subject: [PATCH 2/7] add ListNode --- leetcode/src/lib.rs | 1 + leetcode/src/list.rs | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 leetcode/src/list.rs diff --git a/leetcode/src/lib.rs b/leetcode/src/lib.rs index 694972c..8c8087e 100644 --- a/leetcode/src/lib.rs +++ b/leetcode/src/lib.rs @@ -1,4 +1,5 @@ //! Collections of problems and solutions in LeetCode +mod list; pub mod problems; pub mod solutions; diff --git a/leetcode/src/list.rs b/leetcode/src/list.rs new file mode 100644 index 0000000..9b887e6 --- /dev/null +++ b/leetcode/src/list.rs @@ -0,0 +1,13 @@ +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} From 9079465d8e9289c71ec17f42fb1e2fc1e541b13a Mon Sep 17 00:00:00 2001 From: SKTT1Ryze Date: Wed, 11 Oct 2023 21:25:24 +0900 Subject: [PATCH 3/7] add problem add_two_numbers --- leetcode/src/problems.rs | 1 + leetcode/src/problems/add_two_numbers.rs | 28 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 leetcode/src/problems/add_two_numbers.rs diff --git a/leetcode/src/problems.rs b/leetcode/src/problems.rs index c27ebd3..f4d6577 100644 --- a/leetcode/src/problems.rs +++ b/leetcode/src/problems.rs @@ -1,3 +1,4 @@ +pub mod add_two_numbers; pub mod two_sum; #[allow(dead_code)] diff --git a/leetcode/src/problems/add_two_numbers.rs b/leetcode/src/problems/add_two_numbers.rs new file mode 100644 index 0000000..f6a97c3 --- /dev/null +++ b/leetcode/src/problems/add_two_numbers.rs @@ -0,0 +1,28 @@ +use super::{Difficulty, Problem, Topic}; + +pub struct AddTwoNumbers; + +impl Problem for AddTwoNumbers { + fn id(&self) -> usize { + 2 + } + fn difficulty(&self) -> Difficulty { + Difficulty::Medium + } + fn topic(&self) -> Topic { + Topic::Algorithms + } + fn title(&self) -> String { + "Add Two Numbers".into() + } + fn description(&self) -> String { + r#"You are given two non-empty linked lists representing two non-negative integers. +The digits are stored in reverse order, and each of their nodes contains a single digit. +Add the two numbers and return the sum as a linked list. +You may assume the two numbers do not contain any leading zero, except the number 0 itself."# + .into() + } + fn labels(&self) -> Vec { + ["link list".into()].into() + } +} From 2e974cc43b8e004e115d71afee7819bb1191a227 Mon Sep 17 00:00:00 2001 From: SKTT1Ryze Date: Wed, 11 Oct 2023 22:25:10 +0900 Subject: [PATCH 4/7] setup link list --- leetcode/src/list.rs | 92 +++++++++++++++++++++-- leetcode/src/solutions.rs | 1 + leetcode/src/solutions/add_two_numbers.rs | 54 +++++++++++++ 3 files changed, 142 insertions(+), 5 deletions(-) create mode 100644 leetcode/src/solutions/add_two_numbers.rs 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!() + } +} From be2bb91f2280646b57292ea47d2c070c0dcd5383 Mon Sep 17 00:00:00 2001 From: SKTT1Ryze Date: Wed, 11 Oct 2023 23:06:34 +0900 Subject: [PATCH 5/7] finish add_two_numbers --- leetcode/src/list.rs | 2 +- leetcode/src/solutions/add_two_numbers.rs | 45 +++++++++++++++++++++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/leetcode/src/list.rs b/leetcode/src/list.rs index f1363d1..068a58b 100644 --- a/leetcode/src/list.rs +++ b/leetcode/src/list.rs @@ -7,7 +7,7 @@ pub struct ListNode { impl ListNode { #[inline] - fn new(val: T) -> Self { + pub fn new(val: T) -> Self { ListNode { next: None, val } } diff --git a/leetcode/src/solutions/add_two_numbers.rs b/leetcode/src/solutions/add_two_numbers.rs index eb755f7..3a7ebb4 100644 --- a/leetcode/src/solutions/add_two_numbers.rs +++ b/leetcode/src/solutions/add_two_numbers.rs @@ -46,9 +46,48 @@ impl Solution for AddTwoNumbers { impl AddTwoNumbers { pub fn add_two_numbers( - l1: Option>>, - l2: Option>>, + mut l1: Option>>, + mut l2: Option>>, ) -> Option>> { - todo!() + let mut head = None; + let mut p = &mut head; + let mut residue = 0; + + while let (Some(node1), Some(node2)) = (l1.as_ref(), l2.as_ref()) { + let val = (node1.val + node2.val + residue) % 10; + residue = (node1.val + node2.val + residue) / 10; + + *p = Some(Box::new(ListNode::new(val))); + p = &mut p.as_mut().unwrap().next; + + l1 = l1.take().unwrap().next; + l2 = l2.take().unwrap().next; + } + + while let Some(node) = l1.take() { + let val = (node.val + residue) % 10; + residue = (node.val + residue) / 10; + + *p = Some(Box::new(ListNode::new(val))); + p = &mut p.as_mut().unwrap().next; + + l1 = node.next; + } + + while let Some(node) = l2.take() { + let val = (node.val + residue) % 10; + residue = (node.val + residue) / 10; + + *p = Some(Box::new(ListNode::new(val))); + p = &mut p.as_mut().unwrap().next; + + l2 = node.next; + } + + if residue > 0 { + *p = Some(Box::new(ListNode::new(residue))); + } + + head } } From f670cfe4b2376cd173bf9402e3ae5835b7265554 Mon Sep 17 00:00:00 2001 From: SKTT1Ryze Date: Wed, 11 Oct 2023 23:09:54 +0900 Subject: [PATCH 6/7] register add_two_numbers --- runtime/src/registration.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/runtime/src/registration.rs b/runtime/src/registration.rs index 7b552d6..87cd570 100644 --- a/runtime/src/registration.rs +++ b/runtime/src/registration.rs @@ -6,5 +6,8 @@ pub fn register_all(handle: ContainerHandle) -> anyhow::Result<()> { handle.register_problem(|_| problems::two_sum::TwoSum)?; handle.register_solution(|_| solutions::two_sum::TwoSum)?; + handle.register_problem(|_| problems::add_two_numbers::AddTwoNumbers)?; + handle.register_solution(|_| solutions::add_two_numbers::AddTwoNumbers)?; + Ok(()) } From b01f6121e511ebb630562e2be0560253c6850708 Mon Sep 17 00:00:00 2001 From: SKTT1Ryze Date: Wed, 11 Oct 2023 23:11:20 +0900 Subject: [PATCH 7/7] fix clippy --- leetcode/src/list.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/leetcode/src/list.rs b/leetcode/src/list.rs index 068a58b..e0bbb16 100644 --- a/leetcode/src/list.rs +++ b/leetcode/src/list.rs @@ -49,7 +49,7 @@ mod tests { #[test] fn test_create_list() { let v = [1, 3, 2]; - let list = ListNode::create_list(v.clone()); + let list = ListNode::create_list(v); let mut head = &list; let mut v = Vec::from(v);