Guest User

Untitled

a guest
Dec 19th, 2018
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.45 KB | None | 0 0
  1. #![allow(unused_imports)]
  2. extern crate regex;
  3. #[macro_use]
  4. extern crate lazy_static;
  5. extern crate itertools;
  6. extern crate pbr;
  7. extern crate colored;
  8. use std::collections::VecDeque;
  9. use itertools::Itertools;
  10. use pbr::ProgressBar;
  11. use regex::Regex;
  12. use std::collections::HashMap;
  13. use std::collections::HashSet;
  14. use std::fs::File;
  15. use std::io::Read;
  16. use colored::*;
  17.  
  18. #[derive(Debug, Copy, Clone)]
  19. enum OpType {
  20. add,
  21. set,
  22. mul,
  23. ban,
  24. bor,
  25. gt,
  26. eq
  27. }
  28.  
  29. #[derive(Debug, Copy, Clone)]
  30. enum Mode {
  31. Value,
  32. Register
  33. }
  34.  
  35. #[derive(Debug, Copy, Clone)]
  36. struct Instruction {
  37. op: OpType,
  38. mode_a: Mode,
  39. mode_b: Mode,
  40. a: i32,
  41. b: i32,
  42. c: i32
  43. }
  44.  
  45. #[derive(Debug)]
  46. struct Program {
  47. ip_register: usize,
  48. instructions: Vec<Instruction>
  49. }
  50.  
  51. fn resolve(registers: &[i32], mode: Mode, value: i32) -> i32 {
  52. match mode {
  53. Mode::Value => value,
  54. Mode::Register => registers[value as usize]
  55. }
  56. }
  57.  
  58. impl Program {
  59. fn execute(&self) -> i32 {
  60. let mut registers = vec![0i32; 6];
  61.  
  62. registers[0] = 1;
  63.  
  64. let mut ip = 0;
  65. loop {
  66. registers[self.ip_register] = ip;
  67.  
  68. if ip == 2 && registers[3] != 0 {
  69. if registers[5] % registers[3] == 0 {
  70. registers[0] += registers[3];
  71. }
  72. registers[2] = 0;
  73. registers[1] = registers[5];
  74. ip = 12;
  75. continue;
  76. }
  77.  
  78. if ip as usize >= self.instructions.len() {
  79. break;
  80. }
  81. let instruction = self.instructions[ip as usize];
  82.  
  83. println!("{} {:?} {:?}", ip, registers, instruction);
  84. let value_a = resolve(&registers, instruction.mode_a, instruction.a);
  85. let value_b = resolve(&registers, instruction.mode_b, instruction.b);
  86.  
  87. let result = match instruction.op {
  88. OpType::add => value_a + value_b,
  89. OpType::mul => value_a * value_b,
  90. OpType::ban => value_a & value_b,
  91. OpType::bor => value_a | value_b,
  92. OpType::gt => (value_a > value_b) as i32,
  93. OpType::eq => (value_a == value_b) as i32,
  94. OpType::set => value_a
  95. };
  96.  
  97. registers[instruction.c as usize] = result;
  98.  
  99. ip = registers[self.ip_register];
  100. ip += 1;
  101.  
  102. }
  103. registers[0]
  104. }
  105. }
  106.  
  107. fn parse_op(op: &str) -> (OpType, Mode, Mode) {
  108. match op {
  109. "addr" => (OpType::add, Mode::Register, Mode::Register),
  110. "addi" => (OpType::add, Mode::Register, Mode::Value),
  111. "mulr" => (OpType::mul, Mode::Register, Mode::Register),
  112. "muli" => (OpType::mul, Mode::Register, Mode::Value),
  113. "banr" => (OpType::ban, Mode::Register, Mode::Register),
  114. "bani" => (OpType::ban, Mode::Register, Mode::Value),
  115. "borr" => (OpType::bor, Mode::Register, Mode::Register),
  116. "bori" => (OpType::bor, Mode::Register, Mode::Value),
  117. "setr" => (OpType::set, Mode::Register, Mode::Value),
  118. "seti" => (OpType::set, Mode::Value, Mode::Value),
  119. "gtir" => (OpType::gt, Mode::Value, Mode::Register),
  120. "gtri" => (OpType::gt, Mode::Register, Mode::Value),
  121. "gtrr" => (OpType::gt, Mode::Register, Mode::Register),
  122. "eqir" => (OpType::eq, Mode::Value, Mode::Register),
  123. "eqri" => (OpType::eq, Mode::Register, Mode::Value),
  124. "eqrr" => (OpType::eq, Mode::Register, Mode::Register),
  125. _ => panic!("{}", op)
  126. }
  127. }
  128.  
  129. fn parse(text: &str) -> Program {
  130. let mut lines = text.lines();
  131.  
  132. let ip_line = lines.next().unwrap();
  133. assert!(ip_line.starts_with("#ip"));
  134. let ip_register: usize = ip_line.split_whitespace().collect_vec()[1].parse().unwrap();
  135.  
  136. let instructions = lines.map(|line| {
  137. let parts = line.split_whitespace().collect_vec();
  138. let (op, mode_a, mode_b) = parse_op(parts[0]);
  139. Instruction {
  140. op,mode_a,mode_b, a: parts[1].parse().unwrap(),
  141. b: parts[2].parse().unwrap(),
  142. c: parts[3].parse().unwrap()
  143. }
  144. }).collect();
  145.  
  146. Program {ip_register,instructions}
  147. }
  148.  
  149.  
  150. mod test {
  151. use super::*;
  152.  
  153. #[test]
  154. fn test_it() {
  155. let text= "#ip 0
  156. seti 5 0 1
  157. seti 6 0 2
  158. addi 0 1 0
  159. addr 1 2 3
  160. setr 1 0 0
  161. seti 8 0 4
  162. seti 9 0 5";
  163.  
  164. let program = parse(text);
  165. assert_eq!(program.execute(), 7);
  166. }
  167. }
  168.  
  169. fn main() {
  170. let text = include_str!("input.txt");
  171. let program = parse(text);
  172. println!("{}", program.execute());
  173. }
Add Comment
Please, Sign In to add comment