init
This commit is contained in:
184
d11/src/a1.rs
Normal file
184
d11/src/a1.rs
Normal file
@ -0,0 +1,184 @@
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum Operation {
|
||||
MUL,
|
||||
ADD,
|
||||
SQUARE,
|
||||
}
|
||||
|
||||
struct Monkey {
|
||||
id: i32,
|
||||
inspections :i32,
|
||||
current_items :Vec<i64>,
|
||||
op :(Operation, i64),
|
||||
test :i64,
|
||||
throw_target :(i32, i32) // .0 for false target, .1 for true target
|
||||
|
||||
}
|
||||
|
||||
impl Monkey {
|
||||
|
||||
fn new(id :i32, current_items :Vec<i64>, op :(Operation, i64), test :i64, target :(i32, i32)) -> Self {
|
||||
|
||||
Monkey { id: id, inspections: 0, current_items: current_items, op: op, test: test, throw_target: target}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn eval_op(inp :Vec<&str>) -> (Operation, i64) {
|
||||
|
||||
let mut op = (Operation::ADD, 0);
|
||||
|
||||
match inp[2] {
|
||||
"old" => { return (Operation::SQUARE, 0); }
|
||||
_ => {}
|
||||
}
|
||||
|
||||
op.0 = match inp[1] {
|
||||
"*" => { Operation::MUL }
|
||||
"+" => { Operation::ADD }
|
||||
_ => { Operation::ADD }
|
||||
};
|
||||
|
||||
|
||||
op.1 = inp[2].parse::<i64>().unwrap();
|
||||
|
||||
|
||||
return op;
|
||||
|
||||
}
|
||||
|
||||
fn parse_monkey(monkey :Vec<String>) -> Option<Monkey> {
|
||||
|
||||
if monkey.len() < 6 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let id = monkey[0].split(' ').collect::<Vec<&str>>()[1].trim_matches(':').parse::<i32>().unwrap();
|
||||
|
||||
let current_items = monkey[1].replace(",", "").split(' ').filter_map(|elem| elem.parse::<i64>().ok()).collect::<Vec<i64>>();
|
||||
|
||||
let raw_op = monkey[2].split('=').collect::<Vec<&str>>()[1].trim().split(' ').collect::<Vec<&str>>();
|
||||
let op = eval_op(raw_op);
|
||||
|
||||
let test = monkey[3].split(' ').collect::<Vec<&str>>()[3].parse::<i64>().unwrap();
|
||||
|
||||
let mut target :(i32, i32) = (0, 0);
|
||||
target.0 = monkey[5].split(' ').collect::<Vec<&str>>()[5].parse::<i32>().unwrap();
|
||||
target.1 = monkey[4].split(' ').collect::<Vec<&str>>()[5].parse::<i32>().unwrap();
|
||||
|
||||
//println!("{:?}", id);
|
||||
//println!("{:?}", current_items);
|
||||
//println!("{:?}", op);
|
||||
//println!("{:?}", test);
|
||||
|
||||
return Some(Monkey::new(id, current_items, op, test, target));
|
||||
}
|
||||
|
||||
fn parse_input(inp :&Vec<String>) -> Vec<Monkey> {
|
||||
|
||||
|
||||
|
||||
//let raw_monkeys = inp.chunks(6).map(|test| {if !test.contains("") {test.to_vec()} {""}}).collect::<Vec<Vec<String>>>();
|
||||
|
||||
// split monkeys into single monkey vectors
|
||||
let mut raw_monkeys :Vec<Vec<String>> = vec![vec![]];
|
||||
|
||||
for l in inp {
|
||||
|
||||
if l.is_empty() {
|
||||
raw_monkeys.push(vec![]);
|
||||
continue;
|
||||
}
|
||||
|
||||
raw_monkeys.last_mut().unwrap().push(l.trim().to_owned());
|
||||
|
||||
}
|
||||
|
||||
// extract monkey data
|
||||
let mut monkeys :Vec<Monkey> = vec![];
|
||||
for m in raw_monkeys {
|
||||
monkeys.push(parse_monkey(m).unwrap());
|
||||
}
|
||||
|
||||
|
||||
return monkeys;
|
||||
|
||||
}
|
||||
|
||||
pub fn run(inp :Vec<String>) {
|
||||
|
||||
let mut monkeys = parse_input(&inp);
|
||||
|
||||
const MAX_ROUNDS :i32 = 20;
|
||||
|
||||
for _ in 0..MAX_ROUNDS {
|
||||
for i in 0..monkeys.len() {
|
||||
|
||||
let operation = monkeys[i].op.0;
|
||||
let operand = monkeys[i].op.1;
|
||||
|
||||
for item_index in 0..monkeys[i].current_items.len()
|
||||
{
|
||||
|
||||
let item = &mut monkeys[i].current_items[item_index];
|
||||
|
||||
// new score
|
||||
match operation {
|
||||
Operation::ADD => { *item = *item + operand; }
|
||||
Operation::MUL => { *item = *item * operand; }
|
||||
Operation::SQUARE => { *item = *item * *item }
|
||||
}
|
||||
|
||||
// println!("{}, {}", *item, operand);
|
||||
|
||||
// div 3 floor
|
||||
*item = *item / 3;
|
||||
|
||||
monkeys[i].inspections += 1;
|
||||
}
|
||||
|
||||
// throw to monkey
|
||||
while monkeys[i].current_items.len() > 0 {
|
||||
|
||||
let curr_item = *monkeys[i].current_items.first().unwrap();
|
||||
let test_number = monkeys[i].test;
|
||||
|
||||
let target = {
|
||||
if curr_item % test_number == 0 {
|
||||
monkeys[i].throw_target.1 as usize
|
||||
} else {
|
||||
//println!("{} is not divisible by {}, throwing to monkey {} (else: {})", curr_item, test_number, monkeys[i].throw_target.0 as usize, monkeys[i].throw_target.1 as usize);
|
||||
monkeys[i].throw_target.0 as usize
|
||||
}
|
||||
};
|
||||
|
||||
monkeys[target].current_items.push(curr_item);
|
||||
monkeys[i].current_items.remove(0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
let mut max = 0;
|
||||
let mut s_max = 0;
|
||||
|
||||
for i in 0..monkeys.len() {
|
||||
|
||||
if monkeys[i].inspections >= max {
|
||||
s_max = max;
|
||||
max = monkeys[i].inspections;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
println!("{}", s_max * max);
|
||||
|
||||
}
|
200
d11/src/a2.rs
Normal file
200
d11/src/a2.rs
Normal file
@ -0,0 +1,200 @@
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum Operation {
|
||||
MUL,
|
||||
ADD,
|
||||
SQUARE,
|
||||
}
|
||||
|
||||
struct Monkey {
|
||||
id: i32,
|
||||
inspections :u128,
|
||||
current_items :Vec<u128>,
|
||||
op :(Operation, u128),
|
||||
test :u128,
|
||||
throw_target :(i32, i32) // .0 for false target, .1 for true target
|
||||
|
||||
}
|
||||
|
||||
impl Monkey {
|
||||
|
||||
fn new(id :i32, current_items :Vec<u128>, op :(Operation, u128), test :u128, target :(i32, i32)) -> Self {
|
||||
|
||||
Monkey { id: id, inspections: 0, current_items: current_items, op: op, test: test, throw_target: target}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn eval_op(inp :Vec<&str>) -> (Operation, u128) {
|
||||
|
||||
let mut op = (Operation::ADD, 0);
|
||||
|
||||
match inp[2] {
|
||||
"old" => { return (Operation::SQUARE, 0); }
|
||||
_ => {}
|
||||
}
|
||||
|
||||
op.0 = match inp[1] {
|
||||
"*" => { Operation::MUL }
|
||||
"+" => { Operation::ADD }
|
||||
_ => { Operation::ADD }
|
||||
};
|
||||
|
||||
|
||||
op.1 = inp[2].parse::<u128>().unwrap();
|
||||
|
||||
|
||||
return op;
|
||||
|
||||
}
|
||||
|
||||
fn parse_monkey(monkey :Vec<String>) -> Option<Monkey> {
|
||||
|
||||
if monkey.len() < 6 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let id = monkey[0].split(' ').collect::<Vec<&str>>()[1].trim_matches(':').parse::<i32>().unwrap();
|
||||
|
||||
let current_items = monkey[1].replace(",", "").split(' ').filter_map(|elem| elem.parse::<u128>().ok()).collect::<Vec<u128>>();
|
||||
|
||||
let raw_op = monkey[2].split('=').collect::<Vec<&str>>()[1].trim().split(' ').collect::<Vec<&str>>();
|
||||
let op = eval_op(raw_op);
|
||||
|
||||
let test = monkey[3].split(' ').collect::<Vec<&str>>()[3].parse::<u128>().unwrap();
|
||||
|
||||
let mut target :(i32, i32) = (0, 0);
|
||||
target.0 = monkey[5].split(' ').collect::<Vec<&str>>()[5].parse::<i32>().unwrap();
|
||||
target.1 = monkey[4].split(' ').collect::<Vec<&str>>()[5].parse::<i32>().unwrap();
|
||||
|
||||
//println!("{:?}", id);
|
||||
//println!("{:?}", current_items);
|
||||
//println!("{:?}", op);
|
||||
//println!("{:?}", test);
|
||||
|
||||
return Some(Monkey::new(id, current_items, op, test, target));
|
||||
}
|
||||
|
||||
fn parse_input(inp :&Vec<String>) -> Vec<Monkey> {
|
||||
|
||||
|
||||
|
||||
//let raw_monkeys = inp.chunks(6).map(|test| {if !test.contains("") {test.to_vec()} {""}}).collect::<Vec<Vec<String>>>();
|
||||
|
||||
// split monkeys into single monkey vectors
|
||||
let mut raw_monkeys :Vec<Vec<String>> = vec![vec![]];
|
||||
|
||||
for l in inp {
|
||||
|
||||
if l.is_empty() {
|
||||
raw_monkeys.push(vec![]);
|
||||
continue;
|
||||
}
|
||||
|
||||
raw_monkeys.last_mut().unwrap().push(l.trim().to_owned());
|
||||
|
||||
}
|
||||
|
||||
// extract monkey data
|
||||
let mut monkeys :Vec<Monkey> = vec![];
|
||||
for m in raw_monkeys {
|
||||
monkeys.push(parse_monkey(m).unwrap());
|
||||
}
|
||||
|
||||
|
||||
return monkeys;
|
||||
|
||||
}
|
||||
|
||||
pub fn run(inp :Vec<String>) {
|
||||
|
||||
let mut monkeys = parse_input(&inp);
|
||||
|
||||
const MAX_ROUNDS :i32 = 10000;
|
||||
|
||||
|
||||
|
||||
let mut mod_fact = 1;
|
||||
|
||||
for i in 0..monkeys.len() {
|
||||
mod_fact *= monkeys[i].test;
|
||||
}
|
||||
|
||||
for _ in 0..MAX_ROUNDS {
|
||||
for i in 0..monkeys.len() {
|
||||
|
||||
let operation = monkeys[i].op.0;
|
||||
let operand = monkeys[i].op.1;
|
||||
|
||||
for item_index in 0..monkeys[i].current_items.len() {
|
||||
|
||||
let item = &mut monkeys[i].current_items[item_index];
|
||||
|
||||
// new score
|
||||
match operation {
|
||||
Operation::ADD => { *item = (*item + operand) % mod_fact; }
|
||||
Operation::MUL => { *item = (*item * operand) % mod_fact; }
|
||||
Operation::SQUARE => { *item = (*item * *item) % mod_fact; }
|
||||
}
|
||||
|
||||
// println!("{}, {}", *item, operand);
|
||||
|
||||
// div 3 floor
|
||||
//*item = *item / 3;
|
||||
|
||||
monkeys[i].inspections += 1;
|
||||
}
|
||||
|
||||
// throw to monkey
|
||||
while monkeys[i].current_items.len() > 0 {
|
||||
|
||||
let curr_item = *monkeys[i].current_items.first().unwrap();
|
||||
let test_number = monkeys[i].test;
|
||||
|
||||
let target = {
|
||||
if curr_item % test_number == 0 {
|
||||
monkeys[i].throw_target.1 as usize
|
||||
} else {
|
||||
//println!("{} is not divisible by {}, throwing to monkey {} (else: {})", curr_item, test_number, monkeys[i].throw_target.0 as usize, monkeys[i].throw_target.1 as usize);
|
||||
monkeys[i].throw_target.0 as usize
|
||||
}
|
||||
};
|
||||
|
||||
//println!("throwig {} from {} to {}", curr_item, i, target);
|
||||
|
||||
monkeys[target].current_items.push(curr_item);
|
||||
monkeys[i].current_items.remove(0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
for i in 0..monkeys.len() {
|
||||
//println!("{}: {}", i, monkeys[i].inspections);
|
||||
}
|
||||
//println!();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
let mut max = 0;
|
||||
let mut s_max = 0;
|
||||
|
||||
for i in 0..monkeys.len() {
|
||||
|
||||
if monkeys[i].inspections >= max {
|
||||
s_max = max;
|
||||
max = monkeys[i].inspections;
|
||||
} else if monkeys[i].inspections > s_max {
|
||||
s_max = monkeys[i].inspections;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
println!("{} * {} = {}", s_max, max, s_max * max);
|
||||
|
||||
}
|
41
d11/src/main.rs
Normal file
41
d11/src/main.rs
Normal file
@ -0,0 +1,41 @@
|
||||
use std::io::BufRead;
|
||||
|
||||
mod a1;
|
||||
mod a2;
|
||||
|
||||
fn read_file(path :&str) -> Vec<String> {
|
||||
|
||||
let file = std::fs::File::open(path);
|
||||
|
||||
return match file {
|
||||
|
||||
Ok(handle) => {
|
||||
|
||||
let reader = std::io::BufReader::new(handle);
|
||||
|
||||
let mut vec : Vec<String> = vec![];
|
||||
|
||||
reader.lines().for_each(|elem| {
|
||||
vec.push(elem.unwrap());
|
||||
});
|
||||
|
||||
vec
|
||||
|
||||
}
|
||||
|
||||
Err(_) => vec![]
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
let inp :Vec<String> = read_file("input.txt");
|
||||
|
||||
a1::run(inp.clone());
|
||||
|
||||
a2::run(inp);
|
||||
|
||||
}
|
Reference in New Issue
Block a user