From c4f410fcb6bf3214ffec95b3f3175cf7b0844805 Mon Sep 17 00:00:00 2001 From: kageru Date: Sat, 12 Jan 2019 15:08:56 +0100 Subject: [PATCH] (Rust) day 16 part 2 more wip --- 16/Cargo.toml | 1 + 16/src/functions.rs | 16 +++++++++ 16/src/main.rs | 87 ++++++++++++++++++++++++++++++--------------- 3 files changed, 75 insertions(+), 29 deletions(-) diff --git a/16/Cargo.toml b/16/Cargo.toml index e4e4b01..2fa4e4b 100644 --- a/16/Cargo.toml +++ b/16/Cargo.toml @@ -5,3 +5,4 @@ authors = ["kageru "] edition = "2018" [dependencies] +text_io = "0.1.7" diff --git a/16/src/functions.rs b/16/src/functions.rs index b14e904..8119ff8 100644 --- a/16/src/functions.rs +++ b/16/src/functions.rs @@ -1,94 +1,110 @@ pub fn addi(first: usize, second: usize, address: usize, registers: &[usize; 4]) -> [usize; 4] { + println!("addi"); let mut regs = registers.clone(); regs[address] = regs[first] + second; return regs; } pub fn addr(first: usize, second: usize, address: usize, registers: &[usize; 4]) -> [usize; 4] { + println!("addr"); let mut regs = registers.clone(); regs[address] = regs[first] + regs[second]; return regs; } pub fn muli(first: usize, second: usize, address: usize, registers: &[usize; 4]) -> [usize; 4] { + println!("muli"); let mut regs = registers.clone(); regs[address] = regs[first] * second; return regs; } pub fn mulr(first: usize, second: usize, address: usize, registers: &[usize; 4]) -> [usize; 4] { + println!("rst:"); let mut regs = registers.clone(); regs[address] = regs[first] * regs[second]; return regs; } pub fn bori(first: usize, second: usize, address: usize, registers: &[usize; 4]) -> [usize; 4] { + println!("bori"); let mut regs = registers.clone(); regs[address] = regs[first] | second; return regs; } pub fn borr(first: usize, second: usize, address: usize, registers: &[usize; 4]) -> [usize; 4] { + println!("borr"); let mut regs = registers.clone(); regs[address] = regs[first] | regs[second]; return regs; } pub fn seti(first: usize, _second: usize, address: usize, registers: &[usize; 4]) -> [usize; 4] { + println!("seti"); let mut regs = registers.clone(); regs[address] = first; return regs; } pub fn setr(first: usize, _second: usize, address: usize, registers: &[usize; 4]) -> [usize; 4] { + println!("setr"); let mut regs = registers.clone(); regs[address] = regs[first]; return regs; } pub fn gtir(first: usize, second: usize, address: usize, registers: &[usize; 4]) -> [usize; 4] { + println!("gtir"); let mut regs = registers.clone(); regs[address] = if first > regs[second] {1} else {0}; return regs; } pub fn gtri(first: usize, second: usize, address: usize, registers: &[usize; 4]) -> [usize; 4] { + println!("gtri"); let mut regs = registers.clone(); regs[address] = if regs[first] > second {1} else {0}; return regs; } pub fn gtrr(first: usize, second: usize, address: usize, registers: &[usize; 4]) -> [usize; 4] { + println!("gtrr"); let mut regs = registers.clone(); regs[address] = if regs[first] > regs[second] {1} else {0}; return regs; } pub fn eqir(first: usize, second: usize, address: usize, registers: &[usize; 4]) -> [usize; 4] { + println!("eqir"); let mut regs = registers.clone(); regs[address] = if first == regs[second] {1} else {0}; return regs; } pub fn eqri(first: usize, second: usize, address: usize, registers: &[usize; 4]) -> [usize; 4] { + println!("eqri"); let mut regs = registers.clone(); regs[address] = if regs[first] == second {1} else {0}; return regs; } pub fn eqrr(first: usize, second: usize, address: usize, registers: &[usize; 4]) -> [usize; 4] { + println!("eqrr"); let mut regs = registers.clone(); regs[address] = if regs[first] == regs[second] {1} else {0}; return regs; } pub fn bani(first: usize, second: usize, address: usize, registers: &[usize; 4]) -> [usize; 4] { + println!("bani"); let mut regs = registers.clone(); regs[address] = regs[first] & second; return regs; } pub fn banr(first: usize, second: usize, address: usize, registers: &[usize; 4]) -> [usize; 4] { + println!("banr"); let mut regs = registers.clone(); regs[address] = first & regs[second]; return regs; diff --git a/16/src/main.rs b/16/src/main.rs index 85b9f6e..ccad6df 100644 --- a/16/src/main.rs +++ b/16/src/main.rs @@ -32,25 +32,9 @@ fn verify_fn(func: &fn(usize, usize, usize, &[usize; 4]) -> [usize; 4], calls: & return true; } -fn main() { - let fns = [addi, addr, muli, mulr, seti, setr, bani, banr, bori, borr, gtir, gtri, gtrr, eqir, eqri, eqrr]; - // Apparently, this needs to be mutable for me to take elements inside the loop later - let mut lines = include_str!("../input").lines().filter(|line| line != &"").peekable(); - let mut calls: Vec = Vec::new(); - - while lines.peek() != None { - let mut call = Call::new(); - - scan!(lines.next().unwrap().bytes() => "Before: [{}, {}, {}, {}]", call.before[0], call.before[1], call.before[2], call.before[3]); - scan!(lines.next().unwrap().bytes() => "{} {} {} {}", call.call[0], call.call[1], call.call[2], call.call[3]); - scan!(lines.next().unwrap().bytes() => "After: [{}, {}, {}, {}]", call.after[0], call.after[1], call.after[2], call.after[3]); - - calls.push(call); - } - - // Part 1 +fn part1(calls: &Vec, fns: &[fn(usize, usize, usize, &[usize; 4]) -> [usize; 4]; 16]) { let mut more_than_three = 0; - for call in &calls { + for call in calls { let mut correct = 0; for func in fns.iter() { if check(&func, &call) { @@ -62,20 +46,65 @@ fn main() { } } println!("{}", more_than_three); +} - // Part 2 +fn get_mapping(calls: &Vec, fns: &[fn(usize, usize, usize, &[usize; 4]) -> [usize; 4]; 16]) + -> HashMap [usize; 4]> { let mut mapping: HashMap [usize; 4]> = HashMap::new(); - for i in 0..16 { - let op_calls = calls.iter().filter(|&c| c.call[0] == i).collect::>(); - let clone = fns.clone(); - println!("{}", op_calls.len()); - let funcs = clone.into_iter().filter(|&f| verify_fn(&f, &op_calls)).collect::>(); + let mut funcs = fns.into_iter().enumerate().collect::>(); + while funcs.len() > 0 { + for i in 0..16 { + let op_calls = calls.iter().filter(|&c| c.call[0] == i).collect::>(); + let valid = funcs.iter().filter(|&f| verify_fn(&f.1, &op_calls)).collect::>(); - if funcs.len() == 1 { - //let f = *funcs.get(0).unwrap(); - mapping.insert(i, *funcs.get(0).unwrap().clone()); - } else { - println!("help: {}", funcs.len()); + if valid.len() == 1 { + let (found_id, found) = *valid.get(0).unwrap(); + mapping.insert(i, *found.clone()); + let index = funcs.iter().position(|f| f.0 == *found_id).unwrap(); + funcs.remove(index); + } } } + return mapping; +} + +fn num_string_to_array(input: &str) -> [usize; 4] { + let mut out: [usize; 4] = [0, 0, 0, 0]; + scan!(input.bytes() => "{} {} {} {}", out[0], out[1], out[2], out[3]); + return out; +} + +fn main() { + let fns = [addi, addr, muli, mulr, seti, setr, bani, banr, bori, borr, gtir, gtri, gtrr, eqir, eqri, eqrr]; + // Apparently, this needs to be mutable for me to take elements inside the loop later + let mut lines = include_str!("../input").lines().filter(|line| line != &"").peekable(); + let mut calls: Vec = Vec::new(); + + while lines.peek() != None { + let mut call = Call::new(); + + scan!(lines.next().unwrap().bytes() => "Before: [{}, {}, {}, {}]", call.before[0], call.before[1], call.before[2], call.before[3]); + call.call = num_string_to_array(lines.next().unwrap()); + scan!(lines.next().unwrap().bytes() => "After: [{}, {}, {}, {}]", call.after[0], call.after[1], call.after[2], call.after[3]); + + calls.push(call); + } + + part1(&calls, &fns); + + // Part 2 + let program_lines = include_str!("../input2").lines(); + let mapping = get_mapping(&calls, &fns); + println!("garbage ends"); + + let mut registers: [usize; 4] = [0, 0, 0, 0]; + //scan!(program_lines.next().unwrap().bytes() => "{} {} {} {}", registers[0], registers[1], registers[2], registers[3]); + for line in program_lines { + let call = num_string_to_array(line); + registers = mapping.get(&call[0]).unwrap()(call[1], call[2], call[3], ®isters); + println!("regs: {}, {}, {}, {}", registers[0], registers[1], registers[2], registers[3]); + println!("call: {}, {}, {}, {}", call[0], call[1], call[2], call[3]); + } + // 464 is too low + println!("{}", registers[0]); }