aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
authorReiner Herrmann <reiner@reiner-h.de>2019-10-06 12:45:52 +0200
committerReiner Herrmann <reiner@reiner-h.de>2019-10-06 12:45:52 +0200
commit0742459cb5f82c7b069a3241d52e4984dcf2761e (patch)
treedf7aeae1932d5e9f8e7529072fd86044779a1079 /src/main.rs
parent1d54059ef16a317d2f476bec989276f96a9edf1e (diff)
Optimize program by removing commands that cancel each other
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs
index d93bc5f..75d5d2e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -98,6 +98,23 @@ fn find_loops(commands: &mut Vec<Command>) -> Result<(), String> {
Ok(())
}
+fn optimize(program: &mut Vec<Command>) {
+ let mut remove_pair = |first: Command, second: Command| -> bool {
+ for i in 0 .. program.len() - 1 {
+ if (program[i] == first && program[i+1] == second) ||
+ (program[i] == second && program[i+1] == first) {
+ program.remove(i+1);
+ program.remove(i);
+ return true;
+ }
+ }
+ false
+ };
+
+ while remove_pair(Command::INCPTR, Command::DECPTR) {}
+ while remove_pair(Command::INCVAL, Command::DECVAL) {}
+}
+
fn preprocess(program: &str) -> String {
let allowed_chars = ['>', '<', '+', '-', '.', ',', '[', ']'];
program.chars().filter(|c| allowed_chars.contains(c)).collect()
@@ -129,6 +146,7 @@ fn run() -> Result<(), String> {
Err(e) => return Err(format!("Cannot open file: {}", e)),
};
let mut commands = tokenize(&input);
+ optimize(&mut commands);
find_loops(&mut commands)?;
let mut program = Program{commands};
@@ -220,4 +238,19 @@ mod tests {
let expected = vec!['4' as u8, '2' as u8];
assert_eq!(buf_out.get_ref(), &expected);
}
+
+ #[test]
+ fn test_optimize() {
+ let mut commands = vec![
+ Command::INCPTR, Command::DECPTR,
+ Command::DECPTR, Command::INCPTR,
+ Command::INCVAL, Command::DECVAL,
+ Command::DECVAL, Command::INCVAL,
+ Command::INCPTR, Command::GETC, Command::DECPTR,
+ Command::INCVAL, Command::INCVAL, Command::DECPTR, Command::INCPTR, Command::DECVAL, Command::DECVAL,
+ Command::PUTC, Command::INCVAL,
+ ];
+ optimize(&mut commands);
+ assert_eq!(commands, [Command::INCPTR, Command::GETC, Command::DECPTR, Command::PUTC, Command::INCVAL]);
+ }
}