Files
adventofcode/2016/src/day2.rs
2018-11-29 16:58:51 +01:00

129 lines
2.6 KiB
Rust

use std::cmp::min;
use std::io::prelude::*;
use std::io;
use common;
#[derive(Default)]
pub struct Day2 {
}
impl Day2 {
pub fn new() -> Day2 {
Default::default()
}
}
impl common::Solution for Day2 {
fn part1(&mut self, input: &mut io::Read) -> String {
let reader = io::BufReader::new(input);
let mut pos = 5;
let mut code = String::new();
for line in reader.lines() {
for instruction in line.unwrap().trim().chars() {
pos = move_pos1(pos, instruction);
}
code += &pos.to_string();
}
code
}
fn part2(&mut self, input: &mut io::Read) -> String {
let reader = io::BufReader::new(input);
let mut pos = (0, 2);
let mut code = String::new();
for line in reader.lines() {
for instruction in line.unwrap().trim().chars() {
pos = move_pos2(pos, instruction);
}
code += &pos2char(pos);
}
code
}
}
fn move_pos1(pos: i32, instruction: char) -> i32
{
match instruction {
'U' => if pos > 3 { pos - 3 } else { pos },
'D' => if pos < 7 { pos + 3 } else { pos },
'L' => if pos % 3 != 1 { pos - 1 } else { pos },
'R' => if pos % 3 != 0 { pos + 1 } else { pos },
_ => panic!("Unsupported direction {}", instruction),
}
}
fn row_width(y: i32) -> i32
{
min(2 * y + 1, 9 - 2 * y)
}
fn row_offset(y: i32) -> i32
{
(5 - row_width(y)) / 2
}
fn is_legal(pos: (i32, i32)) -> bool {
let (x, y) = pos;
let width = row_width(y);
let offset = row_offset(y);
y >= 0 && y < 5 && x >= offset && x < offset + width
}
fn move_pos2(pos: (i32, i32), instruction: char) -> (i32, i32)
{
let (x, y) = pos;
let new_pos = match instruction {
'U' => (x, y - 1),
'D' => (x, y + 1),
'L' => (x - 1, y),
'R' => (x + 1, y),
_ => panic!("Unsupported direction {}", instruction),
};
if is_legal(new_pos) { new_pos } else { pos }
}
fn pos2char(pos: (i32, i32)) -> String
{
let (x, y) = pos;
let mut num = x + 1 - row_offset(y);
for i in 0..y {
num += row_width(i);
}
format!("{:X}", num)
}
#[cfg(test)]
mod tests {
use super::*;
use common::Solution;
const SAMPLE: &[u8] = b"ULL
RRDDD
LURDL
UUUUD";
#[test]
fn test_part1() {
let mut instance = Day2::new();
assert_eq!("1985", instance.part1(&mut SAMPLE));
}
#[test]
fn test_part2() {
let mut instance = Day2::new();
assert_eq!("5DB3", instance.part2(&mut SAMPLE));
}
}