Skip to content

Instantly share code, notes, and snippets.

@thiagopnts
Created April 14, 2016 16:21
Show Gist options
  • Select an option

  • Save thiagopnts/fab6c0ddc32a229d385795816ba1ff0a to your computer and use it in GitHub Desktop.

Select an option

Save thiagopnts/fab6c0ddc32a229d385795816ba1ff0a to your computer and use it in GitHub Desktop.
#[derive(PartialEq, Debug)]
enum Op {
Push(i64),
Pop,
Sum,
Sumx,
UnknownOp,
}
struct Machine1 {
stack: Vec<i64>
}
impl Machine1 {
pub fn new() -> Self {
Machine1 {stack: vec![]}
}
pub fn dump_stack(self) -> Vec<i64> {
self.stack.clone()
}
pub fn evaluate(&mut self, ops: Vec<&str>) {
let parsed = self.parse(ops);
for op in parsed {
use Op::*;
match op {
Push(value) => {
self.stack.push(value);
},
Pop => { self.stack.pop(); },
Sum => {
let a = self.stack.pop().unwrap();
let b = self.stack.pop().unwrap();
self.stack.push(a + b);
},
Sumx => {
let len = self.stack.pop().unwrap();
let mut i = 0;
let mut sum = 0;
while i < len {
let value = self.stack.pop().unwrap();
sum += value;
i += 1;
}
self.stack.push(sum);
},
UnknownOp => panic!("invalid instruction"),
};
}
}
fn parse(&mut self, ops: Vec<&str>) -> Vec<Op> {
let mut parsed_ops: Vec<Op> = vec!();
let mut i = 0;
while i < ops.len() {
let op = match ops[i].clone() {
"PUSH" => {
i += 1;
let value = ops[i];
Op::Push(value.parse::<i64>().unwrap())
},
"POP" => Op::Pop,
"SUM" => Op::Sum,
"SUMX" => Op::Sumx,
_ => Op::UnknownOp,
};
parsed_ops.push(op);
i += 1;
}
parsed_ops
}
}
#[test]
fn test_init() {
let machine = Machine1::new();
let dump = machine.dump_stack();
assert!(dump == vec![]);
}
#[test]
fn test_evaluate1() {
let mut machine = Machine1::new();
machine.evaluate(vec!["PUSH", "10"]);
let dump = machine.dump_stack();
assert!(dump == vec![10]);
}
#[test]
fn test_evaluate2() {
let mut machine = Machine1::new();
machine.evaluate(vec!["PUSH", "10", "POP"]);
let dump = machine.dump_stack();
assert!(dump == vec![]);
}
#[test]
fn test_evaluate3() {
let mut machine = Machine1::new();
machine.evaluate(vec!["PUSH", "11", "PUSH", "22", "PUSH", "33", "SUM"]);
let dump = machine.dump_stack();
assert!(dump == vec![11, 55]);
}
#[test]
fn test_evaluate4() {
let mut machine = Machine1::new();
machine.evaluate(vec!["PUSH", "4", "PUSH", "5", "PUSH", "6", "PUSH", "3", "SUMX"]);
let dump = machine.dump_stack();
assert!(dump == vec![15]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment