adventofcode/days/2023/02.rs

116 Zeilen
2,9 KiB
Rust

use advent_of_code::include_aoc;
use advent_of_code::strings::parsenumber;
include_aoc!(2023, 02);
#[derive(Debug, Clone, Copy)]
struct Take {
red: u32,
green: u32,
blue: u32,
}
#[derive(Debug, Clone)]
struct Round {
roundid: u32,
takes: Vec<Take>,
}
#[derive(Debug, Clone, Copy)]
struct Sack {
reds: u32,
greens: u32,
blues: u32,
}
impl Round {
pub fn possible(&self, sack: Sack) -> bool {
let mut ok = true;
for take in self.takes.clone() {
ok = ok
&& if sack.reds.checked_sub(take.red).is_none() {
false
} else if sack.greens.checked_sub(take.green).is_none() {
false
} else if sack.blues.checked_sub(take.blue).is_none() {
false
} else {
true
};
}
ok
}
fn power(&self) -> u64 {
let mut sack = Sack {
reds: 0,
greens: 0,
blues: 0,
};
for take in self.takes.clone() {
if take.red > sack.reds {
sack.reds = take.red
}
if take.green > sack.greens {
sack.greens = take.green
}
if take.blue > sack.blues {
sack.blues = take.blue
}
}
sack.reds as u64 * sack.greens as u64 * sack.blues as u64
}
}
impl From<&str> for Round {
fn from(value: &str) -> Self {
let doublecolon = value.find(':').unwrap();
let mut round = Round {
roundid: parsenumber(value.get(5..doublecolon).unwrap()),
takes: Vec::<Take>::new(),
};
for taking in value.get(doublecolon + 1..).unwrap().split(";") {
let mut take = Take {
red: 0,
green: 0,
blue: 0,
};
for color in taking.split(',').map(str::trim) {
let mut i = color.splitn(2, char::is_whitespace);
let amount = parsenumber(i.next().unwrap());
match i.next() {
Some("red") => take.red = amount,
Some("green") => take.green = amount,
Some("blue") => take.blue = amount,
None | Some(_) => panic!(),
}
}
round.takes.push(take);
}
round
}
}
fn main() {
let mut gamerounds = Vec::<Round>::with_capacity(100);
for game in DATA.split('\n') {
gamerounds.push(game.into());
}
let sack = Sack {
reds: 12,
greens: 13,
blues: 14,
};
let mut sum = 0;
for round in gamerounds.clone() {
if round.possible(sack) {
sum += round.roundid;
}
}
println!("Sum with putback: {}", sum);
let mut sum = 0;
for round in gamerounds {
sum += round.power();
}
println!("Combined Power: {}", sum);
}