summaryrefslogtreecommitdiff
path: root/src/day_2.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/day_2.rs')
-rw-r--r--src/day_2.rs104
1 files changed, 104 insertions, 0 deletions
diff --git a/src/day_2.rs b/src/day_2.rs
new file mode 100644
index 0000000..d7ebcd0
--- /dev/null
+++ b/src/day_2.rs
@@ -0,0 +1,104 @@
+use std::ops::AddAssign;
+
+type Scalar = isize;
+
+#[derive(Copy, Clone, Debug)]
+enum Instruction
+{
+ Forward(Scalar),
+ Down(Scalar),
+ Up(Scalar),
+}
+
+#[derive(Copy, Clone, Debug)]
+struct Victor
+{
+ x: Scalar,
+ y: Scalar,
+}
+
+fn part1(instructions: &[Instruction])
+{
+ let directions: Vec<Victor> = instructions
+ .iter()
+ .map(|&i| Victor::from_direct_instruction(i))
+ .collect();
+
+ let mut position = Victor::new(0, 0);
+ for dir in directions {
+ position += dir;
+ }
+
+ println!("Solution to part 1: {}", position.x * position.y);
+}
+
+fn part2(instructions: &[Instruction])
+{
+ let mut aim: Scalar = 0;
+ let mut position = Victor::new(0, 0);
+
+ for i in instructions {
+ match &i {
+ Instruction::Down(amount) => aim += amount,
+ Instruction::Up(amount) => aim -= amount,
+ Instruction::Forward(amount) => position += Victor::new(*amount, amount * aim),
+ }
+ }
+
+ println!("Solution to part 2: {}", position.x * position.y);
+}
+
+pub fn run(input: Vec<String>)
+{
+ let instructions: Vec<Instruction> = input
+ .into_iter()
+ .map(|s| Instruction::from_str(s))
+ .collect();
+
+ part1(&instructions);
+ part2(&instructions);
+}
+
+impl Instruction
+{
+ pub fn from_str<S>(instruction_str: S) -> Self
+ where
+ S: AsRef<str>,
+ {
+ let parts: Vec<&str> = instruction_str.as_ref().split_whitespace().collect();
+ assert_eq!(parts.len(), 2);
+
+ let scalar = parts[1].parse().expect("Not a valid length");
+ match parts[0] {
+ "forward" => Self::Forward(scalar),
+ "down" => Self::Down(scalar),
+ "up" => Self::Up(scalar),
+ o => panic!("{} is not a valid instruction", o),
+ }
+ }
+}
+
+impl Victor
+{
+ pub fn new(x: Scalar, y: Scalar) -> Self { Self { x, y } }
+
+ pub fn from_direct_instruction(instruction: Instruction) -> Self
+ {
+ use Instruction::*;
+
+ match instruction {
+ Forward(distance) => Victor::new(distance, 0),
+ Down(distance) => Victor::new(0, distance),
+ Up(distance) => Victor::new(0, -distance),
+ }
+ }
+}
+
+impl AddAssign for Victor
+{
+ fn add_assign(&mut self, rhs: Self)
+ {
+ self.x += rhs.x;
+ self.y += rhs.y;
+ }
+}