Skip to content

Instantly share code, notes, and snippets.

@robsears
Last active November 30, 2017 07:15
Show Gist options
  • Save robsears/f20ec33870273261239e11874b3d5418 to your computer and use it in GitHub Desktop.
Save robsears/f20ec33870273261239e11874b3d5418 to your computer and use it in GitHub Desktop.
Rust solution for the 2016 Advent of Code Day 1, parts 1 and 2. My original solution was in Java, but thought I'd give Rust a try.
// Advent of Code 2016: Day 1
// http://adventofcode.com/2016/day/1
// Data structure representing the elf navigating the city.
struct Elf {
x: i32,
y: i32,
heading: f32,
positions: Vec<(i32,i32)>,
revisit: bool
}
// Methods for the Elf
impl Elf {
// Return a tuple representing the Elf's current position
fn position(&self) -> (i32, i32) {
(self.x, self.y)
}
// Update the elf's heading and move to the new location
fn turn_left(&mut self, units: i32) {
self.heading = self.heading + ninety_degrees();
self.move_units(units);
}
// Update the elf's heading and move to the new location
fn turn_right(&mut self, units: i32) {
self.heading = self.heading - ninety_degrees();
self.move_units(units);
}
// Move a specified number of blocks in the correct heading
fn move_units(&mut self, units: i32) {
for _ in 0..units {
self.x = self.x + self.heading.cos().round() as i32;
self.y = self.y + self.heading.sin().round() as i32;
self.check_location();
self.update_postion();
}
}
// Calculate the "Taxicab geometry" for the elf:
// https://en.wikipedia.org/wiki/Taxicab_geometry
fn taxicab_distance(&mut self) -> i32 {
self.x.abs() + self.y.abs()
}
// Check to see if the elf has been in this location before (needed for part 2)
fn check_location(&mut self) {
let position = self.position();
if self.revisit == false && self.positions.contains(&position) {
println!("The first time the elf visits a location twice, it is at a taxicab distance of {} (part 2).", self.taxicab_distance());
self.revisit = true
}
}
// Add the current position to the list of places the elf has visited
fn update_postion(&mut self) {
let position = self.position();
self.positions.push(position);
}
}
// Helper method for proper orientation. Keeps the code clean
fn ninety_degrees() -> f32 {
use std::f32;
f32::consts::PI / 2.0
}
// Helper method for determining how many units the elf will travel
fn get_units(direction: &str) -> i32 {
direction[1..].parse::<i32>().unwrap()
}
fn main() {
// Initialize the elf
let mut elf = Elf { x: 0, y: 0, heading: ninety_degrees(), positions: Vec::new(), revisit: false };
// Input from AoC
let input = "L1, R3, R1, L5, L2, L5, R4, L2, R2, R2, L2, R1, L5, R3, L4, L1, L2, R3, R5, L2, R5, L1, R2, L5, R4, R2, R2, L1, L1, R1, L3, L1, R1, L3, R5, R3, R3, L4, R4, L2, L4, R1, R1, L193, R2, L1, R54, R1, L1, R71, L4, R3, R191, R3, R2, L4, R3, R2, L2, L4, L5, R4, R1, L2, L2, L3, L2, L1, R4, R1, R5, R3, L5, R3, R4, L2, R3, L1, L3, L3, L5, L1, L3, L3, L1, R3, L3, L2, R1, L3, L1, R5, R4, R3, R2, R3, L1, L2, R4, L3, R1, L1, L1, R5, R2, R4, R5, L1, L1, R1, L2, L4, R3, L1, L3, R5, R4, R3, R3, L2, R2, L1, R4, R2, L3, L4, L2, R2, R2, L4, R3, R5, L2, R2, R4, R5, L2, L3, L2, R5, L4, L2, R3, L5, R2, L1, R1, R3, R3, L5, L2, L2, R5";
// Split the input into a list of directions
let directions = input.split(", ");
// Process the directions
for dir in directions {
let units = get_units(dir);
if dir.starts_with("L") {
elf.turn_left(units);
}
else {
elf.turn_right(units);
}
}
// Tell us where the elf ended up
println!("The elf ends up {} taxicab blocks away (part 1).",
elf.taxicab_distance()
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment