day(02): add solution
Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
b87e0ac219
commit
b0554f5cf4
2 changed files with 138 additions and 0 deletions
5
samples/day02.txt
Normal file
5
samples/day02.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
|
||||
Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue
|
||||
Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red
|
||||
Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red
|
||||
Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green
|
133
src/bin/day02.rs
Normal file
133
src/bin/day02.rs
Normal file
|
@ -0,0 +1,133 @@
|
|||
use std::str::FromStr;
|
||||
|
||||
use aoc_2023::*;
|
||||
|
||||
type Output1 = i32;
|
||||
type Output2 = Output1;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct Pick {
|
||||
red: i32,
|
||||
green: i32,
|
||||
blue: i32,
|
||||
}
|
||||
|
||||
impl Pick {
|
||||
fn new() -> Pick {
|
||||
Pick {
|
||||
red: 0,
|
||||
green: 0,
|
||||
blue: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Pick {
|
||||
type Err = &'static str;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(s.split(',')
|
||||
.map(|s| s.trim())
|
||||
.fold(Pick::new(), |mut p, s| {
|
||||
let mut parts = s.split_whitespace();
|
||||
|
||||
let count: i32 = parts.next().unwrap().parse().unwrap();
|
||||
match parts.next().unwrap() {
|
||||
"red" => {
|
||||
p.red = count;
|
||||
}
|
||||
"green" => {
|
||||
p.green = count;
|
||||
}
|
||||
"blue" => {
|
||||
p.blue = count;
|
||||
}
|
||||
_ => unreachable!("invalid color"),
|
||||
}
|
||||
|
||||
p
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
struct Game {
|
||||
id: i32,
|
||||
picks: Vec<Pick>,
|
||||
}
|
||||
|
||||
impl FromStr for Game {
|
||||
type Err = &'static str;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut parts = s.split(':');
|
||||
let mut left = parts.next().unwrap().split_ascii_whitespace();
|
||||
|
||||
let id: i32 = left.nth(1).unwrap().parse().unwrap();
|
||||
|
||||
let picks = parts
|
||||
.next()
|
||||
.unwrap()
|
||||
.split(';')
|
||||
.map(|p| p.trim().parse().unwrap())
|
||||
.collect_vec();
|
||||
|
||||
Ok(Game { id, picks })
|
||||
}
|
||||
}
|
||||
|
||||
impl Game {
|
||||
fn possible(&self, r: i32, g: i32, b: i32) -> bool {
|
||||
self.picks
|
||||
.iter()
|
||||
.all(|p| p.red <= r && p.green <= g && p.blue <= b)
|
||||
}
|
||||
|
||||
fn min(&self) -> (i32, i32, i32) {
|
||||
(
|
||||
self.picks.iter().map(|p| p.red).max().unwrap(),
|
||||
self.picks.iter().map(|p| p.green).max().unwrap(),
|
||||
self.picks.iter().map(|p| p.blue).max().unwrap(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
struct Day02 {
|
||||
games: Vec<Game>,
|
||||
}
|
||||
impl Solution<Output1, Output2> for Day02 {
|
||||
fn new<P: AsRef<Path>>(pathname: P) -> Self {
|
||||
Self {
|
||||
games: file_to_structs(pathname),
|
||||
}
|
||||
}
|
||||
|
||||
fn part_1(&mut self) -> Output1 {
|
||||
self.games
|
||||
.iter()
|
||||
.filter_map(|g| {
|
||||
if g.possible(12, 13, 14) {
|
||||
Some(g.id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn part_2(&mut self) -> Output2 {
|
||||
self.games
|
||||
.iter()
|
||||
.map(|g| {
|
||||
let (r, g, b) = g.min();
|
||||
|
||||
r * g * b
|
||||
})
|
||||
.sum()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
Day02::main()
|
||||
}
|
||||
|
||||
test_sample!(day_02, Day02, 8, 2286);
|
Loading…
Reference in a new issue