[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 super::util;
|
||||||
use regex::{Regex, Captures};
|
use regex::{Regex, Captures};
|
||||||
use std::collections::{HashMap, HashSet, VecDeque};
|
use std::collections::{HashMap, HashSet, VecDeque};
|
||||||
use std::time::Instant;
|
// use std::time::Instant;
|
||||||
|
|
||||||
pub fn solve() {
|
pub fn solve() {
|
||||||
let now = Instant::now();
|
// let now = Instant::now();
|
||||||
let lines = util::read_file("input/day7.txt");
|
let lines = util::read_file("input/day7.txt");
|
||||||
let rules = lines.iter()
|
let rules = lines.iter()
|
||||||
.map(|s| Rule::parse(s))
|
.map(|s| Rule::parse(s))
|
||||||
@@ -26,7 +26,7 @@ pub fn solve() {
|
|||||||
|
|
||||||
let part2 = count_bags("shiny gold", &rules);
|
let part2 = count_bags("shiny gold", &rules);
|
||||||
println!("Day 7 Part 2: {}", part2 - 1);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
67
src/main.rs
67
src/main.rs
@@ -10,16 +10,13 @@ mod day5;
|
|||||||
mod day6;
|
mod day6;
|
||||||
mod day7;
|
mod day7;
|
||||||
mod day8;
|
mod day8;
|
||||||
|
mod day9;
|
||||||
|
|
||||||
fn main() {
|
const MAX_DAY: u8 = 9;
|
||||||
|
const BENCHMARK_AMOUNT: u32 = 100;
|
||||||
|
|
||||||
let now = Instant::now();
|
fn solve(day: u8) {
|
||||||
|
match day {
|
||||||
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(),
|
1 => day1::solve(),
|
||||||
2 => day2::solve(),
|
2 => day2::solve(),
|
||||||
3 => day3::solve(),
|
3 => day3::solve(),
|
||||||
@@ -28,19 +25,51 @@ fn main() {
|
|||||||
6 => day6::solve(),
|
6 => day6::solve(),
|
||||||
7 => day7::solve(),
|
7 => day7::solve(),
|
||||||
8 => day8::solve(),
|
8 => day8::solve(),
|
||||||
|
9 => day9::solve(),
|
||||||
_ => println!("This day is not yet implemented")
|
_ => println!("This day is not yet implemented")
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
// Solve all days:
|
|
||||||
day1::solve();
|
fn main() {
|
||||||
day2::solve();
|
|
||||||
day3::solve();
|
|
||||||
day4::solve();
|
let args: Vec<String> = std::env::args().collect();
|
||||||
day5::solve();
|
|
||||||
day6::solve();
|
let day_arg_idx = args.iter().position(|a| a == "-d");
|
||||||
day7::solve();
|
let single_day = day_arg_idx.is_some();
|
||||||
day8::solve();
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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