summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/day2.rs102
-rw-r--r--src/lib.rs10
2 files changed, 110 insertions, 2 deletions
diff --git a/src/bin/day2.rs b/src/bin/day2.rs
new file mode 100644
index 0000000..066301f
--- /dev/null
+++ b/src/bin/day2.rs
@@ -0,0 +1,102 @@
+struct Position {
+ x: i32,
+ y: i32,
+}
+
+struct AimedPosition {
+ pos: Position,
+ aim: i32,
+}
+
+fn main() {
+ let input = advent::read_lines(2);
+
+ let pos = drive_course(Position {x: 0, y: 0}, &input);
+ println!("2a: {}", pos.x * pos.y);
+
+ let pos = drive_course_aimed(Position {x: 0, y: 0}, &input);
+ println!("2b: {}", pos.x * pos.y);
+}
+
+fn move_submarine(pos: Position, cmd: &str) -> Position {
+ let tokens : Vec<&str> = cmd.split(' ').collect();
+ let direction = tokens[0];
+ let distance = tokens[1].parse::<i32>().unwrap();
+
+ let mut pos = pos;
+ match direction {
+ "forward" => {
+ pos.x += distance;
+ },
+ "down" => {
+ pos.y += distance;
+ },
+ "up" => {
+ pos.y -= distance;
+ },
+ _ => panic!("invalid direction: {}", direction)
+ };
+
+ pos
+}
+
+fn move_submarine_aimed(pos: AimedPosition, cmd: &str) -> AimedPosition {
+ let tokens : Vec<&str> = cmd.split(' ').collect();
+ let direction = tokens[0];
+ let distance = tokens[1].parse::<i32>().unwrap();
+
+ let mut pos = pos;
+ match direction {
+ "forward" => {
+ pos.pos.x += distance;
+ pos.pos.y += pos.aim * distance;
+ },
+ "down" => {
+ pos.aim += distance;
+ },
+ "up" => {
+ pos.aim -= distance;
+ },
+ _ => panic!("invalid direction: {}", direction)
+ };
+
+ pos
+}
+
+fn drive_course<T: AsRef<str>>(start: Position, course: &[T]) -> Position {
+ let mut pos = start;
+ for cmd in course {
+ pos = move_submarine(pos, cmd.as_ref());
+ }
+ pos
+}
+
+fn drive_course_aimed<T: AsRef<str>>(start: Position, course: &[T]) -> Position {
+ let mut pos = AimedPosition { pos: start, aim: 0 };
+ for cmd in course {
+ pos = move_submarine_aimed(pos, cmd.as_ref());
+ }
+ pos.pos
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test() {
+ let course = [
+ "forward 5",
+ "down 5",
+ "forward 8",
+ "up 3",
+ "down 8",
+ "forward 2",
+ ];
+ let pos = drive_course(Position {x: 0, y: 0}, &course);
+ assert_eq!(pos.x * pos.y, 150);
+
+ let pos = drive_course_aimed(Position {x: 0, y: 0}, &course);
+ assert_eq!(pos.x * pos.y, 900);
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 6befee8..2f99150 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -4,9 +4,15 @@ pub fn read_file(day: u8) -> String {
std::fs::read_to_string(filename).unwrap()
}
-pub fn read_numbers(day: u8) -> Vec<usize> {
+pub fn read_lines(day: u8) -> Vec<String> {
read_file(day).split('\n')
.filter(|n| !n.is_empty())
- .map(|n| n.parse::<usize>().unwrap())
+ .map(String::from)
.collect()
}
+
+pub fn read_numbers(day: u8) -> Vec<usize> {
+ read_lines(day).iter()
+ .map(|n| n.parse::<usize>().unwrap())
+ .collect()
+}