Skip to content

Commit

Permalink
Year 2017: Day 14
Browse files Browse the repository at this point in the history
  • Loading branch information
joshleaves committed Mar 28, 2024
1 parent 123bc36 commit 97d52fb
Show file tree
Hide file tree
Showing 10 changed files with 205 additions and 65 deletions.
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 = "2017.13.1"
version = "2017.14.1"
edition = "2021"
authors = ["Arnaud 'red' Rouyer"]
readme = "README.md"
Expand Down
4 changes: 4 additions & 0 deletions NOTES_2017.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,7 @@ I hate traversing trees. But you don't always have to.
## Day 13: Packet Scanners

The maths were a bit annoying on this one, and I was hoping for a specific mathematical formula that would prevent me from looping over all scenarios. I found something that felt promising and ported the code from Python, but to no avail, my original code was already faster...

## Day 14: Disk Defragmentation

I kinda liked this one.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,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, complete!](NOTES_2016.md)
- [2017, up to day 13](NOTES_2017.md)
- [2017, up to day 14](NOTES_2017.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
67 changes: 42 additions & 25 deletions benches/year_2017.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ use advent_rs::year_2017::day_10;
use advent_rs::year_2017::day_11;
use advent_rs::year_2017::day_12;
use advent_rs::year_2017::day_13;
use advent_rs::year_2017::day_14;
use criterion::{black_box, criterion_group, criterion_main, Criterion};

fn year_2017_day_01(c: &mut Criterion) {
let input_day_01 = include_str!("../inputs/year_2017/day_01_input");
assert_eq!(day_01::day_01_v1(black_box(input_day_01)), 1_069);
assert_eq!(day_01::day_01_v2(black_box(input_day_01)), 1_268);
assert_eq!(day_01::day_01_v1(input_day_01), 1_069);
assert_eq!(day_01::day_01_v2(input_day_01), 1_268);

let mut g2017_day_01 = c.benchmark_group("year_2017::day_01");
g2017_day_01.bench_function("year_2017::day_01_v1", |b| {
Expand All @@ -30,8 +31,8 @@ fn year_2017_day_01(c: &mut Criterion) {

fn year_2017_day_02(c: &mut Criterion) {
let input_day_02 = include_str!("../inputs/year_2017/day_02_input");
assert_eq!(day_02::day_02_v1(black_box(input_day_02)), 53_978);
assert_eq!(day_02::day_02_v2(black_box(input_day_02)), 314);
assert_eq!(day_02::day_02_v1(input_day_02), 53_978);
assert_eq!(day_02::day_02_v2(input_day_02), 314);

let mut g2017_day_02 = c.benchmark_group("year_2017::day_02");
g2017_day_02.bench_function("year_2017::day_02_v1", |b| {
Expand All @@ -45,8 +46,8 @@ fn year_2017_day_02(c: &mut Criterion) {

fn year_2017_day_03(c: &mut Criterion) {
let input_day_03 = include_str!("../inputs/year_2017/day_03_input");
assert_eq!(day_03::day_03_v1(black_box(input_day_03)), 552);
assert_eq!(day_03::day_03_v2(black_box(input_day_03)), 330_785);
assert_eq!(day_03::day_03_v1(input_day_03), 552);
assert_eq!(day_03::day_03_v2(input_day_03), 330_785);

let mut g2017_day_03 = c.benchmark_group("year_2017::day_03");
g2017_day_03.bench_function("year_2017::day_03_v1", |b| {
Expand All @@ -60,8 +61,8 @@ fn year_2017_day_03(c: &mut Criterion) {

fn year_2017_day_04(c: &mut Criterion) {
let input_day_04 = include_str!("../inputs/year_2017/day_04_input");
assert_eq!(day_04::day_04_v1(black_box(input_day_04)), 466);
assert_eq!(day_04::day_04_v2(black_box(input_day_04)), 251);
assert_eq!(day_04::day_04_v1(input_day_04), 466);
assert_eq!(day_04::day_04_v2(input_day_04), 251);

let mut g2017_day_04 = c.benchmark_group("year_2017::day_04");
g2017_day_04.bench_function("year_2017::day_04_v1", |b| {
Expand All @@ -75,8 +76,8 @@ fn year_2017_day_04(c: &mut Criterion) {

fn year_2017_day_05(c: &mut Criterion) {
let input_day_05 = include_str!("../inputs/year_2017/day_05_input");
assert_eq!(day_05::day_05_v1(black_box(input_day_05)), 373_160);
assert_eq!(day_05::day_05_v2(black_box(input_day_05)), 26_395_586);
assert_eq!(day_05::day_05_v1(input_day_05), 373_160);
assert_eq!(day_05::day_05_v2(input_day_05), 26_395_586);

let mut g2017_day_05 = c.benchmark_group("year_2017::day_05");
g2017_day_05.bench_function("year_2017::day_05_v1", |b| {
Expand All @@ -90,8 +91,8 @@ fn year_2017_day_05(c: &mut Criterion) {

fn year_2017_day_06(c: &mut Criterion) {
let input_day_06 = include_str!("../inputs/year_2017/day_06_input");
assert_eq!(day_06::day_06_v1(black_box(input_day_06)), 11_137);
assert_eq!(day_06::day_06_v2(black_box(input_day_06)), 1_037);
assert_eq!(day_06::day_06_v1(input_day_06), 11_137);
assert_eq!(day_06::day_06_v2(input_day_06), 1_037);

let mut g2017_day_06 = c.benchmark_group("year_2017::day_06");
g2017_day_06.bench_function("year_2017::day_06_v1", |b| {
Expand All @@ -105,8 +106,8 @@ fn year_2017_day_06(c: &mut Criterion) {

fn year_2017_day_07(c: &mut Criterion) {
let input_day_07 = include_str!("../inputs/year_2017/day_07_input");
assert_eq!(day_07::day_07_v1(black_box(input_day_07)), "ykpsek");
assert_eq!(day_07::day_07_v2(black_box(input_day_07)), "1060");
assert_eq!(day_07::day_07_v1(input_day_07), "ykpsek");
assert_eq!(day_07::day_07_v2(input_day_07), "1060");

let mut g2017_day_07 = c.benchmark_group("year_2017::day_07");
g2017_day_07.bench_function("year_2017::day_07_v1", |b| {
Expand All @@ -120,8 +121,8 @@ fn year_2017_day_07(c: &mut Criterion) {

fn year_2017_day_08(c: &mut Criterion) {
let input_day_08 = include_str!("../inputs/year_2017/day_08_input");
assert_eq!(day_08::day_08_v1(black_box(input_day_08)), 4_163);
assert_eq!(day_08::day_08_v2(black_box(input_day_08)), 5_347);
assert_eq!(day_08::day_08_v1(input_day_08), 4_163);
assert_eq!(day_08::day_08_v2(input_day_08), 5_347);

let mut g2017_day_08 = c.benchmark_group("year_2017::day_08");
g2017_day_08.bench_function("year_2017::day_08_v1", |b| {
Expand All @@ -135,8 +136,8 @@ fn year_2017_day_08(c: &mut Criterion) {

fn year_2017_day_09(c: &mut Criterion) {
let input_day_09 = include_str!("../inputs/year_2017/day_09_input");
assert_eq!(day_09::day_09_v1(black_box(input_day_09)), 17_537);
assert_eq!(day_09::day_09_v2(black_box(input_day_09)), 7_539);
assert_eq!(day_09::day_09_v1(input_day_09), 17_537);
assert_eq!(day_09::day_09_v2(input_day_09), 7_539);

let mut g2017_day_09 = c.benchmark_group("year_2017::day_09");
g2017_day_09.bench_function("year_2017::day_09_v1", |b| {
Expand Down Expand Up @@ -168,8 +169,8 @@ fn year_2017_day_10(c: &mut Criterion) {

fn year_2017_day_11(c: &mut Criterion) {
let input_day_11 = include_str!("../inputs/year_2017/day_11_input");
assert_eq!(day_11::day_11_v1(black_box(input_day_11)), 682);
assert_eq!(day_11::day_11_v2(black_box(input_day_11)), 1_406);
assert_eq!(day_11::day_11_v1(input_day_11), 682);
assert_eq!(day_11::day_11_v2(input_day_11), 1_406);

let mut g2017_day_11 = c.benchmark_group("year_2017::day_11");
g2017_day_11.bench_function("year_2017::day_11_v1", |b| {
Expand All @@ -183,8 +184,8 @@ fn year_2017_day_11(c: &mut Criterion) {

fn year_2017_day_12(c: &mut Criterion) {
let input_day_12 = include_str!("../inputs/year_2017/day_12_input");
assert_eq!(day_12::day_12_v1(black_box(input_day_12)), 130);
assert_eq!(day_12::day_12_v2(black_box(input_day_12)), 189);
assert_eq!(day_12::day_12_v1(input_day_12), 130);
assert_eq!(day_12::day_12_v2(input_day_12), 189);

let mut g2017_day_12 = c.benchmark_group("year_2017::day_12");
g2017_day_12.bench_function("year_2017::day_12_v1", |b| {
Expand All @@ -198,8 +199,8 @@ fn year_2017_day_12(c: &mut Criterion) {

fn year_2017_day_13(c: &mut Criterion) {
let input_day_13 = include_str!("../inputs/year_2017/day_13_input");
assert_eq!(day_13::day_13_v1(black_box(input_day_13)), 2_264);
assert_eq!(day_13::day_13_v2(black_box(input_day_13)), 3_875_838);
assert_eq!(day_13::day_13_v1(input_day_13), 2_264);
assert_eq!(day_13::day_13_v2(input_day_13), 3_875_838);

let mut g2017_day_13 = c.benchmark_group("year_2017::day_13");
g2017_day_13.bench_function("year_2017::day_13_v1", |b| {
Expand All @@ -211,6 +212,21 @@ fn year_2017_day_13(c: &mut Criterion) {
g2017_day_13.finish();
}

fn year_2017_day_14(c: &mut Criterion) {
let input_day_14 = include_str!("../inputs/year_2017/day_14_input");
assert_eq!(day_14::day_14_v1(input_day_14), 8_230);
assert_eq!(day_14::day_14_v2(input_day_14), 1_103);

let mut g2017_day_14 = c.benchmark_group("year_2017::day_14");
g2017_day_14.bench_function("year_2017::day_14_v1", |b| {
b.iter(|| day_14::day_14_v1(black_box(input_day_14)))
});
g2017_day_14.bench_function("year_2017::day_14_v2", |b| {
b.iter(|| day_14::day_14_v2(black_box(input_day_14)))
});
g2017_day_14.finish();
}

criterion_group!(
benches,
year_2017_day_01,
Expand All @@ -225,6 +241,7 @@ criterion_group!(
year_2017_day_10,
year_2017_day_11,
year_2017_day_12,
year_2017_day_13
year_2017_day_13,
year_2017_day_14
);
criterion_main!(benches);
1 change: 1 addition & 0 deletions inputs/year_2017/day_14_input
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
hfdlxzhv
1 change: 1 addition & 0 deletions src/year_2016.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#![doc = include_str!("../NOTES_2016.md")]

mod assembunny;

pub mod day_01;
pub mod day_02;
pub mod day_03;
Expand Down
11 changes: 11 additions & 0 deletions src/year_2017.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
//!
#![doc = include_str!("../NOTES_2017.md")]

mod knot_hash;

pub mod day_01;
pub mod day_02;
pub mod day_03;
Expand All @@ -15,6 +17,7 @@ pub mod day_10;
pub mod day_11;
pub mod day_12;
pub mod day_13;
pub mod day_14;

pub fn solve(day: u8, part: u8, input: impl Into<String>) -> Option<String> {
if part > 2 {
Expand All @@ -35,6 +38,7 @@ pub fn solve(day: u8, part: u8, input: impl Into<String>) -> Option<String> {
11 => Some(day_11::day_11(part, input).to_string()),
12 => Some(day_12::day_12(part, input).to_string()),
13 => Some(day_13::day_13(part, input).to_string()),
14 => Some(day_14::day_14(part, input).to_string()),
_ => None,
}
}
Expand Down Expand Up @@ -133,4 +137,11 @@ mod tests {
assert_eq!(day_13::day_13_v1(input), 2_264);
assert_eq!(day_13::day_13_v2(input), 3_875_838);
}

#[test]
fn day_14() {
let input = include_str!("../inputs/year_2017/day_14_input");
assert_eq!(day_14::day_14_v1(input), 8_230);
assert_eq!(day_14::day_14_v2(input), 1_103);
}
}
47 changes: 9 additions & 38 deletions src/year_2017/day_10.rs
Original file line number Diff line number Diff line change
@@ -1,59 +1,30 @@
use itertools::Itertools;
use super::knot_hash;

#[inline]
fn parse_jumps_v1(input: &str) -> Vec<u32> {
fn parse_jumps(input: &str) -> Vec<u32> {
input
.trim_end()
.split(',')
.map(|number| number.trim().parse::<u32>().unwrap())
.collect()
}

#[inline]
fn parse_jumps_v2(input: &str) -> Vec<u32> {
fn parse_input(input: &str) -> Vec<u32> {
input
.trim_end()
.bytes()
.map(|number| number as u32)
.collect()
}

fn knot_hash(size: u32, jumps: &[u32], rounds: u32) -> Vec<u32> {
let mut numbers: Vec<_> = (0..size).collect_vec();
let num_lens = numbers.len();
let mut jumps_done = 0;
let mut skip_size = 0;

for _ in 0..rounds {
for jump in jumps.iter() {
let extract = numbers[0..*jump as usize]
.iter()
.cloned()
.rev()
.collect_vec();
numbers.splice(0..*jump as usize, extract);
numbers.rotate_left(((jump + skip_size) % num_lens as u32) as usize);
jumps_done += (jump + skip_size) % num_lens as u32;
skip_size += 1;
}
}
numbers.rotate_right(jumps_done as usize % num_lens);

numbers
}

pub fn day_10_v1(input: impl Into<String>) -> String {
let numbers = knot_hash(256, &parse_jumps_v1(&input.into()), 1);
let numbers = knot_hash::_knot_hash(256, &parse_jumps(&input.into()), 1);
(numbers[0] * numbers[1]).to_string()
}

pub fn day_10_v2(input: impl Into<String>) -> String {
let mut jumps = parse_jumps_v2(&input.into());
jumps.append(&mut vec![17, 31, 73, 47, 23]);

knot_hash(256, &jumps, 64)
.chunks(16)
.map(|chunk| chunk.iter().fold(0, |acc, &val| acc ^ val) as u8)
let mut input = parse_input(&input.into());
knot_hash::knot_hash(&mut input)
.iter()
.map(|xor| format!("{:02x}", xor))
.collect::<Vec<_>>()
.join("")
Expand All @@ -67,8 +38,8 @@ mod tests {

#[test]
fn works_with_samples_v1() {
let jumps = parse_jumps_v1("3, 4, 1, 5");
let numbers = knot_hash(5, &jumps, 1);
let jumps = parse_jumps("3, 4, 1, 5");
let numbers = knot_hash::_knot_hash(5, &jumps, 1);
assert_eq!(numbers[0] * numbers[1], 12);
}

Expand Down
Loading

0 comments on commit 97d52fb

Please sign in to comment.