Skip to content

Commit

Permalink
Year 2018: Day 05
Browse files Browse the repository at this point in the history
  • Loading branch information
joshleaves committed Apr 20, 2024
1 parent 7c64d37 commit 0e03067
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ Of note:
- The changelog 2015.5.2 has been rewritten from each commit content.
- This file may be amended entirely in the future to adhere to the [GNU Changelog style](https://www.gnu.org/prep/standards/html_node/Style-of-Change-Logs.html#Style-of-Change-Logs)

## [2018.5.1]
### Added
- Solved [exercice for 2018, day 05](src/year_2018/05.rs).

## [2018.4.1]
### Added
- Solved [exercice for 2018, day 04](src/year_2018/04.rs).
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "advent-rs"
version = "2018.4.1"
version = "2018.5.1"
edition = "2021"
authors = ["Arnaud 'red' Rouyer"]
readme = "README.md"
Expand Down
4 changes: 4 additions & 0 deletions NOTES_2018.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ Not much we haven't seen last year.
## Day 04: Repose Record

There's something about this "find the most used record" type of exercises that I dislike.

## Day 05: Alchemical Reduction

As a programmer, your MUST have used, at least once, the command [`man ascii`](https://man.archlinux.org/man/core/man-pages/ascii.7.en), if only to find the integer value of a specific number. But were you to look specifically at the hexadecimal table, something may have caught your attention: uppercase letters, and their equivalent lowercase values, are all separated by 32 characters. Now, isn't that a nice number that plays VERY WELL with bit masks? Here's a little [playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=d9a88346debfc3c2470c6b1527202f30) to help you!
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ I'm also adding notes that may be useful if you're (like me) discovering Rust:
- [2015, complete!](NOTES_2015.md)
- [2016, complete!](NOTES_2016.md)
- [2017, complete!](NOTES_2017.md)
- [2018, up to day 04](NOTES_2018.md)
- [2018, up to day 05](NOTES_2018.md)

# Regarding style rules
I'm gonna use a mix of what `cargo fmt` does, with some stuff that feels more natural to me.
Expand Down
19 changes: 18 additions & 1 deletion benches/year_2018.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use advent_rs::year_2018::day_01;
use advent_rs::year_2018::day_02;
use advent_rs::year_2018::day_03;
use advent_rs::year_2018::day_04;
use advent_rs::year_2018::day_05;
use criterion::{black_box, criterion_group, criterion_main, Criterion};

fn year_2018_day_01(c: &mut Criterion) {
Expand Down Expand Up @@ -64,11 +65,27 @@ fn year_2018_day_04(c: &mut Criterion) {
g2018_day_04.finish();
}

fn year_2018_day_05(c: &mut Criterion) {
let input = include_str!("../inputs/year_2018/day_05_input");
assert_eq!(day_05::day_05_v1(input), 11_298);
assert_eq!(day_05::day_05_v2(input), 5_148);

let mut g2018_day_05 = c.benchmark_group("year_2018::day_05");
g2018_day_05.bench_function("year_2018::day_05_v1", |b| {
b.iter(|| day_05::day_05_v1(black_box(input)))
});
g2018_day_05.bench_function("year_2018::day_05_v2", |b| {
b.iter(|| day_05::day_05_v2(black_box(input)))
});
g2018_day_05.finish();
}

criterion_group!(
benches,
year_2018_day_01,
year_2018_day_02,
year_2018_day_03,
year_2018_day_04
year_2018_day_04,
year_2018_day_05
);
criterion_main!(benches);
1 change: 1 addition & 0 deletions inputs/year_2018/day_05_input

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions src/year_2018.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub mod day_01;
pub mod day_02;
pub mod day_03;
pub mod day_04;
pub mod day_05;

pub fn solve(day: u8, part: u8, input: impl Into<String>) -> Option<String> {
if part > 2 {
Expand All @@ -17,6 +18,7 @@ pub fn solve(day: u8, part: u8, input: impl Into<String>) -> Option<String> {
2 => Some(day_02::day_02(part, input).to_string()),
3 => Some(day_03::day_03(part, input).to_string()),
4 => Some(day_04::day_04(part, input).to_string()),
5 => Some(day_05::day_05(part, input).to_string()),
_ => None,
}
}
Expand Down Expand Up @@ -52,4 +54,11 @@ mod tests {
assert_eq!(day_04::day_04_v1(input), 35_623);
assert_eq!(day_04::day_04_v2(input), 23_037);
}

#[test]
fn day_05() {
let input = include_str!("../inputs/year_2018/day_05_input");
assert_eq!(day_05::day_05_v1(input), 11_298);
assert_eq!(day_05::day_05_v2(input), 5_148);
}
}
55 changes: 55 additions & 0 deletions src/year_2018/day_05.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
fn react_polymer(input: &str) -> u16 {
input
.bytes()
.fold(vec![], |mut acc, chr| {
if !acc.is_empty() && *acc.last().unwrap() == (chr ^ 32) {
acc.pop();
} else {
acc.push(chr);
}
acc
})
.len() as u16
}

pub fn day_05_v1(input: impl Into<String>) -> u16 {
react_polymer(&input.into())
}

pub fn day_05_v2(input: impl Into<String>) -> u16 {
let input = input.into();
let maj = 'A'..='Z';
('a'..='z')
.zip(maj)
.map(|(min, maj)| react_polymer(&input.replace([min, maj], "")))
.min()
.unwrap()
}

solvable!(day_05, day_05_v1, day_05_v2, u16);

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

const SAMPLE: &str = "dabAcCaCBAcCcaDA";

#[test]
fn works_with_samples_v1() {
let sample_one = [
("aA", 0),
("abBA", 0),
("abAB", 4),
("aabAAB", 6),
(SAMPLE, 10),
];
for (sample, result) in sample_one {
assert_eq!(day_05_v1(sample), result);
}
}

#[test]
fn works_with_samples_v2() {
assert_eq!(day_05_v2(SAMPLE), 4);
}
}

0 comments on commit 0e03067

Please sign in to comment.