aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Cargo.toml3
-rw-r--r--src/day1.rs45
-rw-r--r--src/day2.rs137
-rw-r--r--src/lib.rs1
5 files changed, 187 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index 8a7f3da..f270182 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,7 @@
/target
*~
+/input
+*.swp
# Added by cargo
#
diff --git a/Cargo.toml b/Cargo.toml
index 116750d..2938a76 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,3 +8,6 @@ edition = "2021"
[dependencies]
aoc-runner = "0.3"
aoc-runner-derive = "0.3"
+
+[profile.dev]
+opt-level=3
diff --git a/src/day1.rs b/src/day1.rs
index e5dd408..1326af6 100644
--- a/src/day1.rs
+++ b/src/day1.rs
@@ -6,7 +6,7 @@ pub fn input_generator<'c>(input : &'c str) -> Vec<u32>{
input.lines().map(u32::from_str).map(Result::unwrap).collect()
}
-#[aoc(day1, part1)]
+#[aoc(day1, part1, InternalState)]
pub fn solve_part1(input : &Vec<u32>) -> u32 {
struct Helper {
count : u32,
@@ -14,3 +14,46 @@ pub fn solve_part1(input : &Vec<u32>) -> u32 {
}
input.iter().fold(Helper{count:0,prev:u32::MAX},|x ,curr| -> Helper {if curr > &x.prev {Helper{count : x.count + 1, prev : *curr}} else {Helper{count : x.count, prev : *curr}}}).count
}
+
+#[aoc(day1, part1, Iterators)]
+pub fn solve_part1_iterators(input : &Vec<u32>) -> usize {
+ input.iter().skip(1).zip(input.iter()).filter(|(new, old)| new > old).count()
+}
+
+#[aoc(day1, part2, InternalState)]
+pub fn solve_part2(input : &Vec<u32>) -> usize {
+ let floating_window :u32 = input.iter().take(3).sum();
+ input.iter().skip(3).zip(input.iter()).scan(floating_window, |floating_window, (new, old)| {
+ let prev_window = *floating_window;
+ *floating_window = (*floating_window + *new) - *old;
+ Some((*floating_window, prev_window))
+ }).filter(|(new, old)| new > old).count()
+}
+
+#[aoc(day1,part2, DumbLoop)]
+pub fn solve_part2_dumb_loop(input : &Vec<u32>) -> usize {
+ if input.len() < 3 {
+ 0
+ }
+ else {
+ let mut floating_window = input[0]+input[1]+input[2];
+ let mut sum = 0;
+ for index in 3..input.len() {
+ let old = floating_window;
+ floating_window = (floating_window + input[index]) - input[index -3];
+ if floating_window > old {
+ sum = sum + 1;
+ }
+ }
+ sum
+ }
+}
+
+#[aoc(day1, part2, Iterators)]
+pub fn solve_part2_iterators(input : &Vec<u32>) -> usize {
+ let sliding_window = input.iter().skip(2).zip(input.iter().skip(1)).zip(input.iter())
+ .map(|((third, second), first)| third + second + first);
+ let old_window = sliding_window.clone();
+ let sliding_window = sliding_window.skip(1);
+ sliding_window.zip(old_window).filter(|(new, old)| new > old).count()
+}
diff --git a/src/day2.rs b/src/day2.rs
new file mode 100644
index 0000000..c821d07
--- /dev/null
+++ b/src/day2.rs
@@ -0,0 +1,137 @@
+use aoc_runner_derive::*;
+use std::str::FromStr;
+use std::error::Error;
+use std::ops::Add;
+use std::iter::Sum;
+
+enum Direction {
+ Forward,
+ Up,
+ Down,
+ Back,
+}
+
+pub struct Command {
+ direction : Direction,
+ amount : u32
+}
+
+#[derive(Debug)]
+pub struct CommandError(String);
+impl std::fmt::Display for CommandError {
+ fn fmt(&self, f : &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
+ write!(f,"Invalid Input: {}",self.0)
+ }
+}
+impl Error for CommandError {}
+
+struct Movement {
+ x : i32,
+ y : i32,
+}
+
+impl Add for Movement{
+ type Output = Movement;
+ fn add(self, other : Movement) -> Movement {
+ Movement{x : self.x + other.x, y : self.y + other.y}
+ }
+}
+
+impl Sum for Movement{
+ fn sum<I: Iterator<Item=Self>>(iter: I) -> Self {
+ iter.fold(Movement{x:0,y:0},|x,y| x+y)
+ }
+}
+
+impl From<&Command> for Movement {
+ fn from(c: &Command) -> Self {
+ match c.direction {
+ Direction::Forward => { Movement{x : c.amount as i32, y : 0} }
+ Direction::Up => { Movement{x : 0, y : -(c.amount as i32)}}
+ Direction::Down => { Movement{x :0, y : c.amount as i32}}
+ Direction::Back => { Movement{x : -(c.amount as i32), y : 0} }
+ }
+ }
+}
+
+enum ReinterpretedCommand {
+ Move(i32),
+ ChangeAim(i32),
+}
+
+impl From<&Command> for ReinterpretedCommand {
+ fn from(c: &Command) -> Self {
+ match c.direction {
+ Direction::Forward => { ReinterpretedCommand::Move(c.amount as i32)}
+ Direction::Up => { ReinterpretedCommand::ChangeAim(-(c.amount as i32))}
+ Direction::Down => { ReinterpretedCommand::ChangeAim(c.amount as i32)}
+ Direction::Back => {ReinterpretedCommand::Move(-(c.amount as i32))}
+ }
+ }
+}
+
+struct MovementWithDirection {
+ x : i32,
+ y : i32,
+ aim : i32,
+}
+
+impl Add<ReinterpretedCommand> for MovementWithDirection {
+ type Output = Self;
+ fn add(self, command : ReinterpretedCommand) -> Self {
+ match command {
+ ReinterpretedCommand::Move(distance) => {
+ MovementWithDirection{
+ x: self.x + distance,
+ y: self.y + self.aim * distance,
+ aim : self.aim,
+ }
+ }
+ ReinterpretedCommand::ChangeAim(delta) => {
+ MovementWithDirection {
+ x: self.x,
+ y: self.y,
+ aim : self.aim + delta,
+ }
+ }
+ }
+ }
+}
+
+impl FromStr for Command {
+ type Err = CommandError;
+ fn from_str(s: &str) -> Result<Self, CommandError> {
+ let mut parts = s.split(" ");
+ let direction = match parts.next() {
+ Some("down") => { Some(Direction::Down) }
+ Some("up") => { Some(Direction::Up) }
+ Some("forward") => { Some(Direction::Forward) }
+ Some("back") => { Some(Direction::Back) }
+ None | Some(_) => { None }
+ };
+ let amount = parts.next().map(|ss| FromStr::from_str(ss).ok()).flatten();
+ direction.zip(amount)
+ .map(|(direction, amount)| Command{direction,amount})
+ .ok_or_else(||{ CommandError(String::from(s)) })
+ }
+}
+
+#[aoc_generator(day2)]
+pub fn input_generator<'c>(input : &'c str) -> Vec<Command>{
+ input.lines().map(Command::from_str).map(Result::unwrap).collect()
+}
+
+#[aoc(day2, part1)]
+pub fn solve_part1(input : &Vec<Command>) -> i32 {
+ let target : Movement = input.iter().map(From::from).sum();
+ target.x*target.y
+}
+
+#[aoc(day2, part2)]
+pub fn solve_part2(input : &Vec<Command>) -> i32 {
+ let target = input.iter()
+ .map(From::from)
+ .fold(MovementWithDirection{x:0,y:0,aim:0},Add::add);
+ target.x*target.y
+}
+
diff --git a/src/lib.rs b/src/lib.rs
index 982ebfa..d702470 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,5 +1,6 @@
use aoc_runner_derive::aoc_lib;
pub mod day1;
+pub mod day2;
aoc_lib!{ year = 2021 }