This commit is contained in:
lilymonade 2025-03-13 21:18:04 +01:00
parent 1b850fc73e
commit c741e49e78
Signed by: lilymonade
GPG Key ID: F8967EC454DBDCB6
4 changed files with 115 additions and 0 deletions

View File

@ -1 +1,2 @@
pub mod access;
pub mod compute;

View File

@ -0,0 +1,48 @@
pub enum Operation {
Push(f32),
Binary(Binary),
}
pub enum Binary {
Add,
Sub,
Mul,
Div,
}
#[derive(PartialEq, Debug)]
pub enum ComputeError {
NotEnoughData,
DivisionByZero,
}
pub fn compute(operations: &[Operation]) -> Result<f32, ComputeError> {
let mut stack = vec![];
for operation in operations {
match operation {
Operation::Push(n) => stack.push(*n),
Operation::Binary(op) => {
let b = stack.pop();
let a = stack.pop();
let r = match (a, b) {
(Some(a), Some(b)) => match op {
Binary::Add => a + b,
Binary::Mul => a * b,
Binary::Div => {
if b == 0.0 {
return Err(ComputeError::DivisionByZero);
}
a / b
}
Binary::Sub => a - b,
},
_ => return Err(ComputeError::NotEnoughData),
};
stack.push(r);
}
}
}
stack.pop().ok_or(ComputeError::NotEnoughData)
}

View File

@ -0,0 +1,58 @@
use subject_source::vec::compute::*;
#[test]
pub fn compute_empty() {
assert_eq!(compute(&[]), Err(ComputeError::NotEnoughData));
}
#[test]
pub fn compute_too_many_ops() {
assert_eq!(
compute(&[Operation::Push(1.0), Operation::Binary(Binary::Add)]),
Err(ComputeError::NotEnoughData)
);
}
#[test]
pub fn compute_division_by_zero_push() {
assert_eq!(
compute(&[
Operation::Push(1.0),
Operation::Push(0.0),
Operation::Binary(Binary::Div)
]),
Err(ComputeError::DivisionByZero)
);
}
#[test]
pub fn compute_division_by_zero_operation() {
assert_eq!(
compute(&[
Operation::Push(1.0),
Operation::Push(1.0),
Operation::Push(1.0),
Operation::Binary(Binary::Sub),
Operation::Binary(Binary::Div)
]),
Err(ComputeError::DivisionByZero)
);
}
#[test]
pub fn compute_all_ops() {
assert_eq!(
compute(&[
Operation::Push(1.0),
Operation::Push(3.0),
Operation::Push(2.0),
Operation::Binary(Binary::Sub),
Operation::Push(5.0),
Operation::Binary(Binary::Mul),
Operation::Binary(Binary::Add),
Operation::Push(2.0),
Operation::Binary(Binary::Div),
]),
Ok(3.0),
);
}

View File

@ -16,6 +16,14 @@ if vec.len() < 1 {
Try to implement these functions using non-panicking methods like [`last`](https://doc.rust-lang.org/std/primitive.slice.html#method.last), [`last_chunk`](https://doc.rust-lang.org/std/primitive.slice.html#method.last_chunk), or [`get`](https://doc.rust-lang.org/std/primitive.slice.html#method.get).
```note
Don't be afraid of the `get` function prototype, look at the examples, they are fairly simple, it's just that `get` can work on multiple types, allowing for slice indexing as well as single element indexing.
```
```note
You may want to look at the [`sort`](https://doc.rust-lang.org/std/primitive.slice.html#method.sort) and [`to_vec`](https://doc.rust-lang.org/std/primitive.slice.html#method.to_vec) functions for the median.
```
```prototype
/// Add the last two numbers of the input slice.
///