Skip to content

Commit

Permalink
leetcode: Simplify add-two-numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
XuShaohua committed Dec 18, 2023
1 parent b9cea20 commit 70a587e
Showing 1 changed file with 40 additions and 75 deletions.
115 changes: 40 additions & 75 deletions leetcode/0002.add-two-numbers/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,102 +4,68 @@

//! Problem: [Add Two Numbers](https://leetcode.com/problems/add-two-numbers)
type NodeLink = Option<Box<ListNode>>;

#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct ListNode {
val: i32,
next: Option<Box<ListNode>>,
next: NodeLink,
}

pub type ListNodeRef = Option<Box<ListNode>>;

impl ListNode {
#[must_use]
pub fn new(val: i32) -> Self {
Self { val, next: None }
}

/// Concate |other| list to this one.
pub fn append(mut list: ListNodeRef, mut other: ListNodeRef) -> ListNodeRef {
while let Some(other_box) = other {
list = ListNode::push(list, other_box.val);
other = other_box.next;
}
list
}

pub fn append_with_carrier(
mut list: ListNodeRef,
mut other: ListNodeRef,
mut carrier: i32,
) -> ListNodeRef {
while let Some(other_box) = other {
let sum = other_box.val + carrier;
let remainder = sum % 10;
carrier = sum / 10;
list = ListNode::push(list, remainder);
other = other_box.next;
}
if carrier > 0 {
list = ListNode::push(list, carrier);
}
list
}

/// Add an element to head of list.
pub fn push(list: ListNodeRef, val: i32) -> ListNodeRef {
Some(Box::new(ListNode { val, next: list }))
}

/// Reverse elements in list.
pub fn reverse(mut list: ListNodeRef) -> ListNodeRef {
let mut new_list = None;
while let Some(list_box) = list {
new_list = Self::push(new_list, list_box.val);
list = list_box.next;
}
new_list
}

#[must_use]
pub fn from_slice(slice: &[i32]) -> ListNodeRef {
pub fn from_slice(slice: &[i32]) -> NodeLink {
let mut list = None;
for x in slice.iter().rev() {
list = Self::push(list, *x);
list = Some(Box::new(ListNode {
val: *x,
next: list,
}));
}
list
}
}

fn solution1(l1: ListNodeRef, l2: ListNodeRef) -> ListNodeRef {
let mut result = None;
let mut carrier = 0;
let mut l1 = l1;
let mut l2 = l2;
fn solution1(l1: NodeLink, l2: NodeLink) -> NodeLink {
let mut l3 = Some(Box::new(ListNode::new(0)));
let mut l1 = &l1;
let mut l2 = &l2;
let mut tail = l3.as_mut().unwrap();
let mut carry = 0;

loop {
if l1.is_none() {
result = ListNode::append_with_carrier(result, l2, carrier);
break;
let mut sum = carry;
if let Some(l1_box) = l1 {
sum += l1_box.val;
l1 = &l1_box.next;
}
if let Some(l2_box) = l2 {
sum += l2_box.val;
l2 = &l2_box.next;
}
if l2.is_none() {
result = ListNode::append_with_carrier(result, l1, carrier);
carry = sum / 10;
tail.val = sum % 10;

if l1.is_none() && l2.is_none() {
if carry != 0 {
tail.next = Some(Box::new(ListNode::new(carry)));
}
break;
}
let l1_box = l1.unwrap();
let l2_box = l2.unwrap();
let sum = l1_box.val + l2_box.val + carrier;
let remainder = sum % 10;
carrier = sum / 10;
result = ListNode::push(result, remainder);

l1 = l1_box.next;
l2 = l2_box.next;

tail.next = Some(Box::new(ListNode::new(carry)));
tail = tail.next.as_mut().unwrap();
}

ListNode::reverse(result)
l3
}

fn main() {
fn check_solution1() {
let l1 = ListNode::from_slice(&[2, 4, 3]);
let l2 = ListNode::from_slice(&[5, 6, 4]);
assert_eq!(solution1(l1, l2), ListNode::from_slice(&[7, 0, 8]));
Expand All @@ -116,17 +82,16 @@ fn main() {
);
}

fn main() {
check_solution1();
}

#[cfg(test)]
mod tests {
use super::{solution1, ListNode};
use super::check_solution1;

#[test]
fn test_solution1() {
let l1 = ListNode::from_slice(&[9, 9, 9, 9, 9, 9, 9]);
let l2 = ListNode::from_slice(&[9, 9, 9, 9]);
assert_eq!(
solution1(l1, l2),
ListNode::from_slice(&[8, 9, 9, 9, 0, 0, 0, 1])
);
check_solution1();
}
}

0 comments on commit 70a587e

Please sign in to comment.