From 878e0fbeb4fea1c762187f1e8c22b679a0220268 Mon Sep 17 00:00:00 2001 From: Russell Champoux Date: Fri, 2 Dec 2016 16:40:57 -0500 Subject: [PATCH] First commit for Rust work days 1&2 --- .gitignore | 7 +-- 2016/day01/src/main.rs | 87 ++++++++++++++++++++++++++++++++++++- 2016/day02/Cargo.lock | 4 ++ 2016/day02/Cargo.toml | 6 +++ 2016/day02/src/main.rs | 99 ++++++++++++++++++++++++++++++++++++++++++ README.md | 2 + 6 files changed, 198 insertions(+), 7 deletions(-) create mode 100644 2016/day02/Cargo.lock create mode 100644 2016/day02/Cargo.toml create mode 100644 2016/day02/src/main.rs diff --git a/.gitignore b/.gitignore index cb14a42..7a8754d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,4 @@ # Generated by Cargo # will have compiled files and executables -/target/ - -# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries -# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock -Cargo.lock +**/target/ +**/data \ No newline at end of file diff --git a/2016/day01/src/main.rs b/2016/day01/src/main.rs index e7a11a9..e784a22 100644 --- a/2016/day01/src/main.rs +++ b/2016/day01/src/main.rs @@ -1,3 +1,86 @@ -fn main() { - println!("Hello, world!"); +use std::io::Read; +use std::fs::File; + +fn turn(state: &(i32, i32), direction: &String) -> (i32, i32) { + match direction.as_ref() { + "R" => { // clockwise motion + (-1 * state.1, 1 * state.0) + }, + "L" => { //rotate widdershins + (1 * state.1, -1 * state.0) + }, + _ => { + println!("Invalid direction: {}", direction); + (state.0, state.1) + }, + } } + +fn step(state: &(i32, i32), pos: &(i32, i32), dist: i32) -> (i32, i32) { + (pos.0 + state.0 * dist, pos.1 + state.1 * dist) +} + +// fn state_to_direction(state: &(i32, i32)) -> String { +// match state.0 { +// 1 => "N", +// -1 => "S", +// 0 => { +// match state.1 { +// 1 => "E", +// -1 => "W", +// _ => "Invalid", +// } +// }, +// _ => "Invalid", +// } +// } + +fn part_1(input: &String) { + let mut state = (1, 0); + let mut pos = (0, 0); + for item in input.trim().split(", ") { + let (dir, dist) = item.split_at(1); + let dir: String = dir.to_string(); + let dist: i32 = dist.parse::().unwrap(); + + state = turn(&state, &dir); + pos = step(&state, &pos, dist); + + //println!("Moved {} {} to arrive at ({}, {})", dist, dir, pos.0, pos.1); + } + println!("Part 1: Ended up at ({}, {}), {} away from the start", pos.0, pos.1, pos.0.abs() + pos.1.abs()); +} + +fn part_2(input: &String) { + let mut state = (1, 0); + let mut positions: Vec<(i32, i32)> = vec![(0, 0)]; + + for item in input.trim().split(", ") { + let (dir, dist) = item.split_at(1); + let dir: String = dir.to_string(); + let dist: i32 = dist.parse::().unwrap(); + + state = turn(&state, &dir); + let pos = step(&state, positions.last().unwrap(), dist); + print!("Move {} {} to ({}, {}) - ", dist, dir, pos.0, pos.1); + match positions.iter().position(|&p| p == pos) { + Some(v) => { + println!("Part 2: Stopped twice at ({}, {}) on element {}, {} away from the start", pos.0, pos.1, v, pos.0.abs() + pos.1.abs()); + break; + }, + None => { + println!("Did not match {} locations", positions.len()); + positions.push(pos); + }, + } + } +} + +fn main() { + let mut file = File::open("./data").expect("could not open file"); + let mut input = String::new(); + file.read_to_string(&mut input).expect("could not read file"); + + //part_1(&input); + part_2(&input); +} \ No newline at end of file diff --git a/2016/day02/Cargo.lock b/2016/day02/Cargo.lock new file mode 100644 index 0000000..8681120 --- /dev/null +++ b/2016/day02/Cargo.lock @@ -0,0 +1,4 @@ +[root] +name = "day02" +version = "0.1.0" + diff --git a/2016/day02/Cargo.toml b/2016/day02/Cargo.toml new file mode 100644 index 0000000..54979b2 --- /dev/null +++ b/2016/day02/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "day02" +version = "0.1.0" +authors = ["Russell Champoux "] + +[dependencies] diff --git a/2016/day02/src/main.rs b/2016/day02/src/main.rs new file mode 100644 index 0000000..31f874c --- /dev/null +++ b/2016/day02/src/main.rs @@ -0,0 +1,99 @@ +use std::cmp; +use std::io::Read; +use std::fs::File; + +fn clamp(val: i32, lb: i32, ub: i32) -> i32 { + cmp::min(cmp::max(val, lb), ub) +} + +fn state_to_val(state: (i32, i32)) -> i32 { + state.0 + 3 * state.1 + 1 +} + +fn state_to_new_val(state: (i32, i32)) -> char { + let val_map = [ + [' ', ' ', '1', ' ', ' '], + [' ', '2', '3', '4', ' '], + ['5', '6', '7', '8', '9'], + [' ', 'A', 'B', 'C', ' '], + [' ', ' ', 'D', ' ', ' '] + ]; + val_map[state.1 as usize][state.0 as usize] +} + +fn part_1(input: &String) { + let mut state = (1, 1); + // model a 3x3 grid that looks like + // 1 2 3 + // 4 5 6 + // 7 8 9 + // where (0,0) starts in the upper left + + //println!("Start at {}", state_to_val(state)); + let mut answer = String::new(); + + for line in input.split('\n') { + for letter in line.trim().chars() { + match letter { + 'R' => { state.0 = clamp(state.0 + 1, 0, 2); }, + 'L' => { state.0 = clamp(state.0 - 1, 0, 2); }, + 'U' => { state.1 = clamp(state.1 - 1, 0, 2); }, + 'D' => { state.1 = clamp(state.1 + 1, 0, 2); }, + _ => println!("Unknown!") + } + //println!("Moved {} to {}", letter, state_to_val(state)); + } + //println!("End on {}", state_to_val(state)); + answer += &state_to_val(state).to_string(); + } + println!("Part 1 answer is {}", answer); +} + +fn part_2(input: &String) { + let mut state = (0, 2); + // model a 5x5 grid that looks like + // 1 + // 2 3 4 + // 5 6 7 8 9 + // A B C + // D + // where blank spaces are invalid + let valid_map = [ + [0, 0, 1, 0, 0], + [0, 1, 1, 1, 0], + [1, 1, 1, 1, 1], + [0, 1, 1, 1, 0], + [0, 0, 1, 0, 0] + ]; + let mut answer = String::new(); + + for line in input.split('\n') { + for letter in line.trim().chars() { + let mut new_state = state; + match letter { + 'R' => { new_state.0 = clamp(state.0 + 1, 0, 4); }, + 'L' => { new_state.0 = clamp(state.0 - 1, 0, 4); }, + 'U' => { new_state.1 = clamp(state.1 - 1, 0, 4); }, + 'D' => { new_state.1 = clamp(state.1 + 1, 0, 4); }, + _ => println!("Unknown!") + } + // if this is a valid move position + if valid_map[new_state.1 as usize][new_state.0 as usize] == 1 { + state = new_state; + //println!("Moved {} to {}", letter, state_to_new_val(state)); + } + } + //println!("End on {}", state_to_new_val(state)); + answer.push(state_to_new_val(state)); + } + println!("Part 2 answer is {}", answer); +} + +fn main() { + let mut file = File::open("./data").expect("could not open file"); + let mut input = String::new(); + file.read_to_string(&mut input).expect("could not read file"); + + part_1(&input); + part_2(&input); +} diff --git a/README.md b/README.md index 694f2c2..c9a6509 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # AdventOfCode A repo for Advent of Code stuff + +Each day has its own directory. Input data for each day is saved in the corresponding directory. \ No newline at end of file