Skip to content

Commit

Permalink
Year 2016: Day 04
Browse files Browse the repository at this point in the history
  • Loading branch information
joshleaves committed Mar 16, 2024
1 parent 1cedcf8 commit 545db4b
Show file tree
Hide file tree
Showing 9 changed files with 1,301 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)

## [2016.4.1]
### Added
- Solved [exercice for 2016, day 04](src/year_2015/day_04.rs).

## [2016.3.1]
### Added
- Solved [exercice for 2016, day 03](src/year_2015/day_03.rs).
Expand Down
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "advent-rs"
version = "2016.3.1"
version = "2016.4.1"
edition = "2021"
authors = ["Arnaud 'red' Rouyer"]
readme = "README.md"
Expand Down Expand Up @@ -54,3 +54,6 @@ harness = false
[[bench]]
name = "year_2015_day_05"
harness = false
[[bench]]
name = "year_2016_day_04"
harness = false
6 changes: 6 additions & 0 deletions NOTES_2016.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,9 @@ I must admit: the biggest pleasure in learning a new language is when it compile
## Day 03:Squares With Three Sides

Iterators can be a special kind of hell in Rust, especially when combined, and each type specializes itself further, but in the end, they work.

## Day 04: Security Through Obscurity

Jumping around between `char`, `u8`, and `i32` is a bit of a pain, but it's not too hard once you get it.

Interestingly, when calculating the checksum, it is FASTER to reiterate over the string for each new character we find, rather than query the index straight from a HashMap.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ As I said, [Consistency is hard](https://github.com/joshleaves/advent-rb), and I

I'm also adding notes that may be useful if you're (like me) discovering Rust:
- [2015, complete!](NOTES_2015.md)
- [2016, up to day 03](NOTES_2016.md)
- [2016, up to day 04](NOTES_2016.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
16 changes: 15 additions & 1 deletion benches/year_2016.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use advent_rs::year_2016::day_01;
use advent_rs::year_2016::day_02;
use advent_rs::year_2016::day_03;
use advent_rs::year_2016::day_04;
use criterion::{black_box, criterion_group, criterion_main, Criterion};

pub fn year_2016_day_01(c: &mut Criterion) {
Expand Down Expand Up @@ -39,10 +40,23 @@ pub fn year_2016_day_03(c: &mut Criterion) {
g2016_day_03.finish();
}

pub fn year_2016_day_04(c: &mut Criterion) {
let mut g2016_day_04 = c.benchmark_group("year_2016::day_04");
let input_year_2016_day_04 = include_str!("../inputs/year_2016/day_04_input");
g2016_day_04.bench_function("year_2016::day_04_v1", |b| {
b.iter(|| day_04::day_04_v1(black_box(input_year_2016_day_04)))
});
g2016_day_04.bench_function("year_2016::day_04_v2", |b| {
b.iter(|| day_04::day_04_v2(black_box(input_year_2016_day_04)))
});
g2016_day_04.finish();
}

criterion_group!(
benches,
year_2016_day_01,
year_2016_day_02,
year_2016_day_03
year_2016_day_03,
year_2016_day_04
);
criterion_main!(benches);
98 changes: 98 additions & 0 deletions benches/year_2016_day_04.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use itertools::Itertools;
use regex::Regex;
use std::{collections::HashMap, time::Duration};

fn verify_checksum_naive(checksum: &str, input: &str) -> bool {
let mut letters_cnt: HashMap<char, u8> = HashMap::new();
for chr in input.chars() {
if chr != '-' {
let counter = letters_cnt.entry(chr).or_insert(0);
*counter += 1;
}
}

let letters = input
.chars()
.unique()
.sorted_by_key(|chr| {
let cnt_chr = if *chr == '-' {
0
} else {
*letters_cnt.get(chr).unwrap()
};
[
cnt_chr as i8 * -1,
*chr as i8,
]
})
.take(5)
.collect::<String>();

letters == checksum
}

fn verify_checksum_fast(checksum: &str, input: &str) -> bool {
let letters = input
.chars()
.unique()
.sorted_by_key(|chr| {
let cnt_chr = if *chr == '-' {
0
} else {
input.chars().filter(|in_chr| in_chr == chr).count()
};
[
cnt_chr as i8 * -1,
*chr as i8,
]
})
.take(5)
.collect::<String>();

letters == checksum
}

pub fn day_04_v1_naive(input: impl Into<String>) -> u32 {
let re = Regex::new(r"(?<letters>[\w-]+)-(?<value>\d+)\[(?<checksum>\w+)\]").unwrap();
let mut result: u32 = 0;
for line in input.into().lines() {
let Some(caps) = re.captures(line) else {
panic!("Incorrect input: {}", line);
};
if verify_checksum_naive(&caps["checksum"], &caps["letters"]) {
result += caps["value"].parse::<u32>().unwrap();
}
}
result
}

pub fn day_04_v1_fast(input: impl Into<String>) -> u32 {
let re = Regex::new(r"(?<letters>[\w-]+)-(?<value>\d+)\[(?<checksum>\w+)\]").unwrap();
let mut result: u32 = 0;
for line in input.into().lines() {
let Some(caps) = re.captures(line) else {
panic!("Incorrect input: {}", line);
};
if verify_checksum_fast(&caps["checksum"], &caps["letters"]) {
result += caps["value"].parse::<u32>().unwrap();
}
}
result
}

pub fn bench_year_2016_day_04_checksum(c: &mut Criterion) {
let mut group = c.benchmark_group("year_2016::day_04_v1");
group.warm_up_time(Duration::from_millis(100));
let input = include_str!("../inputs/year_2016/day_04_input");
group.bench_with_input(BenchmarkId::new("Naive", input.len()), input, |b, input| {
b.iter(|| day_04_v1_naive(input))
});
group.bench_with_input(BenchmarkId::new("Fast", input.len()), input, |b, input| {
b.iter(|| day_04_v1_fast(input))
});
group.finish();
}

criterion_group!(bench_year_2016_day_04, bench_year_2016_day_04_checksum);
criterion_main!(bench_year_2016_day_04);
Loading

0 comments on commit 545db4b

Please sign in to comment.