From c15d9534bd29c894a7d89418dd18d6a1c932b38d Mon Sep 17 00:00:00 2001
From: Ty <ty@blahaj.land>
Date: Wed, 6 Dec 2023 06:59:37 -0700
Subject: [PATCH] Quadratics are fun

---
 src/day6/mod.rs | 37 +++++++++++++++++++++++--------------
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/src/day6/mod.rs b/src/day6/mod.rs
index ff2357a..b4167cd 100644
--- a/src/day6/mod.rs
+++ b/src/day6/mod.rs
@@ -8,7 +8,7 @@ pub struct Day6 {
 impl Day for Day6 {
     fn part1(&mut self) -> String {
         let lines = self.input.lines().map(|l| l.split_ascii_whitespace().skip(1).collect::<Vec<_>>()).collect::<Vec<_>>();
-        let races = [
+        let races: [(f64, f64); 4] = [
             (lines[0][0].parse().unwrap(), lines[1][0].parse().unwrap()),
             (lines[0][1].parse().unwrap(), lines[1][1].parse().unwrap()),
             (lines[0][2].parse().unwrap(), lines[1][2].parse().unwrap()),
@@ -18,13 +18,16 @@ impl Day for Day6 {
         let mut acc = 1usize;
 
         for (time, record_distance) in races {
-            let mut wins = 0usize;
-            for time_holding_button in 0..time {
-                let distance = (time - time_holding_button) * time_holding_button /* velocity */;
-                if distance > record_distance { wins += 1; }
-            }
+            // let mut wins = 0usize;
+            // for time_holding_button in 0..time {
+            //     let distance = (time - time_holding_button) * time_holding_button /* velocity */;
+            //     if distance > record_distance { wins += 1; }
+            // }
+            // Mathy solution:
+            let b = ((time+((time*time-4.0*record_distance).sqrt())) / 2.0).ceil();
+            let a = ((time-((time*time-4.0*record_distance).sqrt())) / 2.0).ceil();
 
-            acc *= wins;
+            acc *= (b - a) as usize;
         }
 
         acc.to_string()
@@ -33,13 +36,19 @@ impl Day for Day6 {
     fn part2(&mut self) -> String {
         let lines = self.input.lines().map(|l| l[10..].split_ascii_whitespace().collect::<String>()).collect::<Vec<_>>();
 
-        let (time, record_distance): (u128, u128) = (lines[0].parse().unwrap(), lines[1].parse().unwrap());
-        let mut wins = 0u128;
-        for time_holding_button in 0..time {
-            let distance = (time - time_holding_button) * time_holding_button /* velocity */;
-            if distance > record_distance { wins += 1; }
-        }
+        let (time, record_distance): (f64, f64) = (lines[0].parse().unwrap(), lines[1].parse().unwrap());
+        // Boring solution:
+        // let mut wins = 0u128;
+        // for time_holding_button in 0..time {
+        //     let distance = (time - time_holding_button) * time_holding_button /* velocity */;
+        //     if distance > record_distance { wins += 1; }
+        // }
 
-        wins.to_string()
+        // wins.to_string()
+        // Mathy solution:
+        let b = ((time+((time*time-4.0*record_distance).sqrt())) / 2.0).ceil();
+        let a = ((time-((time*time-4.0*record_distance).sqrt())) / 2.0).ceil();
+
+        (b - a).to_string()
     }
 }