use crate::cli::PathBuf; use crate::util::read_lines; #[derive(Debug)] enum Shape { Rock, Paper, Scissor, } impl Shape { fn get_value(&self) -> u32 { match self { Shape::Rock => 1, Shape::Paper => 2, Shape::Scissor => 3, } } } #[derive(Debug)] enum EncrypedShape { A, B, C, X, Y, Z, } impl EncrypedShape { fn from_str(s: &str) -> Self { match Some(s) { Some("A") => EncrypedShape::A, Some("B") => EncrypedShape::B, Some("C") => EncrypedShape::C, Some("X") => EncrypedShape::X, Some("Y") => EncrypedShape::Y, Some("Z") => EncrypedShape::Z, _ => panic!(), } } fn get_shape(&self) -> Shape { match self { EncrypedShape::A | EncrypedShape::X => Shape::Rock, EncrypedShape::B | EncrypedShape::Y => Shape::Paper, EncrypedShape::C | EncrypedShape::Z => Shape::Scissor, } } fn predict_result(&self) -> RpsResult { match self { EncrypedShape::X => RpsResult::Loss, EncrypedShape::Y => RpsResult::Draw, EncrypedShape::Z => RpsResult::Win, EncrypedShape::A | EncrypedShape::B | EncrypedShape::C => panic!(), } } fn get_value(&self) -> u32 { self.get_shape().get_value() } } #[derive(Debug)] enum RpsResult { Win, Draw, Loss, } #[derive(Debug)] struct RPSPair { op: EncrypedShape, me: EncrypedShape, } impl RPSPair { fn from_vec(v: Vec<&str>) -> Self { RPSPair { op: (EncrypedShape::from_str(v.first().unwrap())), me: (EncrypedShape::from_str(v.last().unwrap())), } } fn my_shape_by_predicted_result(&self) -> Shape { match self.op.get_shape() { Shape::Rock => match self.me.predict_result() { RpsResult::Win => Shape::Paper, RpsResult::Draw => Shape::Rock, RpsResult::Loss => Shape::Scissor, }, Shape::Paper => match self.me.predict_result() { RpsResult::Win => Shape::Scissor, RpsResult::Draw => Shape::Paper, RpsResult::Loss => Shape::Rock, }, Shape::Scissor => match self.me.predict_result() { RpsResult::Win => Shape::Rock, RpsResult::Draw => Shape::Scissor, RpsResult::Loss => Shape::Paper, }, } } fn get_points(&self, alt: &bool) -> u32 { let extra_points: u32; let r: RpsResult; let mv: u32; if *alt { r = self.me.predict_result(); mv = self.my_shape_by_predicted_result().get_value(); } else { r = self.get_result(); mv = self.me.get_value(); } match r { RpsResult::Win => { extra_points = 6; } RpsResult::Draw => { extra_points = 3; } RpsResult::Loss => { extra_points = 0; } } mv + extra_points } fn get_result(&self) -> RpsResult { match self.me.get_shape() { Shape::Rock => match self.op.get_shape() { Shape::Rock => RpsResult::Draw, Shape::Paper => RpsResult::Loss, Shape::Scissor => RpsResult::Win, }, Shape::Paper => match self.op.get_shape() { Shape::Rock => RpsResult::Win, Shape::Paper => RpsResult::Draw, Shape::Scissor => RpsResult::Loss, }, Shape::Scissor => match self.op.get_shape() { Shape::Rock => RpsResult::Loss, Shape::Paper => RpsResult::Win, Shape::Scissor => RpsResult::Draw, }, } } } pub fn subcmd_day002(file: &Option, alt: &bool) { if let Ok(lines) = read_lines(file.as_ref().unwrap().as_path()) { let mut my_score: u32 = 0; for line in lines { if let Ok(ln) = line { let pair: RPSPair = RPSPair::from_vec(ln.split(" ").collect::>()); let my_points: u32 = pair.get_points(alt); let my_value: u32; let my_shape: Shape; let my_result: RpsResult; if *alt { my_shape = pair.my_shape_by_predicted_result(); my_value = my_shape.get_value(); my_result = pair.me.predict_result(); } else { my_shape = pair.me.get_shape(); my_value = pair.me.get_value(); my_result = pair.get_result(); } my_score += my_points; println!( "op: {:?}({:?}), me: {:?}({:?}), result: {:?}, points: {:?}", pair.op.get_shape(), pair.op.get_value(), my_shape, my_value, my_result, my_points ); } } println!("My Total Points: {:?}", my_score) } } pub fn subcmd_day002_op(file: &Option, alt: &bool) { if let Ok(lines) = read_lines(file.as_ref().unwrap().as_path()) { let mut my_score: u32 = 0; for line in lines { if let Ok(ln) = line { let pair: RPSPair = RPSPair::from_vec(ln.split(" ").collect::>()); my_score += pair.get_points(alt); } } println!("My Total Points: {:?}", my_score) } } pub fn subcmd_day002_iter(file: &Option, alt: &bool) { if let Ok(lines) = read_lines(file.as_ref().unwrap().as_path()) { let points:u32 = lines .into_iter() .map(|line| RPSPair::from_vec(line.unwrap().split(" ").collect::>())) .map(|pair| pair.get_points(alt)) .sum(); println!("My Total Points: {:?}", points) } }