use std::sync::Arc;
use std::marker::PhantomData;
use crate::list::*;
enum QueueNode<E: Clone> {
Empty,
Node { back: L<E>, front: L<E> },
}
use QueueNode::*;
type N<E> = Arc<QueueNode<E>>;
type L<E> = List<E>;
fn empty<E: Clone>() -> N<E> {
Arc::new(Empty)
}
fn node<E: Clone>(back: L<E>, front: L<E>) -> N<E> {
match (back.len(), front.len()) {
(0, 0) => empty(),
_ => Arc::new(Node { back, front }),
}
}
fn enqueue<E: Clone>(q: &N<E>, e: E) -> N<E> {
match q.as_ref() {
Empty => node(L::empty().push(e), L::empty()),
Node { back: b, front: f } => node(b.push(e), f.clone()),
}
}
fn dequeue<E: Clone>(q: &N<E>) -> (E, N<E>) {
match q.as_ref() {
Empty => panic!("queue is empty"),
Node { back: b, front: f } => match (b.len(), f.len()) {
(0, 0) => unreachable!("node() invariant violated: Node should never have both lists empty"),
(_, 0) => {
let l = b.rev();
let p = l.pop();
(l.top().clone(), node(L::empty(), p))
}
(_, _) => {
let p = f.pop();
(f.top().clone(), node(b.clone(), p))
}
},
}
}
fn len<E: Clone>(q: &N<E>) -> usize {
match q.as_ref() {
Empty => 0,
Node { back: b, front: f } => b.len() + f.len(),
}
}
fn to_vec<E: Clone>(l: &N<E>) -> Vec<E> {
let mut v = Vec::new();
let mut n = l.clone();
loop {
match n.as_ref() {
Empty => return v,
_ => {
let (e, nn) = dequeue(&n);
v.push(e.clone());
n = nn;
}
}
}
}
#[derive(Clone)]
pub struct Queue<E: Clone> {
n: N<E>,
}
impl<E: Clone> Queue<E> {
pub fn empty() -> Self {
Self { n: empty() }
}
pub fn enqueue(&self, e: E) -> Self {
Self {
n: enqueue(&self.n, e),
}
}
pub fn dequeue(&self) -> (E, Self) {
let (e, n) = dequeue(&self.n);
(e, Self { n })
}
pub fn is_empty(&self) -> bool {
len(&self.n) == 0
}
pub fn len(&self) -> usize {
len(&self.n)
}
pub fn to_vec(&self) -> Vec<E> {
to_vec(&self.n)
}
pub fn iter(&self) -> QueueIter<E> {
QueueIter {
queue: self.n.clone(),
_phantom: PhantomData::default(),
}
}
}
pub struct QueueIter<'a, E: Clone> {
queue: N<E>,
_phantom: PhantomData<&'a E>,
}
impl<'a, E: Clone> std::iter::Iterator for QueueIter<'a, E> {
type Item = E;
fn next(&mut self) -> Option<Self::Item> {
match self.queue.as_ref() {
Empty => None,
_ => {
let (elem, new_queue) = dequeue(&self.queue);
self.queue = new_queue;
Some(elem)
}
}
}
}
#[cfg(test)]
mod tests {
use crate::queue::*;
static mut SEED: i64 = 777;
fn rand() -> i32 {
unsafe {
SEED = SEED.wrapping_mul(1664525).wrapping_add(1013904223);
(SEED >> 24) as i32
}
}
#[test]
fn enqueue() {
let mut elements = Vec::new();
let mut l = Queue::empty();
for _ in 0..1000 {
let e = rand();
elements.push(e);
l = l.enqueue(e);
}
assert_eq!(elements.len(), 1000);
assert_eq!(elements.len(), l.len());
let queue_elems = l.to_vec();
for i in 0..1000 {
assert_eq!(queue_elems[i], elements[i]);
}
}
#[test]
fn dequeue() {
let mut elements = Vec::new();
let mut l = Queue::empty();
for _ in 0..100000 {
let e = rand();
elements.push(e);
l = l.enqueue(e);
}
assert_eq!(elements.len(), 100000);
assert_eq!(elements.len(), l.len());
let list_elems = l.to_vec();
for i in 0..100000 {
assert_eq!(list_elems[i], elements[i]);
}
for i in 0..50000 {
let (e, n) = l.dequeue();
let e2 = elements[i];
assert_eq!(e, e2);
l = n;
}
assert_eq!(l.len(), 50000);
let queue_elems = l.to_vec();
for i in 0..50000 {
assert_eq!(queue_elems[i], elements[i + 50000]);
}
}
#[test]
fn iter() {
let mut elements = Vec::new();
let mut q = Queue::empty();
for _ in 0..1000 {
let e = rand();
elements.push(e);
q = q.enqueue(e);
}
assert_eq!(elements.len(), 1000);
assert_eq!(elements.len(), q.len());
let mut count = 0;
for elem in q.iter() {
assert_eq!(elem, elements[count]);
count += 1;
}
assert_eq!(count, 1000);
let collected: Vec<i32> = q.iter().collect();
assert_eq!(collected, elements);
}
}