Skip to content

Instantly share code, notes, and snippets.

@typester
Created December 3, 2023 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save typester/af399b40851cca9d4c9150127313c404 to your computer and use it in GitHub Desktop.
Save typester/af399b40851cca9d4c9150127313c404 to your computer and use it in GitHub Desktop.
2023 Advent of Code Day 2
use lazy_static::lazy_static;
use regex::Regex;
const INPUT: &str = "..snip..";
fn main() {
let sum: u32 = INPUT.lines()
.map(parse_game_info)
.filter(check_cube_count)
.map(|game| game.id)
.sum();
println!("part1: {}", sum);
let sum: u32 = INPUT.lines()
.map(parse_game_info)
.map(|game| power(&game))
.sum();
println!("part2: {}", sum);
}
struct Game {
id: u32,
cubes: Vec<CubeSet>,
}
struct CubeSet {
red: u32,
green: u32,
blue: u32,
}
fn parse_game_info(s: &str) -> Game {
lazy_static! {
static ref RE_GAME: Regex = Regex::new(r"Game (\d+)").unwrap();
static ref RE_CUBES: Regex = Regex::new(r"(?:(?<red>\d+) red|(?<green>\d+) green|(?<blue>\d+) blue)").unwrap();
}
let (stage, body) = {
let mut i = s.splitn(2, ": ");
(i.next().unwrap(), i.next().unwrap())
};
let stage = match RE_GAME.captures(stage) {
Some(c) => {
match c.get(1) {
Some(n) => n.as_str().parse::<u32>().expect("not number"),
None => panic!("invalid input"),
}
},
None => panic!("invalid input"),
};
let mut cubes: Vec<CubeSet> = vec![];
let mut iter = body.split(";");
while let Some(cubes_info) = iter.next() {
let (mut r, mut g, mut b): (u32, u32, u32) = (0, 0, 0);
let mut caps = RE_CUBES.captures_iter(cubes_info);
while let Some(c) = caps.next() {
r += c.name("red").and_then(|c| Some(c.as_str().parse::<u32>().unwrap_or(0))).unwrap_or(0);
g += c.name("green").and_then(|c| Some(c.as_str().parse::<u32>().unwrap_or(0))).unwrap_or(0);
b += c.name("blue").and_then(|c| Some(c.as_str().parse::<u32>().unwrap_or(0))).unwrap_or(0);
}
cubes.push(CubeSet { red: r, green: g, blue: b });
}
Game { id: stage, cubes }
}
fn check_cube_count(game: &Game) -> bool {
for c in game.cubes.iter() {
if c.red > 12 {
return false
}
if c.green > 13 {
return false
}
if c.blue > 14 {
return false
}
}
true
}
fn power(game: &Game) -> u32 {
let (mut r, mut g, mut b) = (0, 0, 0);
for c in game.cubes.iter() {
if c.red > r {
r = c.red
}
if c.green > g {
g = c.green
}
if c.blue > b {
b = c.blue
}
}
r * g * b
}
#[cfg(test)]
mod tests {
use regex::Regex;
#[test]
fn test_re() {
let re = Regex::new(r"(?:(?<red>\d+) red|(?<green>\d+) green|(?<blue>\d+) blue)").unwrap();
let input = "7 blue, 6 green, 2 red";
let mut iter = re.captures_iter(input);
while let Some(cap) = iter.next() {
let r = cap.name("red").and_then(|c| Some(c.as_str())).unwrap_or("0");
let g = cap.name("green").and_then(|c| Some(c.as_str())).unwrap_or("0");
let b = cap.name("blue").and_then(|c| Some(c.as_str())).unwrap_or("0");
println!("r:{}, g:{}, b:{}", r, g, b);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment