diff --git a/.aoc-cache/6.txt b/.aoc-cache/6.txt
new file mode 100644
index 0000000..f0187ef
--- /dev/null
+++ b/.aoc-cache/6.txt
@@ -0,0 +1,2 @@
+Time: 58 99 64 69
+Distance: 478 2232 1019 1071
diff --git a/src/bin/day_6.rs b/src/bin/day_6.rs
new file mode 100644
index 0000000..36ae259
--- /dev/null
+++ b/src/bin/day_6.rs
@@ -0,0 +1,48 @@
+use aoc_2022::prelude::*;
+use color_eyre::eyre::ContextCompat;
+use std::fmt::Write;
+
+type Input = Vec<(isize, isize)>;
+
+fn parse(s: &str) -> Result {
+ let (time, distance) = s.split_once("\n")
+ .wrap_err("invalid format")?;
+ Ok(ints(time).into_iter().zip(ints(distance)).collect::>())
+}
+
+fn race_calc((total_time, target_distance): (isize, isize)) -> usize {
+ let a = 1.0;
+ let b = -total_time as f64;
+ let c = target_distance as f64;
+ let v1 = (-b + (b*b - 4.0*a*c).sqrt()) / 2.0*a;
+ let v2 = (-b - (b*b - 4.0*a*c).sqrt()) / 2.0*a;
+ let min = v1.min(v2) + 0.00001;
+ let max = v1.max(v2) - 0.00001;
+ let min = min.ceil() as i64;
+ let max = max.floor() as i64;
+ (min..=max).count()
+}
+
+#[aoc(day = 6, parse = parse, test_cases = ["day_6.txt"])]
+fn day_6(mut input: Input) -> Result<()> {
+ // Part 1
+ println!("Part one: ");
+ let result: usize = input.iter().copied().map(race_calc).product();
+ println!("{result}");
+
+ // Part 2
+ println!("Part two: ");
+ let mut total_time = String::new();
+ let mut target_distance = String::new();
+ for (t, d) in &input {
+ write!(total_time, "{t}")?;
+ write!(target_distance, "{d}")?;
+ }
+ let total_time = total_time.parse()?;
+ let target_distance = target_distance.parse()?;
+ println!("{total_time} {target_distance}");
+ let result = race_calc((total_time, target_distance));
+ println!("{result}");
+
+ Ok(())
+}
diff --git a/test_cases/day_6.txt b/test_cases/day_6.txt
new file mode 100644
index 0000000..b39f49d
--- /dev/null
+++ b/test_cases/day_6.txt
@@ -0,0 +1,2 @@
+Time: 7 15 30
+Distance: 9 40 200
\ No newline at end of file