Advertisement
Guest User

Untitled

a guest
Dec 11th, 2019
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.79 KB | None | 0 0
  1. use std::env;
  2. use std::fs;
  3.  
  4. fn tokenize(filepath: &String) -> Vec<i64> {
  5. let contents = fs::read_to_string(filepath).expect("Error reading file");
  6. return contents
  7. .split(',')
  8. .map(|x|
  9. match x.parse::<i64>() {
  10. Ok(x) => x,
  11. Err(_e) => {
  12. //println!("Error: {} for input: {}", _e, x);
  13. return 0;
  14. }
  15. })
  16. .collect();
  17. }
  18.  
  19. fn get_operation_size(op: &i64) -> usize {
  20. match op {
  21. 1 | 2 | 7 | 8 => 4,
  22. 3 | 4 | 9 => 2,
  23. 5 | 6 => 3,
  24. _ => panic!("Unexpected operation"),
  25. }
  26. }
  27.  
  28. fn get_addressing(input: i64, op_size: usize) -> Vec<i64> {
  29. let mut temp = input;
  30. let mut addressing: Vec<i64> = Vec::new();
  31.  
  32. for _ in 0..op_size - 1 {
  33. addressing.push(temp % 10);
  34. temp /= 10;
  35. }
  36.  
  37. return addressing;
  38. }
  39.  
  40. struct Machine {
  41. program: Vec<i64>,
  42. ip: usize,
  43. relative_base: i64,
  44. input: i64,
  45. }
  46.  
  47. impl Machine {
  48. fn get_value(&mut self, addressing: i64, pos: usize) -> i64 {
  49. match addressing {
  50. 0 => {
  51. let source = self.program[pos] as usize;
  52.  
  53. self.memory_check(source);
  54. self.program[source]
  55. }
  56. 1 => self.program[pos],
  57. 2 => {
  58. let source = (self.relative_base + self.program[pos]) as usize;
  59.  
  60. self.memory_check(source);
  61. self.program[source]
  62. }
  63. _ => panic!("Unexpected addressing"),
  64. }
  65. }
  66.  
  67. fn get_index(&mut self, addressing: i64, pos: usize) -> usize {
  68. match addressing {
  69. 0 => {
  70. let source = self.program[pos] as usize;
  71.  
  72. self.memory_check(source);
  73. source
  74. }
  75. 1 => pos,
  76. 2 => {
  77. let source = (self.relative_base + self.program[pos]) as usize;
  78.  
  79. self.memory_check(source);
  80. source
  81. }
  82. _ => panic!("Unexpected addressing"),
  83. }
  84. }
  85.  
  86. fn memory_check(&mut self, dest: usize) {
  87. if dest >= self.program.len() {
  88. self.program.resize(dest + 1, 0);
  89. }
  90. }
  91.  
  92. fn write_to_memory(&mut self, dest: usize, input: i64) {
  93. self.memory_check(dest);
  94.  
  95. self.program[dest] = input;
  96. }
  97.  
  98. fn execute_operation(&mut self, op: i64, addressing: Vec<i64>) {
  99. match op {
  100. 1 => {
  101. let lhs = self.get_value(addressing[0], self.ip + 1);
  102. let rhs = self.get_value(addressing[1], self.ip + 2);
  103. let dest = self.get_index(addressing[2], self.ip + 3);
  104.  
  105. self.write_to_memory(dest, lhs + rhs);
  106. self.ip += get_operation_size(&op);
  107. }
  108. 2 => {
  109. let lhs = self.get_value(addressing[0], self.ip + 1);
  110. let rhs = self.get_value(addressing[1], self.ip + 2);
  111. let dest = self.get_index(addressing[2], self.ip + 3);
  112.  
  113. self.write_to_memory(dest, lhs * rhs);
  114. self.ip += get_operation_size(&op);
  115. }
  116. 3 => {
  117. let dest = self.get_index(addressing[0], self.ip + 1) as usize;
  118.  
  119. self.write_to_memory(dest, self.input);
  120. self.ip += get_operation_size(&op);
  121. }
  122. 4 => {
  123. let source = self.get_value(addressing[0], self.ip + 1);
  124.  
  125. println!("{}", source);
  126. self.ip += get_operation_size(&op);
  127. }
  128. 5 => {
  129. let condition = self.get_value(addressing[0], self.ip + 1);
  130. let dest = self.get_value(addressing[1], self.ip + 2);
  131.  
  132. if condition != 0 {
  133. self.ip = dest as usize;
  134. } else {
  135. self.ip += get_operation_size(&op);
  136. }
  137. }
  138. 6 => {
  139. let condition = self.get_value(addressing[0], self.ip + 1);
  140. let dest = self.get_value(addressing[1], self.ip + 2);
  141.  
  142. if condition == 0 {
  143. self.ip = dest as usize;
  144. } else {
  145. self.ip += get_operation_size(&op);
  146. }
  147. }
  148. 7 => {
  149. let lhs = self.get_value(addressing[0], self.ip + 1);
  150. let rhs = self.get_value(addressing[1], self.ip + 2);
  151. let dest = self.get_index(addressing[2], self.ip + 3);
  152.  
  153. if lhs < rhs {
  154. self.write_to_memory(dest, 1);
  155. } else {
  156. self.write_to_memory(dest, 0);
  157. }
  158. self.ip += get_operation_size(&op);
  159. }
  160. 8 => {
  161. let lhs = self.get_value(addressing[0], self.ip + 1);
  162. let rhs = self.get_value(addressing[1], self.ip + 2);
  163. let dest = self.get_index(addressing[2], self.ip + 3);
  164.  
  165. if lhs == rhs {
  166. self.write_to_memory(dest, 1);
  167. } else {
  168. self.write_to_memory(dest, 0);
  169. }
  170. self.ip += get_operation_size(&op);
  171. }
  172. 9 => {
  173. let adjustment = self.get_value(addressing[0], self.ip + 1);
  174. self.relative_base += adjustment;
  175.  
  176. self.ip += get_operation_size(&op);
  177. }
  178. _ => {
  179. panic!("Unexpected operation");
  180. }
  181. }
  182. }
  183.  
  184. fn execute_program(&mut self) {
  185. while self.ip < self.program.len() {
  186. if self.program[self.ip] == 99 {
  187. break;
  188. }
  189. let op = self.program[self.ip] % 100;
  190. let op_size = get_operation_size(&op);
  191. let addressing_modes = self.program[self.ip] / 100;
  192. self.execute_operation(op, get_addressing(addressing_modes, op_size));
  193. }
  194. }
  195. }
  196.  
  197. fn main() {
  198. let args: Vec<String> = env::args().collect();
  199. if args.len() < 3 {
  200. println!("Provide filename and input");
  201. return;
  202. }
  203. //
  204. let filepath = &args[1];
  205. //let input: i64 = args[2].parse().unwrap();
  206.  
  207. let filename = "C:/Users/tantczak/Desktop/IdeaProjects/excercise190726/target/debug/program.txt";
  208. let _contents = fs::read_to_string(filename)
  209. .expect("Something went wrong reading the file");
  210. //println!("File content:\n{}", _contents);
  211.  
  212.  
  213. let input = 1;
  214. let program = tokenize(filepath);
  215. let mut machine = Machine {
  216. program: program,
  217. ip: 0,
  218. relative_base: 0,
  219. input: input,
  220. };
  221. machine.execute_program();
  222. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement