Compare commits

...

3 Commits

Author SHA1 Message Date
fcc6bb39d0 [CLEANUP] Unused code 2023-12-06 19:16:15 +01:00
95da8147ec [TWEAK] Day 6 is now solved with math, making it a lot faster 2023-12-06 19:15:30 +01:00
e2b87340e2 [TASK] Solved day 6 2023-12-06 19:13:32 +01:00
5 changed files with 84 additions and 5 deletions

View File

@@ -11,7 +11,3 @@ num = "0.4"
# For flamegraph, enable this:
[profile.release]
debug = true
[target.x86_64-unknown-linux-gnu]
linker = "/usr/bin/clang"
rustflags = ["-Clink-arg=-fuse-ld=lld", "-Clink-arg=-Wl,--no-rosegment"]

2
input/day06.txt Normal file
View File

@@ -0,0 +1,2 @@
Time: 55 99 97 93
Distance: 401 1485 2274 1405

2
input/day06_example.txt Normal file
View File

@@ -0,0 +1,2 @@
Time: 7 15 30
Distance: 9 40 200

76
src/day6.rs Normal file
View File

@@ -0,0 +1,76 @@
use num::ToPrimitive;
use crate::day_solver::DaySolver;
#[cfg(test)]
use crate::util::read_file;
pub struct Day6 {
times: Vec<u64>,
distances: Vec<u64>
}
impl Day6 {
pub fn create(input: String) -> Self {
let mut lines = input.lines();
let (_, times_str) = lines.next().unwrap().split_once(": ").unwrap();
let (_, dist_str) = lines.next().unwrap().split_once(": ").unwrap();
// Put the input into the day struct
return Day6 {
times: times_str.trim().split_whitespace().map(|n| n.parse().unwrap()).collect(),
distances: dist_str.trim().split_whitespace().map(|n| n.parse().unwrap()).collect(),
}
}
fn calc_ways_to_beat(time: u64, dist: u64) -> u64 {
// y = (t - x) * x = tx - x^2
// We need to solve for tx - x^2 = d
// Solve for x:
// x = (t - sqrt(t^2 -4d)) / 2
// x = (sqrt(t^2 -4d) + t) / 2
// Difference between those two solutions is the answer
let time_f = time.to_f64().unwrap();
let dist_f = dist.to_f64().unwrap();
let min_win = (time_f - f64::sqrt(time_f * time_f - 4f64 * dist_f)) / 2f64;
let max_win = (f64::sqrt(time_f * time_f - 4f64 * dist_f) + time_f) / 2f64;
return f64::floor(max_win).to_u64().unwrap() - f64::ceil(min_win).to_u64().unwrap() + 1;
}
}
impl DaySolver for Day6 {
fn solve_part1(&mut self) -> String {
assert_eq!(self.times.len(), self.distances.len());
let mut record_beats = Vec::with_capacity(self.times.len());
for i in 0..self.times.len() {
let time = self.times.get(i).unwrap().to_owned();
let dist = self.distances.get(i).unwrap().to_owned();
record_beats.push(Day6::calc_ways_to_beat(time, dist));
}
return record_beats.iter().product::<u64>().to_string()
}
fn solve_part2(&mut self) -> String {
let time = self.times.iter().map(|t| t.to_string()).fold(String::new(), |a, b| a + &b).parse::<u64>().unwrap();
let distance = self.distances.iter().map(|t| t.to_string()).fold(String::new(), |a, b| a + &b).parse::<u64>().unwrap();
return Day6::calc_ways_to_beat(time, distance).to_string()
}
}
#[test]
fn test_part1() {
let mut day = Day6::create(read_file("input/day06_example.txt"));
assert_eq!("288", day.solve_part1());
}
#[test]
fn test_part2() {
let mut day = Day6::create(read_file("input/day06_example.txt"));
assert_eq!("71503", day.solve_part2());
}

View File

@@ -6,6 +6,7 @@ use crate::day2::Day2;
use crate::day3::Day3;
use crate::day4::Day4;
use crate::day5::Day5;
use crate::day6::Day6;
use crate::day_solver::DaySolver;
use crate::util::read_file;
@@ -15,9 +16,10 @@ mod day2;
mod day3;
mod day4;
mod day5;
mod day6;
mod day_solver;
const MAX_DAY: u8 = 5;
const MAX_DAY: u8 = 6;
const DEFAULT_BENCHMARK_AMOUNT: u32 = 100;
fn main() {
@@ -93,6 +95,7 @@ fn build_day_solver(day: u8, input: String) -> Option<Box<dyn DaySolver>> {
3 => Some(Box::new(Day3::create(input))),
4 => Some(Box::new(Day4::create(input))),
5 => Some(Box::new(Day5::create(input))),
6 => Some(Box::new(Day6::create(input))),
_ => None
}
}