[TASK] Solved day 9 + added benchmarking options to the main method

This commit is contained in:
2020-12-09 09:54:26 +01:00
parent f5850ceb2b
commit e053e4ed61
5 changed files with 1157 additions and 26 deletions

1000
input/day9.txt Normal file

File diff suppressed because it is too large Load Diff

20
input/day9_example.txt Normal file
View File

@@ -0,0 +1,20 @@
35
20
15
25
47
40
62
55
65
95
102
117
150
182
127
219
299
277
309
576

View File

@@ -1,10 +1,10 @@
use super::util;
use regex::{Regex, Captures};
use std::collections::{HashMap, HashSet, VecDeque};
use std::time::Instant;
// use std::time::Instant;
pub fn solve() {
let now = Instant::now();
// let now = Instant::now();
let lines = util::read_file("input/day7.txt");
let rules = lines.iter()
.map(|s| Rule::parse(s))
@@ -26,7 +26,7 @@ pub fn solve() {
let part2 = count_bags("shiny gold", &rules);
println!("Day 7 Part 2: {}", part2 - 1);
println!("Algo's took {} μs", now.elapsed().as_micros());
// println!("Algo's took {} μs", now.elapsed().as_micros());
}

82
src/day9.rs Normal file
View File

@@ -0,0 +1,82 @@
use super::util;
use std::collections::BTreeSet;
pub fn solve() {
let lines = util::read_file("input/day9.txt");
let nums = lines.iter().map(|s| s.parse::<u64>().unwrap()).collect::<Vec<_>>();
let part1 = solve_part1(&nums, 25);
println!("Day 9 Part 1: {}", part1);
let part2 = solve_part2(&nums, part1);
println!("Day 9 Part 2: {}", part2.iter().min().unwrap() + part2.iter().max().unwrap())
}
fn solve_part1(nums: &Vec<u64>, preamble: usize) -> u64 {
let mut set = BTreeSet::new();
for i in 0..preamble {
set.insert(nums[i]);
}
for i in preamble..nums.len() {
let n = nums[i];
if !is_sum(n, &set) {
return n;
}
set.remove(&nums[i - preamble]);
set.insert(n);
}
panic!("No number that is not a sum found in the entire list!");
}
fn solve_part2(nums: &Vec<u64>, target: u64) -> &[u64]{
// find a contiguous set of at least two numbers in your list which sum to the target
let mut b: usize = 0;
let mut e: usize = 1;
let mut sum = nums[b] + nums[e];
loop {
if sum < target {
e += 1;
sum += nums[e]
} else if sum > target {
sum -= nums[b];
b += 1;
} else {
// We found the solution!
return &nums[b..(e+1)];
}
}
}
fn is_sum(n: u64, set: &BTreeSet<u64>) -> bool {
let mut forward = set.iter();
let mut backward = set.iter().rev();
let mut x = forward.next().unwrap_or(&u64::max_value());
let mut y = backward.next().unwrap_or(&0);
loop {
if x >= y {
return false;
}
let sum = x + y;
if sum < n {
x = forward.next().unwrap_or(&u64::max_value());
} else if sum > n {
y = backward.next().unwrap_or(&0);
} else {
// Sum found!
return true;
}
}
}

View File

@@ -10,37 +10,66 @@ mod day5;
mod day6;
mod day7;
mod day8;
mod day9;
const MAX_DAY: u8 = 9;
const BENCHMARK_AMOUNT: u32 = 100;
fn solve(day: u8) {
match day {
1 => day1::solve(),
2 => day2::solve(),
3 => day3::solve(),
4 => day4::solve(),
5 => day5::solve(),
6 => day6::solve(),
7 => day7::solve(),
8 => day8::solve(),
9 => day9::solve(),
_ => println!("This day is not yet implemented")
}
}
fn main() {
let now = Instant::now();
let args: Vec<String> = std::env::args().collect();
let day_arg_idx = args.iter().position(|a| a == "-d");
if day_arg_idx.is_some() {
match args[day_arg_idx.unwrap() + 1].parse::<u8>().unwrap() {
1 => day1::solve(),
2 => day2::solve(),
3 => day3::solve(),
4 => day4::solve(),
5 => day5::solve(),
6 => day6::solve(),
7 => day7::solve(),
8 => day8::solve(),
_ => println!("This day is not yet implemented")
let single_day = day_arg_idx.is_some();
let day = if single_day { args[day_arg_idx.unwrap() + 1].parse::<u8>().unwrap() } else { 0 };
let benchmark = args.contains(&String::from("--bench")) || args.contains(&String::from("-b"));
let mut bench_results: Vec<u128> = Vec::new();
// This is essentially the warmup for the benchmark:
run_once(single_day, day, &mut bench_results);
if benchmark {
for _ in 0..BENCHMARK_AMOUNT {
run_once(single_day, day, &mut bench_results);
}
} else {
// Solve all days:
day1::solve();
day2::solve();
day3::solve();
day4::solve();
day5::solve();
day6::solve();
day7::solve();
day8::solve();
}
println!("Execution took {} μs", now.elapsed().as_micros());
let avg_runtime: u128 = bench_results.iter().sum::<u128>() / (bench_results.len() as u128);
println!("Execution took {} μs {}", avg_runtime, if benchmark { "on average" } else { "" });
}
fn run_once(single_day: bool, day: u8, bench_results: &mut Vec<u128>) {
let now = Instant::now();
if single_day {
solve(day);
} else {
solve_all();
}
bench_results.push(now.elapsed().as_micros());
}
fn solve_all() {
for day in 1..(MAX_DAY + 1) {
solve(day);
}
}