Advertisement
Guest User

Untitled

a guest
Dec 16th, 2018
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 8.95 KB | None | 0 0
  1. extern crate regex;
  2. use std::env;
  3. use std::process;
  4. use std::fs::File;
  5. use std::io::prelude::*;
  6. use regex::Regex;
  7. use std::fmt::{ Formatter, Debug };
  8. use std::fmt;
  9.  
  10. fn main() {
  11.     let args = env::args().collect();
  12.  
  13.     let filename = parse_filename(&args);
  14.  
  15.     let mut contents = String::new();
  16.     get_contents(&filename, &mut contents);
  17.  
  18.     //println!("{}", contents);
  19.  
  20.     let (samples, program) = parse_content(&contents);
  21.  
  22.     //println!("Samples:\n{:?}\n\nProgram:\n{:?}", samples, program);
  23.  
  24.     let part1 = has3pos(&samples);
  25.  
  26.     println!("Part1: {}", part1);
  27.  
  28.     let opcodes = deduce_opcodes(&samples);
  29.  
  30.     let part2 = execute(program, opcodes)[0];
  31.  
  32.     println!("Part2: {}", part2);
  33.  
  34. }
  35.  
  36. fn execute(program: Program, opcodes: Vec<OpCode>) -> Vec<usize> {
  37.     let mut codes = opcodes.clone();
  38.     codes.sort_by_key(|code| code.num);
  39.     println!("{:?}", codes);
  40.     let mut reg = vec![0,0,0,0];
  41.  
  42.     for line in program.lines.iter() {
  43.         //println!("{:?}", reg);
  44.         let params = line[1..4].to_vec();
  45.         println!("{:?}", line);
  46.         println!("{} {:?}",codes[line[0]].name, params);
  47.         (codes[line[0]].f)(&params,&mut reg);
  48.         //println!("");
  49.     }
  50.  
  51.     reg
  52. }
  53.  
  54. fn deduce_opcodes(samples: &Vec<Sample>) -> Vec<OpCode> {
  55.     let mut opcodes = Vec::new();
  56.     let named_functions = get_named_functions();
  57.  
  58.     let mut candidates = Vec::new();
  59.     for (name, function) in named_functions.iter() {
  60.         let mut possibilities = Vec::new();
  61.         for num in 0..16 {
  62.             let no_possibility = samples.iter()
  63.                 .filter(|sample| sample.code[0] == num)
  64.                 .any(|sample| !sample.could_be(function));
  65.            
  66.             if !no_possibility{
  67.                 let opcode = OpCode {name: name.clone(), num: num, f: *function};
  68.                 possibilities.push(opcode)
  69.             }
  70.         }
  71.         //println!("Possibilities:\n{:?}", possibilities);
  72.         candidates.push(possibilities);
  73.     }
  74.  
  75.     //println!("Candidates:\n{:?}", candidates);
  76.     let mut found = Vec::new();
  77.  
  78.     while found.len() < 16 {
  79.         for possibilities in candidates.iter() {
  80.             let new: Vec<OpCode> = possibilities.iter().cloned().filter(|pos| !found.contains(&pos.num)).collect();
  81.             if new.len() == 1 {
  82.                 opcodes.push(new[0].clone());
  83.                 found.push(new[0].num)
  84.             }
  85.         }
  86.     }
  87.  
  88.     opcodes
  89. }
  90.  
  91. fn get_functions() -> Vec<fn(&Vec<usize>, &mut Vec<usize>)> {
  92.     let mut functions: Vec<fn(&Vec<usize>, &mut Vec<usize>)> = Vec::new();
  93.     functions.push(addi); functions.push(addr);
  94.     functions.push(muli); functions.push(mulr);
  95.     functions.push(bani); functions.push(banr);
  96.     functions.push(bori); functions.push(borr);
  97.     functions.push(seti); functions.push(setr);
  98.     functions.push(gtir); functions.push(gtri); functions.push(gtrr);
  99.     functions.push(eqir); functions.push(eqri); functions.push(eqrr);
  100.     functions
  101. }
  102.  
  103. fn get_named_functions() -> Vec<(String, fn(&Vec<usize>, &mut Vec<usize>))> {
  104.     let mut functions: Vec<(String, fn(&Vec<usize>, &mut Vec<usize>))> = Vec::new();
  105.     functions.push(("addi".to_string(),addi)); functions.push(("addr".to_string(), addr));
  106.     functions.push(("muli".to_string(),muli)); functions.push(("mulr".to_string(),mulr));
  107.     functions.push(("bani".to_string(),bani)); functions.push(("banr".to_string(),banr));
  108.     functions.push(("bori".to_string(),bori)); functions.push(("borr".to_string(),borr));
  109.     functions.push(("seti".to_string(),seti)); functions.push(("setr".to_string(),setr));
  110.     functions.push(("gtir".to_string(),gtir)); functions.push(("gtri".to_string(),gtri)); functions.push(("gtrr".to_string(),gtrr));
  111.     functions.push(("eqir".to_string(),eqir)); functions.push(("eqri".to_string(),eqri)); functions.push(("eqrr".to_string(),eqrr));
  112.     functions
  113. }
  114.  
  115. fn has3pos(samples: &Vec<Sample>) -> i64 {
  116.     let functions = get_functions();
  117.  
  118.     samples.iter().map(|sample| sample.num_candidates(&functions)).filter(|num| *num >= 3).count() as i64
  119.  
  120. }
  121.  
  122. fn parse_content(contents: &str) -> (Vec<Sample>, Program) {
  123.     let mut samples = Vec::new();
  124.     let mut prog = Vec::new();
  125.     let mut lines = contents.trim_right().lines();
  126.     let re = Regex::new(r"(\d+)").unwrap();
  127.  
  128.     while let Some(line) = lines.next() {
  129.          if line.starts_with("Before") {
  130.              let mut before = Vec::new();
  131.              for cap in re.captures_iter(line) {
  132.                  before.push(cap[1].parse::<usize>().unwrap());
  133.              }
  134.              
  135.              let mut code = Vec::new();
  136.              let code_line = lines.next().expect("Wrongly formatted sample");
  137.              for cap in re.captures_iter(code_line) {
  138.                  code.push(cap[1].parse::<usize>().unwrap());
  139.              }
  140.  
  141.              let mut after = Vec::new();
  142.              let after_line = lines.next().expect("Wrongly formatted sample");
  143.              for cap in re.captures_iter(after_line) {
  144.                  after.push(cap[1].parse::<usize>().unwrap());
  145.              }
  146.            
  147.              samples.push(Sample {before, code, after} );
  148.  
  149.          } else {
  150.          if line != "" {
  151.              let mut source = Vec::new();
  152.              for cap in re.captures_iter(line) {
  153.                  source.push(cap[1].parse::<usize>().unwrap());
  154.              }
  155.              prog.push(source);
  156.          }
  157.          }
  158.     }
  159.    
  160.     (samples, Program {lines: prog})
  161. }
  162.  
  163. #[derive(Clone)]
  164. struct OpCode {
  165.     name: String,
  166.     num: usize,
  167.     f: fn(&Vec<usize>, &mut Vec<usize>),
  168. }
  169.  
  170. impl Debug for OpCode {
  171.     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
  172.         write!(f, "OpCode {{ name: {}, num: {} }}", self.name, self.num)
  173.     }
  174.  
  175. }
  176.  
  177. #[derive(Debug)]
  178. struct Sample {
  179.     before: Vec<usize>,
  180.     code: Vec<usize>,
  181.     after: Vec<usize>,
  182. }
  183.  
  184. impl Sample {
  185.     fn could_be(&self, f: impl Fn(&Vec<usize>, &mut Vec<usize>)) -> bool {
  186.         let mut reg = self.before.clone();
  187.         f(&self.code[1..4].to_vec(), &mut reg);
  188.         reg == self.after
  189.     }
  190.  
  191.     fn num_candidates(&self, functions: &Vec<fn(&Vec<usize>, &mut Vec<usize>)>) -> i64 {
  192.         functions.iter().filter(|f| self.could_be(f)).count() as i64
  193.     }
  194. }
  195.  
  196. #[derive(Debug)]
  197. struct Program {
  198.     lines: Vec<Vec<usize>>,
  199. }
  200.  
  201. fn parse_filename(args: &Vec<String>) -> &str {
  202.  
  203.     if args.len() < 2 {
  204.         println!("Too few arguements, please give a filename");
  205.         process::exit(1);
  206.     }
  207.     args.get(1).expect("No filename provided")
  208. }
  209.  
  210. fn get_contents(filename: &str, contents: &mut String) {
  211.     let mut f = File::open(filename).expect("File not found");
  212.  
  213.     f.read_to_string(contents)
  214.         .expect("Something went wrong reading the file");
  215. }
  216.  
  217. fn addr(params: &Vec<usize>, reg: &mut Vec<usize>) {
  218.     if let [a,b,c] = params[0..3] {
  219.         reg[c] = reg[a] + reg[b];
  220.     } else {
  221.         panic!("Wrong amount of paramters to addr")
  222.     }
  223. }
  224.  
  225. fn addi(params: &Vec<usize>, reg: &mut Vec<usize>) {
  226.     if let [a,b,c] = params[0..3] {
  227.         reg[c] = reg[a] + b;
  228.     } else {
  229.         panic!("Wrong amount of paramters to addr")
  230.     }
  231. }
  232.  
  233. fn mulr(params: &Vec<usize>, reg: &mut Vec<usize>) {
  234.     if let [a,b,c] = params[0..3] {
  235.         reg[c] = reg[a] * reg[b];
  236.     } else {
  237.         panic!("Wrong amount of paramters to addr")
  238.     }
  239. }
  240.  
  241. fn muli(params: &Vec<usize>, reg: &mut Vec<usize>) {
  242.     if let [a,b,c] = params[0..3] {
  243.         reg[c] = reg[a] * b;
  244.     } else {
  245.         panic!("Wrong amount of paramters to addr")
  246.     }
  247. }
  248.  
  249. fn banr(params: &Vec<usize>, reg: &mut Vec<usize>) {
  250.     if let [a,b,c] = params[0..3] {
  251.         reg[c] = reg[a] & reg[b];
  252.     } else {
  253.         panic!("Wrong amount of paramters to addr")
  254.     }
  255. }
  256.  
  257. fn bani(params: &Vec<usize>, reg: &mut Vec<usize>) {
  258.     if let [a,b,c] = params[0..3] {
  259.         reg[c] = reg[a] & b;
  260.     } else {
  261.         panic!("Wrong amount of paramters to addr")
  262.     }
  263. }
  264.  
  265. fn borr(params: &Vec<usize>, reg: &mut Vec<usize>) {
  266.     if let [a,b,c] = params[0..3] {
  267.         reg[c] = reg[a] | reg[b];
  268.     } else {
  269.         panic!("Wrong amount of paramters to addr")
  270.     }
  271. }
  272.  
  273. fn bori(params: &Vec<usize>, reg: &mut Vec<usize>) {
  274.     if let [a,b,c] = params[0..3] {
  275.         reg[c] = reg[a] | b;
  276.     } else {
  277.         panic!("Wrong amount of paramters to addr")
  278.     }
  279. }
  280.  
  281. fn setr(params: &Vec<usize>, reg: &mut Vec<usize>) {
  282.     if let [a,_b,c] = params[0..3] {
  283.         reg[c] = reg[a];
  284.     } else {
  285.         panic!("Wrong amount of paramters to addr")
  286.     }
  287. }
  288.  
  289. fn seti(params: &Vec<usize>, reg: &mut Vec<usize>) {
  290.     if let [a,_b,c] = params[0..3] {
  291.         reg[c] = a;
  292.     } else {
  293.         panic!("Wrong amount of paramters to addr")
  294.     }
  295. }
  296.  
  297. fn gtir(params: &Vec<usize>, reg: &mut Vec<usize>) {
  298.     if let [a,b,c] = params[0..3] {
  299.         reg[c] = if a > reg[b] { 1 } else { 0 }
  300.     } else {
  301.         panic!("Wrong amount of paramters to addr")
  302.     }
  303. }
  304.  
  305. fn gtri(params: &Vec<usize>, reg: &mut Vec<usize>) {
  306.     if let [a,b,c] = params[0..3] {
  307.         reg[c] = if reg[a] > b { 1 } else { 0 }
  308.     } else {
  309.         panic!("Wrong amount of paramters to addr")
  310.     }
  311. }
  312.  
  313. fn gtrr(params: &Vec<usize>, reg: &mut Vec<usize>) {
  314.     if let [a,b,c] = params[0..3] {
  315.         reg[c] = if reg[a] > reg[b] { 1 } else { 0 }
  316.     } else {
  317.         panic!("Wrong amount of paramters to addr")
  318.     }
  319. }
  320.  
  321. fn eqir(params: &Vec<usize>, reg: &mut Vec<usize>) {
  322.     if let [a,b,c] = params[0..3] {
  323.         reg[c] = if a == reg[b] { 1 } else { 0 }
  324.     } else {
  325.         panic!("Wrong amount of paramters to addr")
  326.     }
  327. }
  328.  
  329. fn eqri(params: &Vec<usize>, reg: &mut Vec<usize>) {
  330.     if let [a,b,c] = params[0..3] {
  331.         reg[c] = if reg[a] == b { 1 } else { 0 }
  332.     } else {
  333.         panic!("Wrong amount of paramters to addr")
  334.     }
  335. }
  336.  
  337. fn eqrr(params: &Vec<usize>, reg: &mut Vec<usize>) {
  338.     if let [a,b,c] = params[0..3] {
  339.         reg[c] = if reg[a] == reg[b] { 1 } else { 0 }
  340.     } else {
  341.         panic!("Wrong amount of paramters to addr")
  342.     }
  343. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement