I am solving the problems for Advent of Code 2016 to learn Rust programming. The prompt for the first problem can be summarized:
I start at position 0,0 on a regular grid. I am given a set of directions to get to a location. I can only travel in "steps" on this grid, and I am only given directions in the form (e.g.):
R5, L2, L1, R1, R3, R3, L3, R3, R4, L2, R4, L4, R4
Where the first character is the direction to turn right or left and the following number is the number of steps to take. I need to compute the Manhattan distance between my starting point and the ending point.
The instructions are saved in a text file called "2016-1.txt".
use std::fs;
struct Pos {
facing: char,
x: i32,
y: i32,
}
fn split_dir(dir_str: &str) -> Vec<&str> {
dir_str.split(", ").collect()
}
fn update_facing(rel_dir: &char, face_char: &char) -> char {
if *rel_dir == 'L' {
match face_char {
'N' => 'W',
'S' => 'E',
'E' => 'N',
'W' => 'S',
_ => 'I', // Is there a better way to handle the catch-all?
}
} else {
match face_char {
'N' => 'E',
'S' => 'W',
'E' => 'S',
'W' => 'N',
_ => 'I',
}
}
}
fn update_x(pos_x: i32, face_char: char, move_num: i32) -> i32 {
match face_char {
'E' => pos_x + move_num,
'W' => pos_x - move_num,
_ => pos_x
}
}
fn update_y(pos_y: i32, face_char: char, move_num: &i32) -> i32 {
match face_char {
'N' => pos_y + move_num,
'S' => pos_y - move_num,
_ => pos_y
}
}
fn get_manhattan_dist(pos_x: i32, pos_y: i32, origin_x: i32, origin_y: i32) -> i32 {
(pos_x - origin_x).abs() + (pos_y - origin_y).abs()
}
fn main() {
let s = fs::read_to_string("2016-1.txt")
.expect("Failed to read file.");
let split: Vec<&str> = split_dir(&s);
let mut pos: Pos = Pos {x: 0, y: 0, facing: 'N'};
for inst in split {
// Update direction
let rel_dir = inst.chars().nth(0).unwrap(); // Get first character of the instruction
pos.facing = update_facing(&rel_dir, &pos.facing);
// Update position
let move_num = &inst[1..].parse::<i32>().unwrap();
pos.x = update_x(pos.x, pos.facing, *move_num);
pos.y = update_y(pos.y, pos.facing, &move_num);
}
let dist = get_manhattan_dist(pos.x, pos.y, 0, 0);
println!("{}", dist);
}
I am particularly interested in error handling. Particularly in the update_facing
function. This is my first Rust program, so all advice is warranted as well.