diff --git a/benches/year_2015.rs b/benches/year_2015.rs index 3fde058..7422383 100644 --- a/benches/year_2015.rs +++ b/benches/year_2015.rs @@ -26,300 +26,372 @@ use advent_rs::year_2015::day_25; use criterion::{black_box, criterion_group, criterion_main, Criterion}; fn year_2015_day_01(c: &mut Criterion) { + let input_day_01 = include_str!("../inputs/year_2015/day_01_input"); + assert_eq!(day_01::day_01_v1(input_day_01), 138); + assert_eq!(day_01::day_01_v2(input_day_01), 1771); + let mut g2015_day_01 = c.benchmark_group("year_2015::day_01"); - let input_year_2015_day_01 = include_str!("../inputs/year_2015/day_01_input"); g2015_day_01.bench_function("year_2015::day_01_v1", |b| { - b.iter(|| day_01::day_01_v1(black_box(input_year_2015_day_01))) + b.iter(|| day_01::day_01_v1(black_box(input_day_01))) }); g2015_day_01.bench_function("year_2015::day_01_v2", |b| { - b.iter(|| day_01::day_01_v2(black_box(input_year_2015_day_01))) + b.iter(|| day_01::day_01_v2(black_box(input_day_01))) }); g2015_day_01.finish(); } fn year_2015_day_02(c: &mut Criterion) { + let input_day_02 = include_str!("../inputs/year_2015/day_02_input"); + assert_eq!(day_02::day_02_v1(input_day_02), 1_588_178); + assert_eq!(day_02::day_02_v2(input_day_02), 3_783_758); + let mut g2015_day_02 = c.benchmark_group("year_2015::day_02"); - let input_year_2015_day_02 = include_str!("../inputs/year_2015/day_02_input"); g2015_day_02.bench_function("year_2015::day_02_v1", |b| { - b.iter(|| day_02::day_02_v1(black_box(input_year_2015_day_02))) + b.iter(|| day_02::day_02_v1(black_box(input_day_02))) }); g2015_day_02.bench_function("year_2015::day_02_v2", |b| { - b.iter(|| day_02::day_02_v2(black_box(input_year_2015_day_02))) + b.iter(|| day_02::day_02_v2(black_box(input_day_02))) }); g2015_day_02.finish(); } fn year_2015_day_03(c: &mut Criterion) { + let input_day_03 = include_str!("../inputs/year_2015/day_03_input"); + assert_eq!(day_03::day_03_v1(input_day_03), 2081); + assert_eq!(day_03::day_03_v2(input_day_03), 2341); + let mut g2015_day_03 = c.benchmark_group("year_2015::day_03"); - g2015_day_03.sample_size(60); - let input_year_2015_day_03 = include_str!("../inputs/year_2015/day_03_input"); g2015_day_03.bench_function("year_2015::day_03_v1", |b| { - b.iter(|| day_03::day_03_v1(black_box(input_year_2015_day_03))) + b.iter(|| day_03::day_03_v1(black_box(input_day_03))) }); g2015_day_03.bench_function("year_2015::day_03_v2", |b| { - b.iter(|| day_03::day_03_v2(black_box(input_year_2015_day_03))) + b.iter(|| day_03::day_03_v2(black_box(input_day_03))) }); g2015_day_03.finish(); } fn year_2015_day_04(c: &mut Criterion) { + let input_day_04 = include_str!("../inputs/year_2015/day_04_input"); + assert_eq!(day_04::day_04_v1(input_day_04), 346_386); + assert_eq!(day_04::day_04_v2(input_day_04), 9_958_218); + let mut g2015_day_04 = c.benchmark_group("year_2015::day_04"); - g2015_day_04.sample_size(10); - let input_year_2015_day_04 = include_str!("../inputs/year_2015/day_04_input"); g2015_day_04.bench_function("year_2015::day_04_v1", |b| { - b.iter(|| day_04::day_04_v1(black_box(input_year_2015_day_04))) + b.iter(|| day_04::day_04_v1(black_box(input_day_04))) }); g2015_day_04.bench_function("year_2015::day_04_v2", |b| { - b.iter(|| day_04::day_04_v2(black_box(input_year_2015_day_04))) + b.iter(|| day_04::day_04_v2(black_box(input_day_04))) }); g2015_day_04.finish(); } fn year_2015_day_05(c: &mut Criterion) { + let input_day_05 = include_str!("../inputs/year_2015/day_05_input"); + assert_eq!(day_05::day_05_v1(input_day_05), 238); + assert_eq!(day_05::day_05_v2(input_day_05), 69); + let mut g2015_day_05 = c.benchmark_group("year_2015::day_05"); - let input_year_2015_day_05 = include_str!("../inputs/year_2015/day_05_input"); g2015_day_05.bench_function("year_2015::day_05_v1", |b| { - b.iter(|| day_05::day_05_v1(black_box(input_year_2015_day_05))) + b.iter(|| day_05::day_05_v1(black_box(input_day_05))) }); g2015_day_05.bench_function("year_2015::day_05_v2", |b| { - b.iter(|| day_05::day_05_v2(black_box(input_year_2015_day_05))) + b.iter(|| day_05::day_05_v2(black_box(input_day_05))) }); g2015_day_05.finish(); } fn year_2015_day_06(c: &mut Criterion) { + let input_day_06 = include_str!("../inputs/year_2015/day_06_input"); + assert_eq!(day_06::day_06_v1(input_day_06), 400_410); + assert_eq!(day_06::day_06_v2(input_day_06), 15_343_601); + let mut g2015_day_06 = c.benchmark_group("year_2015::day_06"); - let input_year_2015_day_06 = include_str!("../inputs/year_2015/day_06_input"); g2015_day_06.bench_function("year_2015::day_06_v1", |b| { - b.iter(|| day_06::day_06_v1(black_box(input_year_2015_day_06))) + b.iter(|| day_06::day_06_v1(black_box(input_day_06))) }); g2015_day_06.bench_function("year_2015::day_06_v2", |b| { - b.iter(|| day_06::day_06_v2(black_box(input_year_2015_day_06))) + b.iter(|| day_06::day_06_v2(black_box(input_day_06))) }); g2015_day_06.finish(); } fn year_2015_day_07(c: &mut Criterion) { + let input_day_07 = include_str!("../inputs/year_2015/day_07_input"); + assert_eq!(day_07::day_07_v1(input_day_07), 46_065); + assert_eq!(day_07::day_07_v2(input_day_07), 14_134); + let mut g2015_day_07 = c.benchmark_group("year_2015::day_07"); - let input_year_2015_day_07 = include_str!("../inputs/year_2015/day_07_input"); g2015_day_07.bench_function("year_2015::day_07_v1", |b| { - b.iter(|| day_07::day_07_v1(black_box(input_year_2015_day_07))) + b.iter(|| day_07::day_07_v1(black_box(input_day_07))) }); g2015_day_07.bench_function("year_2015::day_07_v2", |b| { - b.iter(|| day_07::day_07_v2(black_box(input_year_2015_day_07))) + b.iter(|| day_07::day_07_v2(black_box(input_day_07))) }); g2015_day_07.finish(); } fn year_2015_day_08(c: &mut Criterion) { + let input_day_08 = include_str!("../inputs/year_2015/day_08_input"); + assert_eq!(day_08::day_08_v1(input_day_08), 1_333); + assert_eq!(day_08::day_08_v2(input_day_08), 2_046); + let mut g2015_day_08 = c.benchmark_group("year_2015::day_08"); - let input_year_2015_day_08 = include_str!("../inputs/year_2015/day_08_input"); g2015_day_08.bench_function("year_2015::day_08_v1", |b| { - b.iter(|| day_08::day_08_v1(black_box(input_year_2015_day_08))) + b.iter(|| day_08::day_08_v1(black_box(input_day_08))) }); g2015_day_08.bench_function("year_2015::day_08_v2", |b| { - b.iter(|| day_08::day_08_v2(black_box(input_year_2015_day_08))) + b.iter(|| day_08::day_08_v2(black_box(input_day_08))) }); g2015_day_08.finish(); } fn year_2015_day_09(c: &mut Criterion) { + let input_day_09 = include_str!("../inputs/year_2015/day_09_input"); + assert_eq!(day_09::day_09_v1(input_day_09), 117); + assert_eq!(day_09::day_09_v2(input_day_09), 909); + let mut g2015_day_09 = c.benchmark_group("year_2015::day_09"); - let input_year_2015_day_09 = include_str!("../inputs/year_2015/day_09_input"); g2015_day_09.bench_function("year_2015::day_09_v1", |b| { - b.iter(|| day_09::day_09_v1(black_box(input_year_2015_day_09))) + b.iter(|| day_09::day_09_v1(black_box(input_day_09))) }); g2015_day_09.bench_function("year_2015::day_09_v2", |b| { - b.iter(|| day_09::day_09_v2(black_box(input_year_2015_day_09))) + b.iter(|| day_09::day_09_v2(black_box(input_day_09))) }); g2015_day_09.finish(); } fn year_2015_day_10(c: &mut Criterion) { + let input_day_10 = include_str!("../inputs/year_2015/day_10_input"); + assert_eq!(day_10::day_10_v1(input_day_10), 252_594); + assert_eq!(day_10::day_10_v2(input_day_10), 3_579_328); + let mut g2015_day_10 = c.benchmark_group("year_2015::day_10"); - let input_year_2015_day_10 = include_str!("../inputs/year_2015/day_10_input"); g2015_day_10.bench_function("year_2015::day_10_v1", |b| { - b.iter(|| day_10::day_10_v1(black_box(input_year_2015_day_10))) + b.iter(|| day_10::day_10_v1(black_box(input_day_10))) }); g2015_day_10.bench_function("year_2015::day_10_v2", |b| { - b.iter(|| day_10::day_10_v2(black_box(input_year_2015_day_10))) + b.iter(|| day_10::day_10_v2(black_box(input_day_10))) }); g2015_day_10.finish(); } fn year_2015_day_11(c: &mut Criterion) { + let input_day_11 = include_str!("../inputs/year_2015/day_11_input"); + assert_eq!(day_11::day_11_v1(input_day_11), "vzbxxyzz"); + assert_eq!(day_11::day_11_v2(input_day_11), "vzcaabcc"); + let mut g2015_day_11 = c.benchmark_group("year_2015::day_11"); - let input_year_2015_day_11 = include_str!("../inputs/year_2015/day_11_input"); g2015_day_11.bench_function("year_2015::day_11_v1", |b| { - b.iter(|| day_11::day_11_v1(black_box(input_year_2015_day_11))) + b.iter(|| day_11::day_11_v1(black_box(input_day_11))) }); g2015_day_11.bench_function("year_2015::day_11_v2", |b| { - b.iter(|| day_11::day_11_v2(black_box(input_year_2015_day_11))) + b.iter(|| day_11::day_11_v2(black_box(input_day_11))) }); g2015_day_11.finish(); } fn year_2015_day_12(c: &mut Criterion) { + let input_day_12 = include_str!("../inputs/year_2015/day_12_input"); + assert_eq!(day_12::day_12_v1(input_day_12), 111_754); + assert_eq!(day_12::day_12_v2(input_day_12), 65_402); + let mut g2015_day_12 = c.benchmark_group("year_2015::day_12"); - let input_year_2015_day_12 = include_str!("../inputs/year_2015/day_12_input"); g2015_day_12.bench_function("year_2015::day_12_v1", |b| { - b.iter(|| day_12::day_12_v1(black_box(input_year_2015_day_12))) + b.iter(|| day_12::day_12_v1(black_box(input_day_12))) }); g2015_day_12.bench_function("year_2015::day_12_v2", |b| { - b.iter(|| day_12::day_12_v2(black_box(input_year_2015_day_12))) + b.iter(|| day_12::day_12_v2(black_box(input_day_12))) }); g2015_day_12.finish(); } fn year_2015_day_13(c: &mut Criterion) { + let input_day_13 = include_str!("../inputs/year_2015/day_13_input"); + assert_eq!(day_13::day_13_v1(input_day_13), 709); + assert_eq!(day_13::day_13_v2(input_day_13), 668); + let mut g2015_day_13 = c.benchmark_group("year_2015::day_13"); - let input_year_2015_day_13 = include_str!("../inputs/year_2015/day_13_input"); g2015_day_13.bench_function("year_2015::day_13_v1", |b| { - b.iter(|| day_13::day_13_v1(black_box(input_year_2015_day_13))) + b.iter(|| day_13::day_13_v1(black_box(input_day_13))) }); g2015_day_13.bench_function("year_2015::day_13_v2", |b| { - b.iter(|| day_13::day_13_v2(black_box(input_year_2015_day_13))) + b.iter(|| day_13::day_13_v2(black_box(input_day_13))) }); g2015_day_13.finish(); } fn year_2015_day_14(c: &mut Criterion) { + let input_day_14 = include_str!("../inputs/year_2015/day_14_input"); + assert_eq!(day_14::day_14_v1(input_day_14), 2655); + assert_eq!(day_14::day_14_v2(input_day_14), 1059); + let mut g2015_day_14 = c.benchmark_group("year_2015::day_14"); - let input_year_2015_day_14 = include_str!("../inputs/year_2015/day_14_input"); g2015_day_14.bench_function("year_2015::day_14_v1", |b| { - b.iter(|| day_14::day_14_v1(black_box(input_year_2015_day_14))) + b.iter(|| day_14::day_14_v1(black_box(input_day_14))) }); g2015_day_14.bench_function("year_2015::day_14_v2", |b| { - b.iter(|| day_14::day_14_v2(black_box(input_year_2015_day_14))) + b.iter(|| day_14::day_14_v2(black_box(input_day_14))) }); g2015_day_14.finish(); } fn year_2015_day_15(c: &mut Criterion) { + let input_day_15 = include_str!("../inputs/year_2015/day_15_input"); + assert_eq!(day_15::day_15_v1(input_day_15), 222_870); + assert_eq!(day_15::day_15_v2(input_day_15), 117_936); + let mut g2015_day_15 = c.benchmark_group("year_2015::day_15"); - let input_year_2015_day_15 = include_str!("../inputs/year_2015/day_15_input"); g2015_day_15.bench_function("year_2015::day_15_v1", |b| { - b.iter(|| day_15::day_15_v1(black_box(input_year_2015_day_15))) + b.iter(|| day_15::day_15_v1(black_box(input_day_15))) }); g2015_day_15.bench_function("year_2015::day_15_v2", |b| { - b.iter(|| day_15::day_15_v2(black_box(input_year_2015_day_15))) + b.iter(|| day_15::day_15_v2(black_box(input_day_15))) }); g2015_day_15.finish(); } fn year_2015_day_16(c: &mut Criterion) { + let input_day_16 = include_str!("../inputs/year_2015/day_16_input"); + assert_eq!(day_16::day_16_v1(input_day_16), 373); + assert_eq!(day_16::day_16_v2(input_day_16), 260); + let mut g2015_day_16 = c.benchmark_group("year_2015::day_16"); - let input_year_2015_day_16 = include_str!("../inputs/year_2015/day_16_input"); g2015_day_16.bench_function("year_2015::day_16_v1", |b| { - b.iter(|| day_16::day_16_v1(black_box(input_year_2015_day_16))) + b.iter(|| day_16::day_16_v1(black_box(input_day_16))) }); g2015_day_16.bench_function("year_2015::day_16_v2", |b| { - b.iter(|| day_16::day_16_v2(black_box(input_year_2015_day_16))) + b.iter(|| day_16::day_16_v2(black_box(input_day_16))) }); g2015_day_16.finish(); } fn year_2015_day_17(c: &mut Criterion) { + let input_day_17 = include_str!("../inputs/year_2015/day_17_input"); + assert_eq!(day_17::day_17_v1(input_day_17), 1_638); + assert_eq!(day_17::day_17_v2(input_day_17), 17); + let mut g2015_day_17 = c.benchmark_group("year_2015::day_17"); - let input_year_2015_day_17 = include_str!("../inputs/year_2015/day_17_input"); g2015_day_17.bench_function("year_2015::day_17_v1", |b| { - b.iter(|| day_17::day_17_v1(black_box(input_year_2015_day_17))) + b.iter(|| day_17::day_17_v1(black_box(input_day_17))) }); g2015_day_17.bench_function("year_2015::day_17_v2", |b| { - b.iter(|| day_17::day_17_v2(black_box(input_year_2015_day_17))) + b.iter(|| day_17::day_17_v2(black_box(input_day_17))) }); g2015_day_17.finish(); } fn year_2015_day_18(c: &mut Criterion) { + let input_day_18 = include_str!("../inputs/year_2015/day_18_input"); + assert_eq!(day_18::day_18_v1(input_day_18), 821); + assert_eq!(day_18::day_18_v2(input_day_18), 886); + let mut g2015_day_18 = c.benchmark_group("year_2015::day_18"); - let input_year_2015_day_18 = include_str!("../inputs/year_2015/day_18_input"); g2015_day_18.bench_function("year_2015::day_18_v1", |b| { - b.iter(|| day_18::day_18_v1(black_box(input_year_2015_day_18))) + b.iter(|| day_18::day_18_v1(black_box(input_day_18))) }); g2015_day_18.bench_function("year_2015::day_18_v2", |b| { - b.iter(|| day_18::day_18_v2(black_box(input_year_2015_day_18))) + b.iter(|| day_18::day_18_v2(black_box(input_day_18))) }); g2015_day_18.finish(); } fn year_2015_day_19(c: &mut Criterion) { + let input_day_19 = include_str!("../inputs/year_2015/day_19_input"); + assert_eq!(day_19::day_19_v1(input_day_19), 576); + assert_eq!(day_19::day_19_v2(input_day_19), 207); + let mut g2015_day_19 = c.benchmark_group("year_2015::day_19"); - let input_year_2015_day_19 = include_str!("../inputs/year_2015/day_19_input"); g2015_day_19.bench_function("year_2015::day_19_v1", |b| { - b.iter(|| day_19::day_19_v1(black_box(input_year_2015_day_19))) + b.iter(|| day_19::day_19_v1(black_box(input_day_19))) }); g2015_day_19.bench_function("year_2015::day_19_v2", |b| { - b.iter(|| day_19::day_19_v2(black_box(input_year_2015_day_19))) + b.iter(|| day_19::day_19_v2(black_box(input_day_19))) }); g2015_day_19.finish(); } fn year_2015_day_20(c: &mut Criterion) { + let input_day_20 = include_str!("../inputs/year_2015/day_20_input"); + assert_eq!(day_20::day_20_v1(input_day_20), 831_600); + assert_eq!(day_20::day_20_v2(input_day_20), 884_520); + let mut g2015_day_20 = c.benchmark_group("year_2015::day_20"); - let input_year_2015_day_20 = include_str!("../inputs/year_2015/day_20_input"); g2015_day_20.bench_function("year_2015::day_20_v1", |b| { - b.iter(|| day_20::day_20_v1(black_box(input_year_2015_day_20))) + b.iter(|| day_20::day_20_v1(black_box(input_day_20))) }); g2015_day_20.bench_function("year_2015::day_20_v2", |b| { - b.iter(|| day_20::day_20_v2(black_box(input_year_2015_day_20))) + b.iter(|| day_20::day_20_v2(black_box(input_day_20))) }); g2015_day_20.finish(); } fn year_2015_day_21(c: &mut Criterion) { + let input_day_21 = include_str!("../inputs/year_2015/day_21_input"); + assert_eq!(day_21::day_21_v1(input_day_21), 91); + assert_eq!(day_21::day_21_v2(input_day_21), 158); + let mut g2015_day_21 = c.benchmark_group("year_2015::day_21"); - let input_year_2015_day_21 = include_str!("../inputs/year_2015/day_21_input"); g2015_day_21.bench_function("year_2015::day_21_v1", |b| { - b.iter(|| day_21::day_21_v1(black_box(input_year_2015_day_21))) + b.iter(|| day_21::day_21_v1(black_box(input_day_21))) }); g2015_day_21.bench_function("year_2015::day_21_v2", |b| { - b.iter(|| day_21::day_21_v2(black_box(input_year_2015_day_21))) + b.iter(|| day_21::day_21_v2(black_box(input_day_21))) }); g2015_day_21.finish(); } fn year_2015_day_22(c: &mut Criterion) { + let input_day_22 = include_str!("../inputs/year_2015/day_22_input"); + assert_eq!(day_22::day_22_v1(input_day_22), 953); + assert_eq!(day_22::day_22_v2(input_day_22), 1289); + let mut g2015_day_22 = c.benchmark_group("year_2015::day_22"); - let input_year_2015_day_22 = include_str!("../inputs/year_2015/day_22_input"); g2015_day_22.bench_function("year_2015::day_22_v1", |b| { - b.iter(|| day_22::day_22_v1(black_box(input_year_2015_day_22))) + b.iter(|| day_22::day_22_v1(black_box(input_day_22))) }); g2015_day_22.bench_function("year_2015::day_22_v2", |b| { - b.iter(|| day_22::day_22_v2(black_box(input_year_2015_day_22))) + b.iter(|| day_22::day_22_v2(black_box(input_day_22))) }); g2015_day_22.finish(); } fn year_2015_day_23(c: &mut Criterion) { + let input_day_23 = include_str!("../inputs/year_2015/day_23_input"); + assert_eq!(day_23::day_23_v1(input_day_23), 307); + assert_eq!(day_23::day_23_v2(input_day_23), 160); + let mut g2015_day_23 = c.benchmark_group("year_2015::day_23"); - let input_year_2015_day_23 = include_str!("../inputs/year_2015/day_23_input"); g2015_day_23.bench_function("year_2015::day_23_v1", |b| { - b.iter(|| day_23::day_23_v1(black_box(input_year_2015_day_23))) + b.iter(|| day_23::day_23_v1(black_box(input_day_23))) }); g2015_day_23.bench_function("year_2015::day_23_v2", |b| { - b.iter(|| day_23::day_23_v2(black_box(input_year_2015_day_23))) + b.iter(|| day_23::day_23_v2(black_box(input_day_23))) }); g2015_day_23.finish(); } fn year_2015_day_24(c: &mut Criterion) { + let input_day_24 = include_str!("../inputs/year_2015/day_24_input"); + assert_eq!(day_24::day_24_v1(input_day_24), 10_439_961_859); + assert_eq!(day_24::day_24_v2(input_day_24), 72_050_269); + let mut g2015_day_24 = c.benchmark_group("year_2015::day_24"); - let input_year_2015_day_24 = include_str!("../inputs/year_2015/day_24_input"); g2015_day_24.bench_function("year_2015::day_24_v1", |b| { - b.iter(|| day_24::day_24_v1(black_box(input_year_2015_day_24))) + b.iter(|| day_24::day_24_v1(black_box(input_day_24))) }); g2015_day_24.bench_function("year_2015::day_24_v2", |b| { - b.iter(|| day_24::day_24_v2(black_box(input_year_2015_day_24))) + b.iter(|| day_24::day_24_v2(black_box(input_day_24))) }); g2015_day_24.finish(); } fn year_2015_day_25(c: &mut Criterion) { + let input_day_25 = include_str!("../inputs/year_2015/day_25_input"); + assert_eq!(day_25::day_25(input_day_25), 19_980_801); + let mut g2015_day_25 = c.benchmark_group("year_2015::day_25"); - let input_year_2015_day_25 = include_str!("../inputs/year_2015/day_25_input"); g2015_day_25.bench_function("year_2015::day_25", |b| { - b.iter(|| day_25::day_25(black_box(input_year_2015_day_25))) + b.iter(|| day_25::day_25(black_box(input_day_25))) }); g2015_day_25.finish(); } diff --git a/benches/year_2015_day_01.rs b/benches/year_2015_day_01.rs index 96eb70f..944adc9 100644 --- a/benches/year_2015_day_01.rs +++ b/benches/year_2015_day_01.rs @@ -75,18 +75,48 @@ fn day_01_v2_fast(input: impl Into) -> i16 { 0 } +fn day_01_v2_flash(input: impl Into) -> i16 { + unsafe { mem::transmute::>(input.into()) } + .iter() + .try_fold((0, 0), |mut acc, pair| { + match (acc.0, pair) { + // Case for ")" or "))" or "()" + (0, 41) | (0, 10537) | (0, 10281) => return Err((acc.1) + 1), + + // Case for "(" + (_, 40) => acc.0 += 1, + // Case for ")" + (_, 41) => acc.0 -= 1, + // Case for "((" + (_, 10280) => acc.0 += 2, + // Case for "))" + (_, 10537) => acc.0 -= 2, + // Case for ")(" or "()" + (_, 10536) | (_, 10281) => (), + _ => (), + } + acc.1 += 2; + Ok(acc) + }) + .and::(Err(0)) + .unwrap_err() +} + fn bench_year_2015_day_01_v1(c: &mut Criterion) { + let input = include_str!("../inputs/year_2015/day_01_input"); + assert_eq!(day_01::day_01_v1(input), 138); + assert_eq!(day_01_v1_naive(input), 138); + assert_eq!(day_01_v1_fast(input), 138); + let mut group = c.benchmark_group("year_2015::day_01_v1"); group.warm_up_time(Duration::from_millis(100)); - let input = include_str!("../inputs/year_2015/day_01_input"); + group.bench_with_input(BenchmarkId::new("Base", input.len()), input, |b, input| { + b.iter(|| day_01::day_01_v1(input)) + }); + group.bench_with_input(BenchmarkId::new("Naive", input.len()), input, |b, input| { b.iter(|| day_01_v1_naive(input)) }); - group.bench_with_input( - BenchmarkId::new("Normal", input.len()), - input, - |b, input| b.iter(|| day_01::day_01_v1(input)), - ); group.bench_with_input(BenchmarkId::new("Fast", input.len()), input, |b, input| { b.iter(|| day_01_v1_fast(input)) }); @@ -94,17 +124,23 @@ fn bench_year_2015_day_01_v1(c: &mut Criterion) { } fn bench_year_2015_day_01_v2(c: &mut Criterion) { + let input = include_str!("../inputs/year_2015/day_01_input"); + assert_eq!(day_01::day_01_v2(input), 1_771); + assert_eq!(day_01_v2_fast(input), 1_771); + assert_eq!(day_01_v2_flash(input), 1_771); + let mut group = c.benchmark_group("year_2015::day_01_v2"); group.warm_up_time(Duration::from_millis(100)); - let input = include_str!("../inputs/year_2015/day_01_input"); - group.bench_with_input( - BenchmarkId::new("Normal", input.len()), - input, - |b, input| b.iter(|| day_01::day_01_v2(input)), - ); + + group.bench_with_input(BenchmarkId::new("Base", input.len()), input, |b, input| { + b.iter(|| day_01::day_01_v2(input)) + }); group.bench_with_input(BenchmarkId::new("Fast", input.len()), input, |b, input| { b.iter(|| day_01_v2_fast(input)) }); + group.bench_with_input(BenchmarkId::new("Flash", input.len()), input, |b, input| { + b.iter(|| day_01_v2_flash(input)) + }); group.finish(); } diff --git a/benches/year_2017_day_01.rs b/benches/year_2017_day_01.rs index f826a9d..d5c0e53 100644 --- a/benches/year_2017_day_01.rs +++ b/benches/year_2017_day_01.rs @@ -44,43 +44,23 @@ fn day_01_v2_zip(input: impl Into) -> u16 { .sum() } -// fn bench_year_2017_day_01_v1(c: &mut Criterion) { -// let mut group = c.benchmark_group("year_2017::day_01_v1"); -// group.warm_up_time(Duration::from_millis(100)); -// let input = include_str!("../inputs/year_2017/day_01_input"); -// group.bench_with_input(BenchmarkId::new("Naive", input.len()), input, |b, input| { -// b.iter(|| day_01_v1_naive(input)) -// }); -// assert_eq!(day_01::day_01_v1(input), 1_069); -// group.bench_with_input( -// BenchmarkId::new("Normal", input.len()), -// input, -// |b, input| b.iter(|| day_01::day_01_v1(input)), -// ); -// group.bench_with_input(BenchmarkId::new("Fast", input.len()), input, |b, input| { -// b.iter(|| day_01_v1_fast(input)) -// }); -// group.finish(); -// } - fn bench_year_2017_day_01_v2(c: &mut Criterion) { - let mut group = c.benchmark_group("year_2017::day_01_v2"); - group.warm_up_time(Duration::from_millis(100)); let input = include_str!("../inputs/year_2017/day_01_input"); assert_eq!(day_01_v2_naive(input), 1_268); assert_eq!(day_01_v2_zip(input), 1_268); assert_eq!(day_01::day_01_v2(input), 1_268); + + let mut group = c.benchmark_group("year_2017::day_01_v2"); + group.warm_up_time(Duration::from_millis(100)); group.bench_with_input(BenchmarkId::new("Naive", input.len()), input, |b, input| { b.iter(|| day_01_v2_naive(input)) }); group.bench_with_input(BenchmarkId::new("Zip", input.len()), input, |b, input| { b.iter(|| day_01_v2_zip(input)) }); - group.bench_with_input( - BenchmarkId::new("Normal", input.len()), - input, - |b, input| b.iter(|| day_01::day_01_v2(input)), - ); + group.bench_with_input(BenchmarkId::new("Base", input.len()), input, |b, input| { + b.iter(|| day_01::day_01_v2(input)) + }); group.finish(); } diff --git a/benches/year_2017_day_02.rs b/benches/year_2017_day_02.rs index 7502a29..b5b086d 100644 --- a/benches/year_2017_day_02.rs +++ b/benches/year_2017_day_02.rs @@ -27,11 +27,9 @@ fn bench_year_2017_day_02_v1(c: &mut Criterion) { group.bench_with_input(BenchmarkId::new("Naive", input.len()), input, |b, input| { b.iter(|| day_02_v1_naive(input)) }); - group.bench_with_input( - BenchmarkId::new("Normal", input.len()), - input, - |b, input| b.iter(|| day_02::day_02_v1(input)), - ); + group.bench_with_input(BenchmarkId::new("Base", input.len()), input, |b, input| { + b.iter(|| day_02::day_02_v1(input)) + }); group.finish(); } diff --git a/benches/year_2017_day_04.rs b/benches/year_2017_day_04.rs index dd90eb3..2f7d55b 100644 --- a/benches/year_2017_day_04.rs +++ b/benches/year_2017_day_04.rs @@ -58,6 +58,10 @@ fn bench_year_2017_day_04_v1(c: &mut Criterion) { assert_eq!(day_04_v1_naive(input), 466); assert_eq!(day_04_v1_sorted(input), 466); assert_eq!(day_04_v1_with_set(input), 466); + + group.bench_with_input(BenchmarkId::new("Base", input.len()), input, |b, input| { + b.iter(|| day_04::day_04_v1(input)) + }); group.bench_with_input(BenchmarkId::new("Naive", input.len()), input, |b, input| { b.iter(|| day_04_v1_naive(input)) }); @@ -71,11 +75,6 @@ fn bench_year_2017_day_04_v1(c: &mut Criterion) { input, |b, input| b.iter(|| day_04_v1_with_set(input)), ); - group.bench_with_input( - BenchmarkId::new("Normal", input.len()), - input, - |b, input| b.iter(|| day_04::day_04_v1(input)), - ); group.finish(); } diff --git a/benches/year_2017_day_13.rs b/benches/year_2017_day_13.rs index 37856ab..19dd264 100644 --- a/benches/year_2017_day_13.rs +++ b/benches/year_2017_day_13.rs @@ -47,11 +47,9 @@ fn bench_year_2017_day_13_v2(c: &mut Criterion) { group.bench_with_input(BenchmarkId::new("Sieve", input.len()), input, |b, input| { b.iter(|| day_13_v2_sieve(input)) }); - group.bench_with_input( - BenchmarkId::new("Normal", input.len()), - input, - |b, input| b.iter(|| day_13::day_13_v2(input)), - ); + group.bench_with_input(BenchmarkId::new("Base", input.len()), input, |b, input| { + b.iter(|| day_13::day_13_v2(input)) + }); group.finish(); } diff --git a/src/year_2015/day_01.rs b/src/year_2015/day_01.rs index a45e2cf..4313409 100644 --- a/src/year_2015/day_01.rs +++ b/src/year_2015/day_01.rs @@ -38,6 +38,9 @@ //! > //! > Your puzzle answer was ~~`REDACTED`~~. //! +//! # Implementation tricks +//! +//! /// Solve exercise for year 2015, day 1 (part 1). /// @@ -87,17 +90,17 @@ /// assert_eq!(day_01::day_01_v1(")))"), -3); /// assert_eq!(day_01::day_01_v1(")())())"), -3); /// ``` -pub fn day_01_v1(input: impl Into) -> i16 { - let mut lvl: i16 = 0; - for chr in input.into().bytes() { - match chr { - b'(' => lvl += 1, - b')' => lvl -= 1, - _ => panic!("Invalid character: {}", chr), - } - } - lvl +pub fn day_01_v1(input: impl Into) -> i16 { + input + .into() + .bytes() + .map(|chr| match chr { + b'(' => 1, + b')' => -1, + _ => 0, + }) + .sum() } /// Solve exercise for year 2015, day 1 (part 2). @@ -122,8 +125,8 @@ pub fn day_01_v1(input: impl Into) -> i16 { /// - If `level` reaches `-1`, return current `index` multipled by `2` (compound /// size) and add `1` (because `index` started at `0`). /// -/// Advantage: Impossible to use the "Naive" implementation, and "Normal" is not -/// a huge time loss either. +/// Advantage: Impossible to use the "Naive" implementation, and "Base" is not a +/// huge time loss either. /// /// # Samples /// ``` @@ -133,20 +136,23 @@ pub fn day_01_v1(input: impl Into) -> i16 { /// assert_eq!(day_01::day_01_v2(")"), 1); /// assert_eq!(day_01::day_01_v2("()())"), 5); /// ``` -pub fn day_01_v2(input: impl Into) -> i16 { - let mut lvl: i16 = 0; - for (idx, chr) in input.into().bytes().enumerate() { - match chr { - b'(' => lvl += 1, - b')' => lvl -= 1, - _ => panic!("Invalid character: {}", chr), - } - if lvl < 0 { - return idx as i16 + 1; - } - } - 0 +pub fn day_01_v2(input: impl Into) -> i16 { + input + .into() + .bytes() + .try_fold((0, 0), |mut acc, chr| { + acc.1 += 1; + match (acc.0, chr) { + (0, b')') => return Err(acc.1), + (_, b'(') => acc.0 += 1, + (_, b')') => acc.0 -= 1, + _ => (), + } + Ok(acc) + }) + .and::(Err(0)) + .unwrap_err() } solvable!(day_01, day_01_v1, day_01_v2, i16); @@ -175,11 +181,13 @@ mod tests { #[test] fn works_with_samples_v2() { - let sample_two: [(&str, i16); 2] = [ + let sample_two: [(&str, i16); 3] = [ + ("(())", 0), (")", 1), ("()())", 5), ]; for (sample, result) in sample_two.iter() { + println!("Test: {}", sample); assert_eq!(day_01_v2(*sample), *result); } } diff --git a/src/year_2015/day_04.rs b/src/year_2015/day_04.rs index f3dfec6..d6f5460 100644 --- a/src/year_2015/day_04.rs +++ b/src/year_2015/day_04.rs @@ -18,36 +18,54 @@ //! > //! > Your puzzle answer was ~~`REDACTED`~~. //! +//! # Implementation tricks +//! +//! Since the [md-5 crate](https://crates.io/crates/md-5) used returns hashes as +//! an array of hex(`u4`) values joined by two into a single `u8`, we can either +//! turn the hash into a string and check for leading `0` characters, which will +//! be costly, or we can limit ourselves to checking the first three `u8``. +//! +//! To match the first '00' hexadecimal pair, we can match it to `0u8`. Same will +//! go for the second pair. +//! +//! For the third one, we're in a bit of a pickle: we must match either one part +//! of the number, or all of it. The most obvious approach is using bitmasks, or +//! we can simply compare the value of the hash. Since the only values producing +//! a hash starting with (at least one) zero are all inferior to `0x10` (`16` in +//! an u8 format), we can match with any number inferior to `16`. +//! +//! # Samples +//! ``` +//! /// Import the module +//! use advent_rs::year_2015::day_04; +//! +//! assert_eq!(day_04::day_04_v1("abcdef"), 609_043); +//! assert_eq!(day_04::day_04_v1("pqrstuv"), 1_048_970); +//! assert_eq!(day_04::day_04_v2("abcdef"), 6_742_839); +//! ``` -use md5::{Digest, Md5}; - -#[mutants::skip] // Don't even try this hahaha -fn loop_until_hash(input: &str, stop_value: u8) -> u32 { - let mut starter: u32 = 0; - let mut hasher = Md5::new(); - hasher.update(input); - loop { - let mut hasher_num = hasher.clone(); - hasher_num.update(starter.to_string()); - let hash = hasher_num.finalize(); - if hash[..2] == [0, 0] && hash[2] <= stop_value { - return starter; - } +use md5::Digest; +use md5::Md5; - starter += 1; - } +fn find_hash(input: &str, stop_value: u8) -> u32 { + let mut md5 = Md5::new(); + md5.update(input); + (0..=u32::MAX) + .find(|counter| { + let mut hasher = md5.clone(); + hasher.update(&counter.to_string()); + let hash = hasher.finalize(); + hash[0] == 0 && hash[1] == 0 && hash[2] < stop_value + }) + .unwrap() } pub fn day_04_v1(input: impl Into) -> u32 { - let input_str = input.into(); - let clean_str = input_str.trim_end(); - loop_until_hash(clean_str, 15) + find_hash(input.into().trim_end(), 16) } pub fn day_04_v2(input: impl Into) -> u32 { - let input_str = input.into(); - let clean_str = input_str.trim_end(); - loop_until_hash(clean_str, 0) + find_hash(input.into().trim_end(), 1) } solvable!(day_04, day_04_v1, day_04_v2, u32); @@ -60,8 +78,8 @@ mod tests { #[ignore = "Too slow for CI"] fn works_with_samples_v1() { let sample_one: [(&str, u32); 2] = [ - ("abcdef", 609043), - ("pqrstuv", 1048970), + ("abcdef", 609_043), + ("pqrstuv", 1_048_970), ]; for (sample, result) in sample_one.iter() { assert_eq!(day_04_v1(*sample), *result); @@ -71,6 +89,6 @@ mod tests { #[test] #[ignore = "Too slow for CI"] fn works_with_samples_v2() { - assert_eq!(day_04_v2("abcdef"), 6742839); + assert_eq!(day_04_v2("abcdef"), 6_742_839); } } diff --git a/src/year_2016/day_09.rs b/src/year_2016/day_09.rs index 26a6f89..727022f 100644 --- a/src/year_2016/day_09.rs +++ b/src/year_2016/day_09.rs @@ -1,24 +1,24 @@ -fn decompressed_size(mut input: &str, deep_decompress: bool) -> usize { - let mut result: usize = 0; +fn decompressed_size(mut input: &str, deep_decompress: bool) -> u64 { + let mut result: u64 = 0; while !input.is_empty() { if let Some(next_paren_l) = input.find('(') { let next_paren_r = input.find(')').unwrap(); let nums: Vec<_> = input[next_paren_l + 1..next_paren_r].split('x').collect(); let (duration, repeat) = ( - nums[0].parse::().unwrap(), - nums[1].parse::().unwrap(), + nums[0].parse::().unwrap(), + nums[1].parse::().unwrap(), ); - result += next_paren_l; + result += next_paren_l as u64; input = &input[next_paren_r + 1..]; if deep_decompress { - let dup_elt = &input[..duration]; + let dup_elt = &input[..duration as usize]; result += decompressed_size(dup_elt, true) * repeat; } else { result += duration * repeat; } - input = &input[duration..]; + input = &input[duration as usize..]; } else { - result += input.len(); + result += input.len() as u64; input = ""; } } @@ -26,15 +26,15 @@ fn decompressed_size(mut input: &str, deep_decompress: bool) -> usize { result } -pub fn day_09_v1(input: impl Into) -> usize { +pub fn day_09_v1(input: impl Into) -> u64 { decompressed_size(&input.into(), false) } -pub fn day_09_v2(input: impl Into) -> usize { +pub fn day_09_v2(input: impl Into) -> u64 { decompressed_size(&input.into(), true) } -solvable!(day_09, day_09_v1, day_09_v2, usize); +solvable!(day_09, day_09_v1, day_09_v2, u64); #[cfg(test)] mod tests { @@ -42,7 +42,7 @@ mod tests { #[test] fn works_with_samples_v1() { - let sample_one: [(&str, usize); 6] = [ + let sample_one: [(&str, u64); 6] = [ ("ADVENT", 6), ("A(1x5)BC", 7), ("(3x3)XYZ", 9), @@ -57,7 +57,7 @@ mod tests { #[test] fn works_with_samples_v2() { - let sample_two: [(&str, usize); 4] = [ + let sample_two: [(&str, u64); 4] = [ ("(3x3)XYZ", 9), ("X(8x2)(3x3)ABCY", 20), ("(27x12)(20x12)(13x14)(7x10)(1x12)A", 241_920),