use std::option::Option;
use std::boxed::Box;
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct ListNode {
pub val: i32,
pub next: Option<Box<ListNode>>,
}
impl ListNode {
#[inline]
fn new(val: i32) -> Self {
ListNode { next: None, val }
}
}
fn add_two_numbers(
l1: Option<Box<ListNode>>,
l2: Option<Box<ListNode>>,
) -> Option<Box<ListNode>> {
let mut p1 = l1;
let mut p2 = l2;
let mut carry = 0;
let mut dummy_head = Box::new(ListNode::new(0));
let mut current = &mut dummy_head;
while p1.is_some() || p2.is_some() || carry != 0 {
let val1 = p1.as_ref().map_or(0, |node| node.val);
let val2 = p2.as_ref().map_or(0, |node| node.val);
let sum = val1 + val2 + carry;
carry = sum / 10;
let digit = sum % 10;
current.next = Some(Box::new(ListNode::new(digit)));
current = current.next.as_mut().unwrap();
if let Some(node) = p1 {
p1 = node.next;
} else {
p1 = None;
}
if let Some(node) = p2 {
p2 = node.next;
} else {
p2 = None;
}
}
dummy_head.next
}
fn build_list(nums: &[i32]) -> Option<Box<ListNode>> {
let mut head = None;
for &num in nums.iter().rev() {
let mut node = Box::new(ListNode::new(num));
node.next = head;
head = Some(node);
}
head
}
fn print_list(list: &Option<Box<ListNode>>) {
let mut current = list.as_ref();
while let Some(node) = current {
print!("{}", node.val);
if node.next.is_some() {
print!(" -> ");
}
current = node.next.as_ref();
}
println!(" -> null");
}
fn main() {
let l1 = build_list(&[2, 4, 3]);
let l2 = build_list(&[5, 6, 4]);
let result = add_two_numbers(l1, l2);
print_list(&result);
}while p1.is_some() || p2.is_some() || carry != 0 {
continue adding while there are digits or carry
let val1 = p1.as_ref().map_or(0, |node| node.val);
get current digit from first list or 0 if none
let val2 = p2.as_ref().map_or(0, |node| node.val);
get current digit from second list or 0 if none
let sum = val1 + val2 + carry;
sum digits plus carry
calculate carry for next digit
digit to store in current node
current.next = Some(Box::new(ListNode::new(digit)));
append new node with digit to result list
current = current.next.as_mut().unwrap();
move current pointer to new node
if let Some(node) = p1 { p1 = node.next; } else { p1 = None; }
advance pointer in first list
if let Some(node) = p2 { p2 = node.next; } else { p2 = None; }
advance pointer in second list