Skip to content

Commit

Permalink
Day 2: Cube Conundrum
Browse files Browse the repository at this point in the history
  • Loading branch information
ephemient committed Dec 2, 2023
1 parent 6565fcd commit 837398b
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 3 deletions.
2 changes: 1 addition & 1 deletion rs/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# [Advent of Code 2022](https://adventofcode.com/2022)
# [Advent of Code 2023](https://adventofcode.com/2023)
### my answers in [Rust](https://www.rust-lang.org/) ![Rust CI](https://github.com/ephemient/aoc2022/workflows/Rust%20CI/badge.svg)

This project builds with [Cargo](https://docs.rust-lang.org/cargo).
Expand Down
8 changes: 7 additions & 1 deletion rs/benches/criterion.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use aoc2023::day1;
use aoc2023::{day1, day2};
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use std::env;
use std::fs;
Expand All @@ -19,6 +19,12 @@ fn aoc2023_bench(c: &mut Criterion) -> Result<(), io::Error> {
g.bench_function("part 1", |b| b.iter(|| day1::part1(black_box(&data))));
g.bench_function("part 2", |b| b.iter(|| day1::part2(black_box(&data))));
g.finish();

let data = get_day_input(2)?;
let mut g = c.benchmark_group("day 2");
g.bench_function("part 1", |b| b.iter(|| day2::part1(black_box(&data))));
g.bench_function("part 2", |b| b.iter(|| day2::part2(black_box(&data))));
g.finish();
Ok(())
}

Expand Down
71 changes: 71 additions & 0 deletions rs/src/day2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use std::cmp::max;
use std::collections::BTreeMap;

fn parse(data: &str) -> Vec<(u32, BTreeMap<&str, u32>)> {
data.lines()
.filter_map(|line| {
let line = line.strip_prefix("Game ")?;
let (game_id, line) = line.split_once(":")?;
let game_id = game_id.parse().ok()?;
let mut cubes = BTreeMap::<&str, u32>::new();
for part in line.split([',', ';']) {
let (count, color) = part.strip_prefix(' ')?.split_once(' ')?;
let count = count.parse().ok()?;
cubes
.entry(color)
.and_modify(|x| *x = max(*x, count))
.or_insert(count);
}
Some((game_id, cubes))
})
.collect()
}

pub fn part1(data: &str) -> u32 {
parse(data)
.into_iter()
.filter_map(|(game_id, mut cubes)| {
if cubes.remove("red").unwrap_or(0) <= 12
&& cubes.remove("green").unwrap_or(0) <= 13
&& cubes.remove("blue").unwrap_or(0) <= 14
&& cubes.is_empty()
{
Some(game_id)
} else {
None
}
})
.sum()
}

pub fn part2(data: &str) -> u32 {
parse(data)
.into_iter()
.map(|(_, cubes)| cubes.into_iter().map(|(_, count)| count).product::<u32>())
.sum()
}

#[cfg(test)]
mod tests {
use super::*;
use indoc::indoc;
use pretty_assertions::assert_eq;

static EXAMPLE: &str = indoc! {"
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
"};

#[test]
fn part1_examples() {
assert_eq!(8, part1(EXAMPLE));
}

#[test]
fn part2_examples() {
assert_eq!(2286, part2(EXAMPLE));
}
}
1 change: 1 addition & 0 deletions rs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod day1;
pub mod day2;
10 changes: 9 additions & 1 deletion rs/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use aoc2023::day1;
use aoc2023::{day1, day2};
use std::collections::HashSet;
use std::env;
use std::fs;
Expand All @@ -24,5 +24,13 @@ fn main() -> io::Result<()> {
println!();
}

if args.is_empty() || args.contains("2") {
let data = get_day_input(2)?;
println!("Day 2");
println!("{:?}", day2::part1(&data));
println!("{:?}", day2::part2(&data));
println!();
}

Ok(())
}

0 comments on commit 837398b

Please sign in to comment.