d11p2
This commit is contained in:
		| @@ -130,19 +130,23 @@ fn main() { | ||||
|     loop { | ||||
|         match parse_monkey(&mut lines) { | ||||
|             Ok(None) => break, | ||||
|             Ok(Some(m)) => { assert!(m.id == monkeys.len() as u64); monkeys.push(m) }, | ||||
|             Ok(Some(m)) => { | ||||
|                 assert!(m.id == monkeys.len() as u64); | ||||
|                 monkeys.push(m) | ||||
|             }, | ||||
|             Err(e) => eprintln!("{:?}", e), | ||||
|         } | ||||
|     } | ||||
|     let mut monkey_item_counts = vec![0; monkeys.len()]; | ||||
|     let lcd = monkeys.iter().fold(1, |acc, m| acc * m.div_by_test); | ||||
|  | ||||
|     for _round in 1..=20 { | ||||
|     for _round in 1..=10000 { | ||||
|         for i in 0..monkeys.len() { | ||||
|             monkey_item_counts[i] += monkeys[i].items.len(); | ||||
|  | ||||
|             for _item in 0..monkeys[i].items.len() { | ||||
|                 let old_item = monkeys[i].items.pop_front().unwrap(); | ||||
|                 let new_item = monkeys[i].operation.perform(old_item) / 3; | ||||
|                 let new_item = monkeys[i].operation.perform(old_item) % lcd; | ||||
|                 let new_i = if new_item % monkeys[i].div_by_test == 0 { | ||||
|                     monkeys[i].true_throw | ||||
|                 } else { | ||||
|   | ||||
							
								
								
									
										158
									
								
								day11/src/main1.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								day11/src/main1.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,158 @@ | ||||
| use std::num::ParseIntError; | ||||
| use std::env; | ||||
| use std::fs::File; | ||||
| use std::io::{self, BufRead, Lines}; | ||||
| use std::collections::VecDeque; | ||||
|  | ||||
| #[derive(Debug)] | ||||
| enum Operator { Add, Mul } | ||||
| #[derive(Debug)] | ||||
| enum Operand { Old, Imm(u64) } | ||||
|  | ||||
| #[derive(Debug)] | ||||
| struct Operation { left: Operand, op: Operator, right: Operand } | ||||
| impl Operation { | ||||
|     fn perform(&self, old: u64) -> u64 { | ||||
|         let left = match self.left { | ||||
|             Operand::Old => old, | ||||
|             Operand::Imm(x) => x, | ||||
|         }; | ||||
|         let right = match self.right { | ||||
|             Operand::Old => old, | ||||
|             Operand::Imm(x) => x, | ||||
|         }; | ||||
|         match self.op { | ||||
|             Operator::Add => left + right, | ||||
|             Operator::Mul => left * right, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Debug)] | ||||
| struct Monkey { | ||||
|     id: u64, | ||||
|     items: VecDeque<u64>, | ||||
|     operation: Operation, | ||||
|     div_by_test: u64, | ||||
|     true_throw: u64, | ||||
|     false_throw: u64, | ||||
| } | ||||
|  | ||||
| #[derive(Debug)] | ||||
| enum MonkeyError { | ||||
|     ParseError(), | ||||
|     ParseIntError(ParseIntError), | ||||
|     IoError(io::Error), | ||||
| } | ||||
| impl From<ParseIntError> for MonkeyError { | ||||
|     fn from(e: ParseIntError) -> Self { MonkeyError::ParseIntError(e) } | ||||
| } | ||||
| impl From<io::Error> for MonkeyError { | ||||
|     fn from(e: io::Error) -> Self { MonkeyError::IoError(e) } | ||||
| } | ||||
|  | ||||
| fn parse_monkey<B: BufRead>( | ||||
|     lines: &mut Lines<B> | ||||
| ) -> Result<Option<Monkey>, MonkeyError> { | ||||
|     let id = match lines.next() { | ||||
|         Some(line) => line? | ||||
|             .strip_prefix("Monkey ").ok_or(MonkeyError::ParseError())? | ||||
|             .strip_suffix(":").ok_or(MonkeyError::ParseError())? | ||||
|             .parse::<u64>()?, | ||||
|         None => return Ok(None), | ||||
|     }; | ||||
|  | ||||
|     let starting_items = lines.next().ok_or(MonkeyError::ParseError())?? | ||||
|         .strip_prefix("  Starting items: ").ok_or(MonkeyError::ParseError())? | ||||
|         .split(", ") | ||||
|         .map(|item| item.parse::<u64>()) | ||||
|         .collect::<Result<VecDeque<_>, _>>()?; | ||||
|  | ||||
|     let op_line = lines.next().ok_or(MonkeyError::ParseError())??; | ||||
|     let op_vec = op_line | ||||
|         .strip_prefix("  Operation: new = ").ok_or(MonkeyError::ParseError())? | ||||
|         .split(' ').collect::<Vec<_>>(); | ||||
|     let (left, operator, right) = (op_vec[0], op_vec[1], op_vec[2]); | ||||
|     let operation = Operation { | ||||
|         left: match left { | ||||
|             "old" => Operand::Old, | ||||
|             _ => Operand::Imm(left.parse()?) | ||||
|         }, | ||||
|         op: match operator { | ||||
|             "+" => Ok(Operator::Add), | ||||
|             "*" => Ok(Operator::Mul), | ||||
|             _ => Err(MonkeyError::ParseError()) | ||||
|         }?, | ||||
|         right: match right { | ||||
|             "old" => Operand::Old, | ||||
|             _ => Operand::Imm(right.parse()?) | ||||
|         }, | ||||
|     }; | ||||
|          | ||||
|     let test_val = lines.next().ok_or(MonkeyError::ParseError())?? | ||||
|         .strip_prefix("  Test: divisible by ").ok_or(MonkeyError::ParseError())? | ||||
|         .parse::<u64>()?; | ||||
|  | ||||
|     let true_throw = lines.next().ok_or(MonkeyError::ParseError())?? | ||||
|         .strip_prefix("    If true: throw to monkey ") | ||||
|         .ok_or(MonkeyError::ParseError())? | ||||
|         .parse::<u64>()?; | ||||
|     let false_throw = lines.next().ok_or(MonkeyError::ParseError())?? | ||||
|         .strip_prefix("    If false: throw to monkey ") | ||||
|         .ok_or(MonkeyError::ParseError())? | ||||
|         .parse::<u64>()?; | ||||
|  | ||||
|     // Remove empty line if exists | ||||
|     match lines.next() { | ||||
|         None => Ok(()), | ||||
|         Some(Err(e)) => Err(e), | ||||
|         Some(Ok(s)) => Ok(match s.as_str() { | ||||
|             "" => Ok(()), | ||||
|             _ => Err(MonkeyError::ParseError()), | ||||
|         }?), | ||||
|     }?; | ||||
|  | ||||
|     Ok(Some(Monkey { | ||||
|         id: id, | ||||
|         items: starting_items, | ||||
|         operation: operation, | ||||
|         div_by_test: test_val, | ||||
|         true_throw: true_throw, | ||||
|         false_throw: false_throw, | ||||
|     }) | ||||
| )} | ||||
|  | ||||
| fn main() { | ||||
|     let file = File::open(&env::args().nth(1).unwrap()).unwrap(); | ||||
|     let mut lines = io::BufReader::new(file).lines(); | ||||
|     let mut monkeys: Vec<Monkey> = Vec::new(); | ||||
|  | ||||
|     loop { | ||||
|         match parse_monkey(&mut lines) { | ||||
|             Ok(None) => break, | ||||
|             Ok(Some(m)) => { assert!(m.id == monkeys.len() as u64); monkeys.push(m) }, | ||||
|             Err(e) => eprintln!("{:?}", e), | ||||
|         } | ||||
|     } | ||||
|     let mut monkey_item_counts = vec![0; monkeys.len()]; | ||||
|  | ||||
|     for _round in 1..=20 { | ||||
|         for i in 0..monkeys.len() { | ||||
|             monkey_item_counts[i] += monkeys[i].items.len(); | ||||
|  | ||||
|             for _item in 0..monkeys[i].items.len() { | ||||
|                 let old_item = monkeys[i].items.pop_front().unwrap(); | ||||
|                 let new_item = monkeys[i].operation.perform(old_item) / 3; | ||||
|                 let new_i = if new_item % monkeys[i].div_by_test == 0 { | ||||
|                     monkeys[i].true_throw | ||||
|                 } else { | ||||
|                     monkeys[i].false_throw | ||||
|                 } as usize; | ||||
|                 monkeys[new_i].items.push_back(new_item); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     monkey_item_counts.sort_by(|x, y| y.cmp(x)); | ||||
|     println!("{:?}", monkey_item_counts[0]*monkey_item_counts[1]); | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user