summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Wernick <justin@worthe-it.co.za>2021-12-18 21:05:52 +0200
committerJustin Wernick <justin@worthe-it.co.za>2021-12-18 21:05:52 +0200
commit14d2607863d653b6b367e76955bbdde085340738 (patch)
tree83f566481bb3193260785f9ebd15371a9191e54c
parent1d780f776c1fd43604dac79691b6753fb69f2359 (diff)
Day 17
-rw-r--r--inputs/day_17.txt1
-rw-r--r--src/bin/day_17.rs82
2 files changed, 83 insertions, 0 deletions
diff --git a/inputs/day_17.txt b/inputs/day_17.txt
new file mode 100644
index 0000000..039df20
--- /dev/null
+++ b/inputs/day_17.txt
@@ -0,0 +1 @@
+target area: x=206..250, y=-105..-57
diff --git a/src/bin/day_17.rs b/src/bin/day_17.rs
new file mode 100644
index 0000000..0d60240
--- /dev/null
+++ b/src/bin/day_17.rs
@@ -0,0 +1,82 @@
+use nom::{
+ bytes::complete::tag, character::complete::i32 as nom_i32, combinator::map, sequence::tuple,
+ IResult,
+};
+use std::fs;
+
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+ let input = fs::read_to_string("inputs/day_17.txt")?;
+ let target = parse_target(&input).unwrap().1;
+
+ let max_y_throw = 0 - target.min_y - 1;
+ let max_height = max_y_throw * (max_y_throw + 1) / 2;
+ dbg!(max_height);
+
+ let min_y_throw = target.min_y;
+ let max_x_throw = target.max_x;
+ let min_x_throw = (2.0 * target.min_x as f32).sqrt() as i32;
+
+ let mut count = 0;
+ for x in min_x_throw..=max_x_throw {
+ for y in min_y_throw..=max_y_throw {
+ if simulate_throw(x, y, &target) {
+ count += 1;
+ }
+ }
+ }
+ dbg!(count);
+
+ Ok(())
+}
+
+fn simulate_throw(mut x_vel: i32, mut y_vel: i32, target: &TargetArea) -> bool {
+ let mut x_pos = 0;
+ let mut y_pos = 0;
+ loop {
+ x_pos += x_vel;
+ y_pos += y_vel;
+ if x_vel > 0 {
+ x_vel -= 1;
+ }
+ y_vel -= 1;
+ if x_pos >= target.min_x
+ && x_pos <= target.max_x
+ && y_pos >= target.min_y
+ && y_pos <= target.max_y
+ {
+ return true;
+ }
+ if x_pos > target.max_x || y_pos < target.min_y {
+ return false;
+ }
+ }
+}
+
+#[derive(Debug)]
+struct TargetArea {
+ min_x: i32,
+ max_x: i32,
+ min_y: i32,
+ max_y: i32,
+}
+
+fn parse_target(input: &str) -> IResult<&str, TargetArea> {
+ map(
+ tuple((
+ tag("target area: x="),
+ nom_i32,
+ tag(".."),
+ nom_i32,
+ tag(", y="),
+ nom_i32,
+ tag(".."),
+ nom_i32,
+ )),
+ |(_, min_x, _, max_x, _, min_y, _, max_y)| TargetArea {
+ min_x,
+ max_x,
+ min_y,
+ max_y,
+ },
+ )(input)
+}