115 Zeilen
2,9 KiB
Rust
115 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);
|
|
}
|