#[cfg(not(feature = "no_std"))]
use core::{fmt::Display, ptr::NonNull};
#[cfg(not(feature = "no_std"))]
#[derive(Debug)]
struct Node<T> {
next: Option<NonNull<Node<T>>>,
prev: Option<NonNull<Node<T>>>,
element: T,
}
#[cfg(not(feature = "no_std"))]
#[derive(Debug)]
pub struct LinkedList<T> {
head: Option<NonNull<Node<T>>>,
tail: Option<NonNull<Node<T>>>,
len: usize,
marker: core::marker::PhantomData<Box<Node<T>>>,
}
#[cfg(not(feature = "no_std"))]
impl<T> Node<T> {
fn new(element: T) -> Self {
return Node {
next: None,
prev: None,
element,
};
}
fn into_element(self) -> T {
return self.element; }
}
#[cfg(not(feature = "no_std"))]
impl<T> Default for LinkedList<T> {
fn default() -> Self {
return Self::new();
}
}
#[cfg(not(feature = "no_std"))]
impl<T> LinkedList<T> {
pub const fn new() -> Self {
return LinkedList {
head: None,
tail: None,
len: 0usize,
marker: core::marker::PhantomData,
};
}
pub fn back(&self) -> Option<&T> {
if let Some(tail) = self.tail {
unsafe {
return Some(&(*tail.as_ptr()).element);
}
} else {
return None;
}
}
pub fn front(&self) -> Option<&T> {
if let Some(head) = self.head {
unsafe {
return Some(&(*head.as_ptr()).element);
}
} else {
return None;
}
}
pub fn push_back(&mut self, element: T) {
let mut new_node = Box::new(Node::new(element));
new_node.prev = self.tail;
let new_node = NonNull::new(Box::into_raw(new_node));
match self.tail {
Some(node) => {
unsafe {
(*node.as_ptr()).next = new_node;
}
}
None => self.head = new_node,
}
self.tail = new_node;
self.len += 1;
}
pub fn push_front(&mut self, element: T) {
let mut new_node = Box::new(Node::new(element));
new_node.next = self.head;
let new_node = NonNull::new(Box::into_raw(new_node));
match self.head {
Some(node) => {
unsafe {
(*node.as_ptr()).prev = new_node;
}
}
None => self.tail = new_node,
}
self.head = new_node;
self.len += 1;
}
pub fn len(&self) -> usize {
return self.len;
}
pub fn insert(&mut self, index: usize, element: T) -> Result<(), String> {
if self.len < index {
return Err(format!(
"LinkedList len is {}, but index is {}",
self.len, index
));
}
if index == 0 || self.head.is_none() {
self.push_front(element);
return Ok(());
}
if self.len == index {
self.push_back(element);
return Ok(());
}
if let Some(mut current_node) = self.head {
for _ in 0..index {
unsafe {
match (*current_node.as_ptr()).next {
None => {
return Err(format!(
"LinkedList len is {}, but index is {}",
self.len, index
))
}
Some(next_ptr) => current_node = next_ptr,
}
}
}
let mut new_node = Box::new(Node::new(element));
unsafe {
new_node.prev = (*current_node.as_ptr()).prev;
new_node.next = Some(current_node);
}
unsafe {
if let Some(old_prev) = (*current_node.as_ptr()).prev {
let node_ptr = NonNull::new(Box::into_raw(new_node));
(*old_prev.as_ptr()).next = node_ptr;
(*current_node.as_ptr()).prev = node_ptr;
self.len += 1;
}
}
}
Ok(())
}
pub fn pop_front(&mut self) -> Option<T> {
if let Some(node) = self.head {
unsafe {
if let Some(new_head) = (*node.as_ptr()).next {
(*new_head.as_ptr()).prev = None;
let node = Box::from_raw(node.as_ptr());
self.head = Some(new_head);
return Some(node.into_element());
} else {
if let Some(head) = self.head {
self.head = None;
let node = Box::from_raw(head.as_ptr());
return Some(node.into_element());
}
}
}
}
return None;
}
pub fn pop_back(&mut self) -> Option<T> {
if let Some(node) = self.tail {
unsafe {
if let Some(new_tail) = (*node.as_ptr()).prev {
(*new_tail.as_ptr()).next = None;
let node = Box::from_raw(node.as_ptr());
self.tail = Some(new_tail);
return Some(node.into_element());
} else {
if let Some(tail) = self.tail {
self.tail = None;
let node = Box::from_raw(tail.as_ptr());
return Some(node.into_element());
}
}
}
}
return None;
}
pub fn pop(&mut self, index: usize) -> Option<T> {
if self.len < index {
return None;
}
if index == 0 || self.head.is_none() {
return self.pop_front();
}
if self.len == index {
return self.pop_back();
}
if let Some(mut current_node) = self.head {
for _ in 0..index {
unsafe {
match (*current_node.as_ptr()).next {
None => {
return None;
}
Some(next_ptr) => current_node = next_ptr,
}
}
}
unsafe {
if let Some(prev_node) = (*current_node.as_ptr()).prev {
if let Some(next_node) = (*current_node.as_ptr()).next {
(*prev_node.as_ptr()).next = Some(next_node);
(*next_node.as_ptr()).prev = Some(prev_node);
}
}
}
unsafe {
let delete_node = Box::from_raw(current_node.as_ptr());
return Some(delete_node.into_element());
}
}
None
}
pub fn get(&self, index: usize) -> Option<&T> {
if self.len < index || self.head.is_none() {
return None;
}
if index == 0 {
if let Some(element) = self.head {
unsafe {
return Some(&(*element.as_ptr()).element);
}
}
}
if let Some(mut current_node) = self.head {
for _ in 0..index {
unsafe {
match (*current_node.as_ptr()).next {
None => {
return None;
}
Some(next_ptr) => current_node = next_ptr,
}
}
}
unsafe {
return Some(&(*current_node.as_ptr()).element);
}
}
None
}
pub fn to_vec(mut self) -> Vec<T> {
let mut vec = vec![];
while self.head.is_some() {
if let Some(value) = self.pop_front() {
vec.push(value);
}
}
return vec;
}
}
#[cfg(not(feature = "no_std"))]
impl<T> Display for LinkedList<T>
where
T: Display,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if self.len == 0 {
return Ok(());
}
if let Some(mut current_node) = self.head {
unsafe {
write!(f, "{}", (*current_node.as_ptr()).element).unwrap();
}
for _ in 0..self.len {
unsafe {
match (*current_node.as_ptr()).next {
Some(node) => {
write!(f, "->{}", (*node.as_ptr()).element).unwrap();
current_node = node;
}
None => {
break;
}
}
}
}
}
return Ok(());
}
}
#[cfg(not(feature = "no_std"))]
impl<T> Drop for LinkedList<T> {
fn drop(&mut self) {
while self.pop_front().is_some() {}
}
}
#[cfg(not(feature = "no_std"))]
impl<T, const N: usize> From<[T; N]> for LinkedList<T> {
fn from(array: [T; N]) -> Self {
let mut new_linkedlist = LinkedList::new();
for value in array {
new_linkedlist.push_back(value);
}
return new_linkedlist;
}
}
#[cfg(not(feature = "no_std"))]
pub fn add_two_linkedlist(a: LinkedList<i32>, b: LinkedList<i32>) -> LinkedList<i32> {
let mut result = LinkedList::new();
let current = &mut result;
let (mut p1, mut p2) = (a, b);
let mut sum = 0i32;
while p1.front().is_some() || p2.front().is_some() || sum != 0 {
if let Some(value) = p1.pop_front() {
sum += value;
}
if let Some(value) = p2.pop_front() {
sum += value;
}
current.push_back(sum % 10);
sum = sum / 10;
}
return result;
}
#[cfg(not(feature = "no_std"))]
pub fn add_two_binary_linkedlist(a: LinkedList<bool>, b: LinkedList<bool>) -> LinkedList<bool> {
let mut result = LinkedList::new();
let (mut p1, mut p2) = (a, b);
let mut sum = [false; 3];
while p1.front().is_some() || p2.front().is_some() || sum[2] == true {
if let Some(value) = p1.pop_front() {
sum[0] = value;
}
if let Some(value) = p2.pop_front() {
sum[1] = value;
}
let xor1 = sum[0] ^ sum[1];
let add_result = xor1 ^ sum[2]; sum[2] = (xor1 & sum[2]) | (sum[0] & sum[1]); (sum[0], sum[1]) = (false, false); result.push_back(add_result);
}
return result;
}
#[cfg(not(feature = "no_std"))]
#[cfg(test)]
mod add_two_binary_test {
use super::add_two_binary_linkedlist;
use super::LinkedList;
#[test]
fn empty() -> () {
let a: LinkedList<bool> = [].into();
let b: LinkedList<bool> = [].into();
let result = add_two_binary_linkedlist(a, b);
assert_eq!(&result.to_vec(), &[]);
}
#[test]
fn carry() -> () {
let a: LinkedList<bool> = [true].into();
let b: LinkedList<bool> = [true].into();
let result = add_two_binary_linkedlist(a, b);
assert_eq!(&result.to_vec(), &[false, true]);
}
#[test]
fn one() -> () {
let a: LinkedList<bool> = [false].into();
let b: LinkedList<bool> = [true].into();
let result = add_two_binary_linkedlist(a, b);
assert_eq!(&result.to_vec(), &[true]);
}
#[test]
fn two() -> () {
let a: LinkedList<bool> = [true, false].into();
let b: LinkedList<bool> = [true].into();
let result = add_two_binary_linkedlist(a, b);
assert_eq!(&result.to_vec(), &[false, true]);
}
#[test]
fn more() -> () {
let a: LinkedList<bool> = [false, false].into();
let b: LinkedList<bool> = [true].into();
let result = add_two_binary_linkedlist(a, b);
assert_eq!(&result.to_vec(), &[true, false]);
}
#[test]
fn common() -> () {
let a: LinkedList<bool> = [false, false, true, true, false, true].into();
let b: LinkedList<bool> = [true, false, true, false, true, false, true, true].into();
let result = add_two_binary_linkedlist(a, b);
assert_eq!(
&result.to_vec(),
&[true, false, false, false, false, false, false, false, true]
);
}
}
#[cfg(not(feature = "no_std"))]
#[cfg(test)]
mod add_two_linkedlist {
use super::add_two_linkedlist;
use super::LinkedList;
#[test]
fn empty() -> () {
let a: LinkedList<i32> = [].into();
let b: LinkedList<i32> = [].into();
let result = add_two_linkedlist(a, b);
assert_eq!(&result.to_vec(), &[]);
}
#[test]
fn carry() -> () {
let a: LinkedList<i32> = [9].into();
let b: LinkedList<i32> = [8].into();
let result = add_two_linkedlist(a, b);
assert_eq!(&result.to_vec(), &[7, 1]);
}
#[test]
fn one() -> () {
let a: LinkedList<i32> = [2].into();
let b: LinkedList<i32> = [3].into();
let result = add_two_linkedlist(a, b);
assert_eq!(&result.to_vec(), &[5]);
}
#[test]
fn two() -> () {
let a: LinkedList<i32> = [9, 2].into();
let b: LinkedList<i32> = [3, 9].into();
let result = add_two_linkedlist(a, b);
assert_eq!(&result.to_vec(), &[2, 2, 1]);
}
#[test]
fn more() -> () {
let a: LinkedList<i32> = [9, 2, 9, 2].into();
let b: LinkedList<i32> = [3, 9].into();
let result = add_two_linkedlist(a, b);
assert_eq!(&result.to_vec(), &[2, 2, 0, 3]);
}
#[test]
fn common() -> () {
let a: LinkedList<i32> =
[0, 2, 3, 1, 5, 3, 6, 2, 5, 8, 1, 8, 9, 2, 9, 5, 3, 5, 9, 0].into();
let b: LinkedList<i32> =
[8, 2, 3, 6, 2, 1, 6, 2, 9, 1, 5, 1, 6, 5, 8, 2, 3, 1, 5, 2].into();
let result = add_two_linkedlist(a, b);
assert_eq!(
&result.to_vec(),
&[8, 4, 6, 7, 7, 4, 2, 5, 4, 0, 7, 9, 5, 8, 7, 8, 6, 6, 4, 3]
);
}
}