commit
c2312bcab1
@ -0,0 +1,4 @@
|
|||||||
|
[[package]]
|
||||||
|
name = "imposters"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "imposters"
|
name = "imposters"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Jason Staten <jason.staten@domo.com>"]
|
authors = ["Jason Staten <jstaten07@gmail.com>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
ISC License (ISC)
|
||||||
|
Copyright (c) 2018, Jason Staten
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for
|
||||||
|
any purpose with or without fee is hereby granted, provided that the
|
||||||
|
above copyright notice and this permission notice appear in all
|
||||||
|
copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||||
|
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||||
|
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||||
|
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||||
|
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
PERFORMANCE OF THIS SOFTWARE.
|
@ -0,0 +1,3 @@
|
|||||||
|
# Rust Turing Machine
|
||||||
|
|
||||||
|
I made a turing machine when reading Impostor's Handbook
|
@ -0,0 +1,72 @@
|
|||||||
|
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||||
|
enum State {
|
||||||
|
Idle,
|
||||||
|
TimeInput,
|
||||||
|
Cook,
|
||||||
|
Pause,
|
||||||
|
Done,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Event {
|
||||||
|
DigitPressed,
|
||||||
|
StopPressed,
|
||||||
|
StartPressed,
|
||||||
|
TimerElapsed,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Microwave {
|
||||||
|
state: State,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Microwave {
|
||||||
|
fn dispatch(&mut self, event: Event) {
|
||||||
|
use self::Event::*;
|
||||||
|
use self::State::*;
|
||||||
|
|
||||||
|
self.state = match (self.state, event) {
|
||||||
|
(Idle, DigitPressed) => TimeInput,
|
||||||
|
(TimeInput, DigitPressed) => TimeInput,
|
||||||
|
(TimeInput, StartPressed) => Cook,
|
||||||
|
(TimeInput, StopPressed) => Idle,
|
||||||
|
(Cook, TimerElapsed) => Done,
|
||||||
|
(Cook, StopPressed) => Pause,
|
||||||
|
(Pause, StartPressed) => Cook,
|
||||||
|
(Pause, StopPressed) => Idle,
|
||||||
|
(Done, StopPressed) => Idle,
|
||||||
|
_ => self.state,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fsm() {
|
||||||
|
use self::Event::*;
|
||||||
|
use self::State::*;
|
||||||
|
|
||||||
|
let mut mic = Microwave { state: Idle };
|
||||||
|
// Punch in numbers
|
||||||
|
mic.dispatch(DigitPressed);
|
||||||
|
mic.dispatch(DigitPressed);
|
||||||
|
mic.dispatch(DigitPressed);
|
||||||
|
assert_eq!(mic.state, TimeInput);
|
||||||
|
|
||||||
|
// Start microwave
|
||||||
|
mic.dispatch(StartPressed);
|
||||||
|
assert_eq!(mic.state, Cook);
|
||||||
|
|
||||||
|
// Check if food is hot
|
||||||
|
mic.dispatch(StopPressed);
|
||||||
|
assert_eq!(mic.state, Pause);
|
||||||
|
|
||||||
|
// Continue cooking
|
||||||
|
mic.dispatch(StartPressed);
|
||||||
|
assert_eq!(mic.state, Cook);
|
||||||
|
|
||||||
|
// Timer finished
|
||||||
|
mic.dispatch(TimerElapsed);
|
||||||
|
assert_eq!(mic.state, Done);
|
||||||
|
|
||||||
|
// Clear "done" message
|
||||||
|
mic.dispatch(StopPressed);
|
||||||
|
assert_eq!(mic.state, Idle);
|
||||||
|
}
|
@ -1,7 +1,2 @@
|
|||||||
#[cfg(test)]
|
pub mod fsm;
|
||||||
mod tests {
|
pub mod turing;
|
||||||
#[test]
|
|
||||||
fn it_works() {
|
|
||||||
assert_eq!(2 + 2, 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -0,0 +1,118 @@
|
|||||||
|
type State = usize;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
enum Cell {
|
||||||
|
Blank,
|
||||||
|
Zero,
|
||||||
|
One,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum Move {
|
||||||
|
Stay,
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Transition {
|
||||||
|
start: State,
|
||||||
|
end: State,
|
||||||
|
read: Cell,
|
||||||
|
write: Cell,
|
||||||
|
operation: Move,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Machine {
|
||||||
|
initial: State,
|
||||||
|
done: State,
|
||||||
|
transitions: Vec<Transition>,
|
||||||
|
}
|
||||||
|
|
||||||
|
type Tape = Vec<Cell>;
|
||||||
|
|
||||||
|
fn run(machine: Machine, code: Tape) -> Tape {
|
||||||
|
let mut position = 0;
|
||||||
|
let mut state = machine.initial;
|
||||||
|
let mut tape = code.to_vec();
|
||||||
|
tape.resize(10, Cell::Blank);
|
||||||
|
|
||||||
|
while state != machine.done {
|
||||||
|
let transition;
|
||||||
|
{
|
||||||
|
let cell = tape.get(position).unwrap_or(&Cell::Blank);
|
||||||
|
transition = machine
|
||||||
|
.transitions
|
||||||
|
.iter()
|
||||||
|
.find(|t| t.start == state && &t.read == cell)
|
||||||
|
.expect("Missing transition");
|
||||||
|
}
|
||||||
|
state = transition.end;
|
||||||
|
tape[position] = transition.write.clone();
|
||||||
|
position = match transition.operation {
|
||||||
|
Move::Left => position - 1,
|
||||||
|
Move::Right => position + 1,
|
||||||
|
Move::Stay => position,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return tape;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_build() {
|
||||||
|
let machine = Machine {
|
||||||
|
initial: 0,
|
||||||
|
done: 2,
|
||||||
|
transitions: vec![
|
||||||
|
Transition {
|
||||||
|
start: 0,
|
||||||
|
end: 0,
|
||||||
|
read: Cell::Zero,
|
||||||
|
write: Cell::Zero,
|
||||||
|
operation: Move::Right,
|
||||||
|
},
|
||||||
|
Transition {
|
||||||
|
start: 0,
|
||||||
|
end: 0,
|
||||||
|
read: Cell::One,
|
||||||
|
write: Cell::One,
|
||||||
|
operation: Move::Right,
|
||||||
|
},
|
||||||
|
Transition {
|
||||||
|
start: 0,
|
||||||
|
end: 1,
|
||||||
|
read: Cell::Blank,
|
||||||
|
write: Cell::Blank,
|
||||||
|
operation: Move::Left,
|
||||||
|
},
|
||||||
|
Transition {
|
||||||
|
start: 1,
|
||||||
|
end: 1,
|
||||||
|
read: Cell::One,
|
||||||
|
write: Cell::Zero,
|
||||||
|
operation: Move::Left,
|
||||||
|
},
|
||||||
|
Transition {
|
||||||
|
start: 1,
|
||||||
|
end: 2,
|
||||||
|
read: Cell::Zero,
|
||||||
|
write: Cell::One,
|
||||||
|
operation: Move::Stay,
|
||||||
|
},
|
||||||
|
Transition {
|
||||||
|
start: 1,
|
||||||
|
end: 2,
|
||||||
|
read: Cell::Blank,
|
||||||
|
write: Cell::One,
|
||||||
|
operation: Move::Stay,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = run(machine, vec![Cell::One, Cell::One, Cell::Zero, Cell::One]);
|
||||||
|
println!("{:?}", result);
|
||||||
|
|
||||||
|
let mut expected = vec![Cell::One, Cell::One, Cell::One, Cell::Zero];
|
||||||
|
expected.resize(10, Cell::Blank);
|
||||||
|
assert_eq!(result, expected);
|
||||||
|
}
|
Loading…
Reference in new issue