Guest User

Untitled

a guest
Dec 16th, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.82 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. 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. }
Add Comment
Please, Sign In to add comment