Day 2
This commit is contained in:
parent
ad791df964
commit
14a77cd34f
25
2023/rust/Cargo.lock
generated
25
2023/rust/Cargo.lock
generated
|
@ -5,3 +5,28 @@ version = 3
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aoc2023"
|
name = "aoc2023"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"nom",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "minimal-lexical"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "7.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"minimal-lexical",
|
||||||
|
]
|
||||||
|
|
|
@ -103,3 +103,4 @@ name = "day25"
|
||||||
path = "src/day25.rs"
|
path = "src/day25.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
nom = "7.1.3"
|
||||||
|
|
140
2023/rust/src/day2.rs
Normal file
140
2023/rust/src/day2.rs
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
extern crate nom;
|
||||||
|
|
||||||
|
mod prelude;
|
||||||
|
|
||||||
|
use nom::{
|
||||||
|
branch::alt,
|
||||||
|
bytes::complete::{tag, take_while_m_n},
|
||||||
|
combinator::{map_res, value},
|
||||||
|
multi::separated_list0,
|
||||||
|
IResult,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
Day2::show(day_input(2), day_input(2))
|
||||||
|
}
|
||||||
|
|
||||||
|
type Solution = usize;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
enum Reveal {
|
||||||
|
Red(usize),
|
||||||
|
Green(usize),
|
||||||
|
Blue(usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
struct RevealGroup {
|
||||||
|
red: Option<usize>,
|
||||||
|
green: Option<usize>,
|
||||||
|
blue: Option<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec<Reveal>> for RevealGroup {
|
||||||
|
fn from(value: Vec<Reveal>) -> Self {
|
||||||
|
// TODO: this obviously won't work if the vector contains multiple reveals of the same kind
|
||||||
|
// there's probably a simpler way to parse it out
|
||||||
|
let mut result = Self {
|
||||||
|
red: None,
|
||||||
|
blue: None,
|
||||||
|
green: None,
|
||||||
|
};
|
||||||
|
for v in value {
|
||||||
|
match v {
|
||||||
|
Reveal::Red(v) => result.red = Some(v),
|
||||||
|
Reveal::Green(v) => result.green = Some(v),
|
||||||
|
Reveal::Blue(v) => result.blue = Some(v),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
struct Game {
|
||||||
|
id: usize,
|
||||||
|
reveal_groups: Vec<RevealGroup>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn int(input: &str) -> IResult<&str, usize> {
|
||||||
|
map_res(take_while_m_n(1, 16, |c: char| c.is_numeric()), |s| {
|
||||||
|
usize::from_str_radix(s, 10)
|
||||||
|
})(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reveal(input: &str) -> IResult<&str, Reveal> {
|
||||||
|
let (input, num) = int(input)?;
|
||||||
|
alt((
|
||||||
|
value(Reveal::Red(num), tag(" red")),
|
||||||
|
value(Reveal::Green(num), tag(" green")),
|
||||||
|
value(Reveal::Blue(num), tag(" blue")),
|
||||||
|
))(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reveal_group(input: &str) -> IResult<&str, RevealGroup> {
|
||||||
|
let (input, reveals) = separated_list0(tag(", "), reveal)(input)?;
|
||||||
|
Ok((input, RevealGroup::from(reveals)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn game(input: &str) -> IResult<&str, Game> {
|
||||||
|
println!("that belle");
|
||||||
|
let (input, id) = int(tag("Game ")(input)?.0)?;
|
||||||
|
let (input, reveal_groups) = separated_list0(tag("; "), reveal_group)(tag(": ")(input)?.0)?;
|
||||||
|
|
||||||
|
println!("{id} {:?}", reveal_groups);
|
||||||
|
Ok((input, Game { id, reveal_groups }))
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Day2 {}
|
||||||
|
impl Day2 {}
|
||||||
|
|
||||||
|
impl AoCSolution for Day2 {
|
||||||
|
type Input = String;
|
||||||
|
type Solution = Solution;
|
||||||
|
|
||||||
|
fn part1(input: Self::Input) -> Self::Solution {
|
||||||
|
const MAX_RED: Solution = 12;
|
||||||
|
const MAX_GREEN: Solution = 13;
|
||||||
|
const MAX_BLUE: Solution = 14;
|
||||||
|
|
||||||
|
let valid_reveal_group = |rg: &RevealGroup| {
|
||||||
|
rg.red.unwrap_or(0) <= MAX_RED
|
||||||
|
&& rg.green.unwrap_or(0) <= MAX_GREEN
|
||||||
|
&& rg.blue.unwrap_or(0) <= MAX_BLUE
|
||||||
|
};
|
||||||
|
|
||||||
|
input
|
||||||
|
.lines()
|
||||||
|
.map(|s| game(s).unwrap().1)
|
||||||
|
.filter(|g| g.reveal_groups.iter().all(valid_reveal_group))
|
||||||
|
.map(|g| g.id)
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2(input: Self::Input) -> Self::Solution {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test() {
|
||||||
|
assert_eq!(
|
||||||
|
Day2::part1(
|
||||||
|
r#"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"#
|
||||||
|
.into()
|
||||||
|
),
|
||||||
|
8
|
||||||
|
);
|
||||||
|
assert_eq!(Day2::part2(r#""#.into()), 0);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue