[TASK] Solved day 9 + added benchmarking options to the main method
This commit is contained in:
1000
input/day9.txt
Normal file
1000
input/day9.txt
Normal file
File diff suppressed because it is too large
Load Diff
20
input/day9_example.txt
Normal file
20
input/day9_example.txt
Normal 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
|
||||
@@ -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
82
src/day9.rs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
75
src/main.rs
75
src/main.rs
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user