d11p2
This commit is contained in:
parent
68b71fe794
commit
efd1fb5ca9
@ -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]);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user