Alexey Dorokhov 2 år sedan
förälder
incheckning
b8adbc8043
8 ändrade filer med 215 tillägg och 0 borttagningar
  1. 1 0
      day_6a/.gitignore
  2. 32 0
      day_6a/Cargo.lock
  3. 9 0
      day_6a/Cargo.toml
  4. 65 0
      day_6a/src/main.rs
  5. 1 0
      day_6b/.gitignore
  6. 32 0
      day_6b/Cargo.lock
  7. 9 0
      day_6b/Cargo.toml
  8. 66 0
      day_6b/src/main.rs

+ 1 - 0
day_6a/.gitignore

@@ -0,0 +1 @@
+target

+ 32 - 0
day_6a/Cargo.lock

@@ -0,0 +1,32 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "day_6a"
+version = "0.1.0"
+dependencies = [
+ "nom",
+]
+
+[[package]]
+name = "memchr"
+version = "2.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
+
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
+[[package]]
+name = "nom"
+version = "7.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]

+ 9 - 0
day_6a/Cargo.toml

@@ -0,0 +1,9 @@
+[package]
+name = "day_6a"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+nom = "7"

+ 65 - 0
day_6a/src/main.rs

@@ -0,0 +1,65 @@
+use std::fs;
+use std::env;
+
+use nom::IResult;
+use nom::multi::separated_list1;
+use nom::bytes::complete::tag;
+use nom::character::complete::i64;
+use nom::character::complete::space1;
+use nom::character::complete::line_ending;
+use nom::sequence::tuple;
+use nom::sequence::preceded;
+use nom::sequence::terminated;
+
+fn parse_input_data(input: &str) -> IResult<&str, (Vec<i64>, Vec<i64>)> {
+    tuple((terminated(preceded(tuple((tag("Time:"), space1)),
+                               separated_list1(space1,i64)),
+                      line_ending),
+           terminated(preceded(tuple((tag("Distance:"), space1)),
+                               separated_list1(space1,i64)),
+                      line_ending)
+    ))(input)
+}
+
+fn parse_leaderboard(input_data: &str) -> Result<(Vec<i64>,Vec<i64>), String> {
+    match parse_input_data(input_data) {
+        Ok((rest, data)) => if rest == "" {
+            Ok(data)
+        } else {
+            Err(format!("Incomplete parse, remaining: {}", rest))
+        },
+        Err(error) => Err(error.to_string()),
+    }
+}
+
+fn solve_eq(t: f64, d: f64) -> Option<(f64,f64)> {
+    let discr = t*t - 4.0*d;
+    if discr >= 0.0 {
+        return Some(((t - discr.sqrt())/2.0, (t + discr.sqrt())/2.0));
+    }
+    None
+}
+
+fn integer_bounds(t: i64, d: i64) -> (i64, i64) {
+    match solve_eq(t as f64, d as f64) {
+        Some((x1,x2)) => ((x1+0.0000001).ceil() as i64, (x2-0.0000001).floor() as i64),
+        None => (0,0)
+    }
+}
+
+
+fn main() {
+    let args: Vec<String> = env::args().collect();
+    let file_path = &args[1];
+    let input_data = fs::read_to_string(file_path).unwrap_or_else(
+        |_|{panic!("Can't read file {}", file_path)});
+    let (times,distances) = parse_leaderboard(&input_data).unwrap_or_else(
+        |e|{panic!("Failed to parse almanac: {}", e)});
+
+    let mut result: i64 = 1;
+    for i in 0..times.len() {
+        let (min, max) = integer_bounds(times[i], distances[i]);
+        result *= max - min + 1;
+    }
+    println!("{result}");
+}

+ 1 - 0
day_6b/.gitignore

@@ -0,0 +1 @@
+target

+ 32 - 0
day_6b/Cargo.lock

@@ -0,0 +1,32 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "day_6b"
+version = "0.1.0"
+dependencies = [
+ "nom",
+]
+
+[[package]]
+name = "memchr"
+version = "2.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
+
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
+[[package]]
+name = "nom"
+version = "7.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]

+ 9 - 0
day_6b/Cargo.toml

@@ -0,0 +1,9 @@
+[package]
+name = "day_6b"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+nom = "7"

+ 66 - 0
day_6b/src/main.rs

@@ -0,0 +1,66 @@
+use std::fs;
+use std::env;
+
+use nom::IResult;
+use nom::multi::separated_list1;
+use nom::bytes::complete::tag;
+use nom::character::complete::i64;
+use nom::character::complete::space1;
+use nom::character::complete::line_ending;
+use nom::sequence::tuple;
+use nom::sequence::preceded;
+use nom::sequence::terminated;
+
+fn parse_input_data(input: &str) -> IResult<&str, (Vec<i64>, Vec<i64>)> {
+    tuple((terminated(preceded(tuple((tag("Time:"), space1)),
+                               separated_list1(space1,i64)),
+                      line_ending),
+           terminated(preceded(tuple((tag("Distance:"), space1)),
+                               separated_list1(space1,i64)),
+                      line_ending)
+    ))(input)
+}
+
+fn parse_leaderboard(input_data: &str) -> Result<(Vec<i64>,Vec<i64>), String> {
+    match parse_input_data(input_data) {
+        Ok((rest, data)) => if rest == "" {
+            Ok(data)
+        } else {
+            Err(format!("Incomplete parse, remaining: {}", rest))
+        },
+        Err(error) => Err(error.to_string()),
+    }
+}
+
+fn solve_eq(t: f64, d: f64) -> Option<(f64,f64)> {
+    let discr = t*t - 4.0*d;
+    if discr >= 0.0 {
+        return Some(((t - discr.sqrt())/2.0, (t + discr.sqrt())/2.0));
+    }
+    None
+}
+
+fn integer_bounds(t: i64, d: i64) -> (i64, i64) {
+    match solve_eq(t as f64, d as f64) {
+        Some((x1,x2)) => ((x1+0.0000001).ceil() as i64, (x2-0.0000001).floor() as i64),
+        None => (0,0)
+    }
+}
+
+
+fn main() {
+    let args: Vec<String> = env::args().collect();
+    let file_path = &args[1];
+    let input_data = fs::read_to_string(file_path).unwrap_or_else(
+        |_|{panic!("Can't read file {}", file_path)});
+    let (times,distances) = parse_leaderboard(&input_data).unwrap_or_else(
+        |e|{panic!("Failed to parse almanac: {}", e)});
+
+    let times_strings:Vec<String> = times.into_iter().map(|x|{x.to_string()}).collect();
+    let distances_strings:Vec<String> = distances.into_iter().map(|x|{x.to_string()}).collect();
+
+    let time = times_strings.join("").parse::<i64>().unwrap();
+    let distance = distances_strings.join("").parse::<i64>().unwrap();
+    let (min, max) = integer_bounds(time, distance);
+    println!("{}", max - min + 1);
+}