daily pastebin goal
38%
SHARE
TWEET

Untitled

a guest Dec 16th, 2018 55 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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.     let mut reg = vec![0,0,0,0];
  40.  
  41.     for line in program.lines.iter() {
  42.         //println!("{:?}", reg);
  43.         let params = line[1..4].to_vec();
  44.         println!("{} {:?}",codes[line[0]].name, params);
  45.         (codes[line[0]].f)(&params,&mut reg);
  46.         //println!("");
  47.     }
  48.  
  49.     reg
  50. }
  51.  
  52. fn deduce_opcodes(samples: &Vec<Sample>) -> Vec<OpCode> {
  53.     let mut opcodes = Vec::new();
  54.     let named_functions = get_named_functions();
  55.  
  56.     let mut candidates = Vec::new();
  57.     for (name, function) in named_functions.iter() {
  58.         let mut possibilities = Vec::new();
  59.         for num in 0..16 {
  60.             let no_possibility = samples.iter()
  61.                 .filter(|sample| sample.code[0] == num)
  62.                 .any(|sample| !sample.could_be(function));
  63.            
  64.             if !no_possibility{
  65.                 let opcode = OpCode {name: name.clone(), num: num, f: *function};
  66.                 possibilities.push(opcode)
  67.             }
  68.         }
  69.         //println!("Possibilities:\n{:?}", possibilities);
  70.         candidates.push(possibilities);
  71.     }
  72.  
  73.     //println!("Candidates:\n{:?}", candidates);
  74.     let mut found = Vec::new();
  75.  
  76.     while found.len() < 16 {
  77.         for possibilities in candidates.iter() {
  78.             let new: Vec<OpCode> = possibilities.iter().cloned().filter(|pos| !found.contains(&pos.num)).collect();
  79.             if new.len() == 1 {
  80.                 opcodes.push(new[0].clone());
  81.                 found.push(new[0].num)
  82.             }
  83.         }
  84.     }
  85.  
  86.     opcodes
  87. }
  88.  
  89. fn get_functions() -> Vec<fn(&Vec<usize>, &mut Vec<usize>)> {
  90.     let mut functions: Vec<fn(&Vec<usize>, &mut Vec<usize>)> = Vec::new();
  91.     functions.push(addi); functions.push(addr);
  92.     functions.push(muli); functions.push(mulr);
  93.     functions.push(bani); functions.push(banr);
  94.     functions.push(bori); functions.push(borr);
  95.     functions.push(seti); functions.push(setr);
  96.     functions.push(gtir); functions.push(gtri); functions.push(gtrr);
  97.     functions.push(eqir); functions.push(eqri); functions.push(eqrr);
  98.     functions
  99. }
  100.  
  101. fn get_named_functions() -> Vec<(String, fn(&Vec<usize>, &mut Vec<usize>))> {
  102.     let mut functions: Vec<(String, fn(&Vec<usize>, &mut Vec<usize>))> = Vec::new();
  103.     functions.push(("addi".to_string(),addi)); functions.push(("addr".to_string(), addr));
  104.     functions.push(("muli".to_string(),muli)); functions.push(("mulr".to_string(),mulr));
  105.     functions.push(("bani".to_string(),bani)); functions.push(("banr".to_string(),banr));
  106.     functions.push(("bori".to_string(),bori)); functions.push(("borr".to_string(),borr));
  107.     functions.push(("seti".to_string(),seti)); functions.push(("setr".to_string(),setr));
  108.     functions.push(("gtir".to_string(),gtir)); functions.push(("gtri".to_string(),gtri)); functions.push(("gtrr".to_string(),gtrr));
  109.     functions.push(("eqir".to_string(),eqir)); functions.push(("eqri".to_string(),eqri)); functions.push(("eqrr".to_string(),eqrr));
  110.     functions
  111. }
  112.  
  113. fn has3pos(samples: &Vec<Sample>) -> i64 {
  114.     let functions = get_functions();
  115.  
  116.     samples.iter().map(|sample| sample.num_candidates(&functions)).filter(|num| *num >= 3).count() as i64
  117.  
  118. }
  119.  
  120. fn parse_content(contents: &str) -> (Vec<Sample>, Program) {
  121.     let mut samples = Vec::new();
  122.     let mut prog = Vec::new();
  123.     let mut lines = contents.trim_right().lines();
  124.     let re = Regex::new(r"(\d+)").unwrap();
  125.  
  126.     while let Some(line) = lines.next() {
  127.          if line.starts_with("Before") {
  128.              let mut before = Vec::new();
  129.              for cap in re.captures_iter(line) {
  130.                  before.push(cap[1].parse::<usize>().unwrap());
  131.              }
  132.              
  133.              let mut code = Vec::new();
  134.              let code_line = lines.next().expect("Wrongly formatted sample");
  135.              for cap in re.captures_iter(code_line) {
  136.                  code.push(cap[1].parse::<usize>().unwrap());
  137.              }
  138.  
  139.              let mut after = Vec::new();
  140.              let after_line = lines.next().expect("Wrongly formatted sample");
  141.              for cap in re.captures_iter(after_line) {
  142.                  after.push(cap[1].parse::<usize>().unwrap());
  143.              }
  144.            
  145.              samples.push(Sample {before, code, after} );
  146.  
  147.          }
  148.          if line != "" {
  149.              let mut source = Vec::new();
  150.              for cap in re.captures_iter(line) {
  151.                  source.push(cap[1].parse::<usize>().unwrap());
  152.              }
  153.              prog.push(source);
  154.          }
  155.     }
  156.    
  157.     (samples, Program {lines: prog})
  158. }
  159.  
  160. #[derive(Clone)]
  161. struct OpCode {
  162.     name: String,
  163.     num: usize,
  164.     f: fn(&Vec<usize>, &mut Vec<usize>),
  165. }
  166.  
  167. impl Debug for OpCode {
  168.     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
  169.         write!(f, "OpCode {{ name: {}, num: {} }}", self.name, self.num)
  170.     }
  171.  
  172. }
  173.  
  174. #[derive(Debug)]
  175. struct Sample {
  176.     before: Vec<usize>,
  177.     code: Vec<usize>,
  178.     after: Vec<usize>,
  179. }
  180.  
  181. impl Sample {
  182.     fn could_be(&self, f: impl Fn(&Vec<usize>, &mut Vec<usize>)) -> bool {
  183.         let mut reg = self.before.clone();
  184.         f(&self.code[1..4].to_vec(), &mut reg);
  185.         reg == self.after
  186.     }
  187.  
  188.     fn num_candidates(&self, functions: &Vec<fn(&Vec<usize>, &mut Vec<usize>)>) -> i64 {
  189.         functions.iter().filter(|f| self.could_be(f)).count() as i64
  190.     }
  191. }
  192.  
  193. #[derive(Debug)]
  194. struct Program {
  195.     lines: Vec<Vec<usize>>,
  196. }
  197.  
  198. fn parse_filename(args: &Vec<String>) -> &str {
  199.  
  200.     if args.len() < 2 {
  201.         println!("Too few arguements, please give a filename");
  202.         process::exit(1);
  203.     }
  204.     args.get(1).expect("No filename provided")
  205. }
  206.  
  207. fn get_contents(filename: &str, contents: &mut String) {
  208.     let mut f = File::open(filename).expect("File not found");
  209.  
  210.     f.read_to_string(contents)
  211.         .expect("Something went wrong reading the file");
  212. }
  213.  
  214. fn addr(params: &Vec<usize>, reg: &mut Vec<usize>) {
  215.     if let [a,b,c] = params[0..3] {
  216.         reg[c] = reg[a] + reg[b];
  217.     } else {
  218.         panic!("Wrong amount of paramters to addr")
  219.     }
  220. }
  221.  
  222. fn addi(params: &Vec<usize>, reg: &mut Vec<usize>) {
  223.     if let [a,b,c] = params[0..3] {
  224.         reg[c] = reg[a] + b;
  225.     } else {
  226.         panic!("Wrong amount of paramters to addr")
  227.     }
  228. }
  229.  
  230. fn mulr(params: &Vec<usize>, reg: &mut Vec<usize>) {
  231.     if let [a,b,c] = params[0..3] {
  232.         reg[c] = reg[a] * reg[b];
  233.     } else {
  234.         panic!("Wrong amount of paramters to addr")
  235.     }
  236. }
  237.  
  238. fn muli(params: &Vec<usize>, reg: &mut Vec<usize>) {
  239.     if let [a,b,c] = params[0..3] {
  240.         reg[c] = reg[a] * b;
  241.     } else {
  242.         panic!("Wrong amount of paramters to addr")
  243.     }
  244. }
  245.  
  246. fn banr(params: &Vec<usize>, reg: &mut Vec<usize>) {
  247.     if let [a,b,c] = params[0..3] {
  248.         reg[c] = reg[a] & reg[b];
  249.     } else {
  250.         panic!("Wrong amount of paramters to addr")
  251.     }
  252. }
  253.  
  254. fn bani(params: &Vec<usize>, reg: &mut Vec<usize>) {
  255.     if let [a,b,c] = params[0..3] {
  256.         reg[c] = reg[a] & b;
  257.     } else {
  258.         panic!("Wrong amount of paramters to addr")
  259.     }
  260. }
  261.  
  262. fn borr(params: &Vec<usize>, reg: &mut Vec<usize>) {
  263.     if let [a,b,c] = params[0..3] {
  264.         reg[c] = reg[a] | reg[b];
  265.     } else {
  266.         panic!("Wrong amount of paramters to addr")
  267.     }
  268. }
  269.  
  270. fn bori(params: &Vec<usize>, reg: &mut Vec<usize>) {
  271.     if let [a,b,c] = params[0..3] {
  272.         reg[c] = reg[a] | b;
  273.     } else {
  274.         panic!("Wrong amount of paramters to addr")
  275.     }
  276. }
  277.  
  278. fn setr(params: &Vec<usize>, reg: &mut Vec<usize>) {
  279.     if let [a,_b,c] = params[0..3] {
  280.         reg[c] = reg[a];
  281.     } else {
  282.         panic!("Wrong amount of paramters to addr")
  283.     }
  284. }
  285.  
  286. fn seti(params: &Vec<usize>, reg: &mut Vec<usize>) {
  287.     if let [a,_b,c] = params[0..3] {
  288.         reg[c] = a;
  289.     } else {
  290.         panic!("Wrong amount of paramters to addr")
  291.     }
  292. }
  293.  
  294. fn gtir(params: &Vec<usize>, reg: &mut Vec<usize>) {
  295.     if let [a,b,c] = params[0..3] {
  296.         reg[c] = if a > reg[b] { 1 } else { 0 }
  297.     } else {
  298.         panic!("Wrong amount of paramters to addr")
  299.     }
  300. }
  301.  
  302. fn gtri(params: &Vec<usize>, reg: &mut Vec<usize>) {
  303.     if let [a,b,c] = params[0..3] {
  304.         reg[c] = if reg[a] > b { 1 } else { 0 }
  305.     } else {
  306.         panic!("Wrong amount of paramters to addr")
  307.     }
  308. }
  309.  
  310. fn gtrr(params: &Vec<usize>, reg: &mut Vec<usize>) {
  311.     if let [a,b,c] = params[0..3] {
  312.         reg[c] = if reg[a] > reg[b] { 1 } else { 0 }
  313.     } else {
  314.         panic!("Wrong amount of paramters to addr")
  315.     }
  316. }
  317.  
  318. fn eqir(params: &Vec<usize>, reg: &mut Vec<usize>) {
  319.     if let [a,b,c] = params[0..3] {
  320.         reg[c] = if a == reg[b] { 1 } else { 0 }
  321.     } else {
  322.         panic!("Wrong amount of paramters to addr")
  323.     }
  324. }
  325.  
  326. fn eqri(params: &Vec<usize>, reg: &mut Vec<usize>) {
  327.     if let [a,b,c] = params[0..3] {
  328.         reg[c] = if reg[a] == b { 1 } else { 0 }
  329.     } else {
  330.         panic!("Wrong amount of paramters to addr")
  331.     }
  332. }
  333.  
  334. fn eqrr(params: &Vec<usize>, reg: &mut Vec<usize>) {
  335.     if let [a,b,c] = params[0..3] {
  336.         reg[c] = if reg[a] == reg[b] { 1 } else { 0 }
  337.     } else {
  338.         panic!("Wrong amount of paramters to addr")
  339.     }
  340. }
  341.  
  342. #[cfg(test)]
  343. mod test {
  344.     use super::*;
  345.  
  346.     #[test]
  347.     fn test_addr() {
  348.         let mut reg = vec![1,2,3,4];
  349.         let params = vec![0,1,3];
  350.         addr(&params, &mut reg);
  351.         assert_eq!(reg, vec![1,2,3,3])
  352.     }
  353.  
  354.     #[test]
  355.     fn test_addi() {
  356.         let mut reg = vec![1,2,3,4];
  357.         let params = vec![0,1,3];
  358.         addi(&params, &mut reg);
  359.         assert_eq!(reg, vec![1,2,3,2])
  360.     }
  361.  
  362.     #[test]
  363.     fn test_mulr() {
  364.         let mut reg = vec![1,2,3,4];
  365.         let params = vec![0,1,3];
  366.         mulr(&params, &mut reg);
  367.         assert_eq!(reg, vec![1,2,3,2])
  368.     }
  369.  
  370.     #[test]
  371.     fn test_muli() {
  372.         let mut reg = vec![1,2,3,4];
  373.         let params = vec![0,1,3];
  374.         muli(&params, &mut reg);
  375.         assert_eq!(reg, vec![1,2,3,1])
  376.     }
  377.  
  378.     #[test]
  379.     fn test_banr() {
  380.         let mut reg = vec![1,2,3,4];
  381.         let params = vec![0,1,3];
  382.         banr(&params, &mut reg);
  383.         assert_eq!(reg, vec![1,2,3,0])
  384.     }
  385.  
  386.     #[test]
  387.     fn test_bani() {
  388.         let mut reg = vec![1,2,3,4];
  389.         let params = vec![0,1,3];
  390.         bani(&params, &mut reg);
  391.         assert_eq!(reg, vec![1,2,3,1])
  392.     }
  393.  
  394.     #[test]
  395.     fn test_borr() {
  396.         let mut reg = vec![1,2,3,4];
  397.         let params = vec![0,1,3];
  398.         borr(&params, &mut reg);
  399.         assert_eq!(reg, vec![1,2,3,3])
  400.     }
  401.  
  402.     #[test]
  403.     fn test_bori() {
  404.         let mut reg = vec![1,2,3,4];
  405.         let params = vec![0,1,3];
  406.         bori(&params, &mut reg);
  407.         assert_eq!(reg, vec![1,2,3,1])
  408.     }
  409.  
  410.     #[test]
  411.     fn test_setr() {
  412.         let mut reg = vec![1,2,3,4];
  413.         let params = vec![0,1,3];
  414.         setr(&params, &mut reg);
  415.         assert_eq!(reg, vec![1,2,3,1])
  416.     }
  417.  
  418.     #[test]
  419.     fn test_seti() {
  420.         let mut reg = vec![1,2,3,4];
  421.         let params = vec![0,1,3];
  422.         seti(&params, &mut reg);
  423.         assert_eq!(reg, vec![1,2,3,0])
  424.     }
  425.  
  426.     #[test]
  427.     fn test_gtir() {
  428.         let mut reg = vec![1,2,3,4];
  429.         let params = vec![0,1,3];
  430.         gtir(&params, &mut reg);
  431.         assert_eq!(reg, vec![1,2,3,0])
  432.     }
  433.  
  434.     #[test]
  435.     fn test_gtri() {
  436.         let mut reg = vec![1,2,3,4];
  437.         let params = vec![0,1,3];
  438.         gtri(&params, &mut reg);
  439.         assert_eq!(reg, vec![1,2,3,0])
  440.     }
  441.  
  442.     #[test]
  443.     fn test_gtrr() {
  444.         let mut reg = vec![1,2,3,4];
  445.         let params = vec![0,1,3];
  446.         gtrr(&params, &mut reg);
  447.         assert_eq!(reg, vec![1,2,3,0])
  448.     }
  449.  
  450.     #[test]
  451.     fn test_eqir() {
  452.         let mut reg = vec![1,2,3,4];
  453.         let params = vec![0,1,3];
  454.         eqir(&params, &mut reg);
  455.         assert_eq!(reg, vec![1,2,3,0])
  456.     }
  457.  
  458.     #[test]
  459.     fn test_eqri() {
  460.         let mut reg = vec![1,2,3,4];
  461.         let params = vec![0,1,3];
  462.         eqri(&params, &mut reg);
  463.         assert_eq!(reg, vec![1,2,3,1])
  464.     }
  465.  
  466.     #[test]
  467.     fn test_eqrr() {
  468.         let mut reg = vec![1,2,3,4];
  469.         let params = vec![0,1,3];
  470.         eqrr(&params, &mut reg);
  471.         assert_eq!(reg, vec![1,2,3,0])
  472.     }
  473.  
  474.     #[test]
  475.     fn test_could_be_mulr() {
  476.         let sample = Sample {before: vec![3,2,1,1], code: vec![9,2,1,2], after: vec![3,2,2,1]};
  477.         assert_eq!(sample.could_be(mulr), true)
  478.     }
  479.     #[test]
  480.     fn test_could_be_addi() {
  481.         let sample = Sample {before: vec![3,2,1,1], code: vec![9,2,1,2], after: vec![3,2,2,1]};
  482.         assert_eq!(sample.could_be(addi), true)
  483.     }
  484.     #[test]
  485.     fn test_could_be_seti() {
  486.         let sample = Sample {before: vec![3,2,1,1], code: vec![9,2,1,2], after: vec![3,2,2,1]};
  487.         assert_eq!(sample.could_be(seti), true)
  488.     }
  489.     #[test]
  490.     fn test_could_not_be_banr() {
  491.         let sample = Sample {before: vec![3,2,1,1], code: vec![9,2,1,2], after: vec![3,2,2,1]};
  492.         assert_eq!(sample.could_be(banr), false)
  493.     }
  494.  
  495.     #[test]
  496.     fn num_candidates() {
  497.         let sample = Sample {before: vec![3,2,1,1], code: vec![9,2,1,2], after: vec![3,2,2,1]};
  498.         let functions = get_functions();
  499.  
  500.         assert_eq!(sample.num_candidates(&functions), 3)
  501.     }
  502. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top