160 lines
3.7 KiB
Rust
160 lines
3.7 KiB
Rust
|
use std::collections::HashMap;
|
||
|
use std::{
|
||
|
fs::File,
|
||
|
io::{prelude::*, BufReader},
|
||
|
path::Path,
|
||
|
};
|
||
|
|
||
|
fn lines_from_file(filename: impl AsRef<Path>) -> Vec<String> {
|
||
|
let file = File::open(filename).expect("no such file");
|
||
|
let buf = BufReader::new(file);
|
||
|
buf.lines()
|
||
|
.map(|l| l.expect("Could not parse line"))
|
||
|
.collect()
|
||
|
}
|
||
|
// ---
|
||
|
|
||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||
|
enum Move {
|
||
|
Rock,
|
||
|
Paper,
|
||
|
Scissors,
|
||
|
INVALID,
|
||
|
Win,
|
||
|
Lose,
|
||
|
Tie,
|
||
|
}
|
||
|
|
||
|
fn main() {
|
||
|
let lines = lines_from_file("../full/day02.txt");
|
||
|
part1(&lines);
|
||
|
part2(&lines);
|
||
|
}
|
||
|
|
||
|
fn to_enum(s: &str, part: i32) -> Move {
|
||
|
if s == "A" {
|
||
|
return Move::Rock;
|
||
|
} else if s == "B" {
|
||
|
return Move::Paper;
|
||
|
} else if s == "C" {
|
||
|
return Move::Scissors;
|
||
|
} else if s == "X" {
|
||
|
if part == 1 {
|
||
|
return Move::Rock;
|
||
|
} else {
|
||
|
return Move::Lose;
|
||
|
}
|
||
|
} else if s == "Y" {
|
||
|
if part == 1 {
|
||
|
return Move::Paper;
|
||
|
} else {
|
||
|
return Move::Tie;
|
||
|
}
|
||
|
} else if s == "Z" {
|
||
|
if part == 1 {
|
||
|
return Move::Scissors;
|
||
|
} else {
|
||
|
return Move::Win;
|
||
|
}
|
||
|
}
|
||
|
return Move::INVALID;
|
||
|
}
|
||
|
|
||
|
fn parse(lines: &Vec<String>, part: i32) -> (Vec<Move>, Vec<Move>) {
|
||
|
let mut oppt: Vec<Move> = Vec::new();
|
||
|
let mut mine: Vec<Move> = Vec::new();
|
||
|
for line in lines {
|
||
|
let split = line.split_whitespace().collect::<Vec<_>>();
|
||
|
oppt.push(to_enum(split[0], part));
|
||
|
mine.push(to_enum(split[1], part));
|
||
|
}
|
||
|
return (oppt, mine);
|
||
|
}
|
||
|
|
||
|
fn score_1(o: &Move, m: Move) -> i32 {
|
||
|
let mut score: i32 = 0;
|
||
|
let scores: HashMap<Move, i32> = HashMap::from([
|
||
|
(Move::Rock, 1),
|
||
|
(Move::Paper, 2),
|
||
|
(Move::Scissors, 3),
|
||
|
(Move::Win, 6),
|
||
|
(Move::Tie, 3),
|
||
|
(Move::Lose, 0),
|
||
|
]);
|
||
|
// For my choice
|
||
|
score += scores[&m];
|
||
|
|
||
|
// for which outcome
|
||
|
if o == &m {
|
||
|
//println!("Tie");
|
||
|
score += scores[&Move::Tie];
|
||
|
} else if (m == Move::Paper && o == &Move::Rock)
|
||
|
|| (m == Move::Rock && o == &Move::Scissors)
|
||
|
|| (m == Move::Scissors && o == &Move::Paper)
|
||
|
{
|
||
|
//println!("Win");
|
||
|
score += scores[&Move::Win];
|
||
|
} else {
|
||
|
//println!("Lose");
|
||
|
score += scores[&Move::Lose];
|
||
|
}
|
||
|
|
||
|
return score;
|
||
|
}
|
||
|
|
||
|
fn part1(lines: &Vec<String>) {
|
||
|
let (oppt, mine) = parse(lines, 1);
|
||
|
let mut score: i32 = 0;
|
||
|
for (idx, el) in oppt.iter().enumerate() {
|
||
|
score += score_1(el, mine[idx]);
|
||
|
}
|
||
|
println!("{}", score);
|
||
|
}
|
||
|
|
||
|
fn score_2(o: &Move, m: Move) -> i32 {
|
||
|
let mut new_move: &Move = &Move::INVALID;
|
||
|
let mut score: i32 = 0;
|
||
|
let scores: HashMap<Move, i32> = HashMap::from([
|
||
|
(Move::Rock, 1),
|
||
|
(Move::Paper, 2),
|
||
|
(Move::Scissors, 3),
|
||
|
(Move::Win, 6),
|
||
|
(Move::Tie, 3),
|
||
|
(Move::Lose, 0),
|
||
|
]);
|
||
|
// For my choice
|
||
|
if m == Move::Tie {
|
||
|
new_move = o;
|
||
|
} else if m == Move::Lose {
|
||
|
if o == &Move::Rock {
|
||
|
new_move = &Move::Scissors;
|
||
|
} else if o == &Move::Paper {
|
||
|
new_move = &Move::Rock;
|
||
|
} else {
|
||
|
new_move = &Move::Paper;
|
||
|
}
|
||
|
} else if m == Move::Win {
|
||
|
if o == &Move::Rock {
|
||
|
new_move = &Move::Paper;
|
||
|
} else if o == &Move::Paper {
|
||
|
new_move = &Move::Scissors;
|
||
|
} else {
|
||
|
new_move = &Move::Rock;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
score += scores[new_move];
|
||
|
score += scores[&m];
|
||
|
|
||
|
return score;
|
||
|
}
|
||
|
|
||
|
fn part2(lines: &Vec<String>) {
|
||
|
let (oppt, mine) = parse(lines, 2);
|
||
|
let mut score: i32 = 0;
|
||
|
for (idx, el) in oppt.iter().enumerate() {
|
||
|
score += score_2(el, mine[idx]);
|
||
|
}
|
||
|
println!("{}", score);
|
||
|
}
|