From 174772b5b8d9f5bf5e3c8e8152adfd89f0e83f6b Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Tue, 19 Apr 2022 20:22:56 +0200 Subject: Refile for merging repos --- 2016/aoc10/src/main.rs | 155 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 2016/aoc10/src/main.rs (limited to '2016/aoc10/src/main.rs') diff --git a/2016/aoc10/src/main.rs b/2016/aoc10/src/main.rs new file mode 100644 index 0000000..c2c18be --- /dev/null +++ b/2016/aoc10/src/main.rs @@ -0,0 +1,155 @@ +extern crate regex; +use regex::Regex; + +use std::io::BufReader; +use std::io::prelude::*; +use std::fs::File; +use std::cmp; + +#[derive(Debug, Clone)] +struct Bot { + low: Option, + high: Option, + low_dest: Option, + high_dest: Option +} + +#[derive(Debug, Clone)] +enum Dest { + Bot(usize), + Output(usize) +} + +impl Bot { + fn new() -> Bot { + Bot {low: None, high: None, low_dest: None, high_dest: None} + } + + fn add_input(&mut self, input: i32) { + if self.low.is_none() { + self.low = Some(input); + } + else { + let other = self.low.unwrap(); //already handled none case + self.low = Some(cmp::min(input,other)); + self.high = Some(cmp::max(input,other)); + } + } + fn ready(&self) -> bool { + self.low.is_some() && self.high.is_some() && + self.low_dest.is_some() && self.high_dest.is_some() + } + fn clear(&mut self) { + self.low = None; + self.high = None; + } +} + + +fn main() { + let mut bots = build_bots_graph(); + let outputs = find_outputs(&mut bots); + println!("Outputs {:?}", outputs); +} + +fn find_outputs(bots: &mut Vec) -> Vec { + let mut output = Vec::new(); + + let mut is_stable = false; + while !is_stable { + is_stable = true; + + for i in 0..bots.len() { + if bots[i].ready() { + is_stable = false; + + let low = bots[i].low.unwrap(); + let high = bots[i].high.unwrap(); + bots[i].clear(); + + match bots[i].low_dest { + Some(Dest::Bot(j)) => { + bots[j].add_input(low); + }, + Some(Dest::Output(j)) => { + check_add_output(&mut output, j); + output[j] = low; + }, + _ => {} + }; + match bots[i].high_dest { + Some(Dest::Bot(j)) => { + bots[j].add_input(high); + }, + Some(Dest::Output(j)) => { + check_add_output(&mut output, j); + output[j] = high; + }, + _ => {} + }; + } + } + } + + output +} + +fn build_bots_graph() -> Vec { + let lines = read_file(); + let mut bots = Vec::new(); + + let value_regex = Regex::new(r"^value (\d+) goes to bot (\d+)$").unwrap(); + let give_regex = Regex::new(r"^bot (\d+) gives low to (output|bot) (\d+) and high to (output|bot) (\d+)$").unwrap(); + + for line in lines { + if value_regex.is_match(line.as_ref()) { + let cap = value_regex.captures(line.as_ref()).unwrap(); + let value = cap.at(1).unwrap().parse().unwrap(); + let bot_index = cap.at(2).unwrap().parse().unwrap(); + check_add_bot(&mut bots, bot_index); + bots[bot_index].add_input(value); + } + else if give_regex.is_match(line.as_ref()) { + let cap = give_regex.captures(line.as_ref()).unwrap(); + let give_bot_index = cap.at(1).unwrap().parse().unwrap(); + let low_is_to_output = cap.at(2).unwrap() == "output"; + let low_dest = cap.at(3).unwrap().parse().unwrap(); + let high_is_to_output = cap.at(4).unwrap() == "output"; + let high_dest = cap.at(5).unwrap().parse().unwrap(); + + check_add_bot(&mut bots, give_bot_index); + bots[give_bot_index].low_dest = if low_is_to_output { + Some(Dest::Output(low_dest)) + } else { + Some(Dest::Bot(low_dest)) + }; + bots[give_bot_index].high_dest = if high_is_to_output { + Some(Dest::Output(high_dest)) + } else { + Some(Dest::Bot(high_dest)) + }; + } + } + + bots +} + +fn check_add_bot(bots: &mut Vec, index: usize) { + while index >= bots.len() { + bots.push(Bot::new()); + } +} + +fn check_add_output(outputs: &mut Vec, index: usize) { + while index >= outputs.len() { + outputs.push(0); + } +} + +fn read_file() -> Vec { + let file = BufReader::new(File::open("input.txt").unwrap()); + file.lines() + .map(|line| line.unwrap().trim().to_string()) + .filter(|line| line.len() > 0) + .collect() +} -- cgit v1.2.3