Last active
November 30, 2017 07:15
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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