common.rs (3059B)
1 use std::cmp::*; 2 3 #[derive(PartialEq, Copy, Clone, Debug)] 4 pub enum Tile { Walk, Wall, Skip } 5 6 #[allow(dead_code)] 7 impl Tile { 8 pub fn from_byte(b: u8) -> Tile { 9 match b { 10 b'.' => Tile::Walk, 11 b'#' => Tile::Wall, 12 b' ' => Tile::Skip, 13 _ => panic!("not a valid tile {}", b) 14 } 15 } 16 17 pub fn to_char(&self) -> char { 18 match self { 19 Tile::Walk => '.', 20 Tile::Wall => '#', 21 Tile::Skip => ' ' 22 } 23 } 24 } 25 26 #[derive(PartialEq, Copy, Clone, Debug)] 27 pub enum Direction { Up, Down, Right, Left } 28 29 #[allow(dead_code)] 30 impl Direction { 31 pub fn from_char(c: char) -> Direction { 32 match c { 33 'U' => Direction::Up, 34 'D' => Direction::Down, 35 'R' => Direction::Right, 36 'L' => Direction::Left, 37 _ => panic!("invalid char for direction") 38 } 39 } 40 41 pub fn turn(&self, t: Direction) -> Direction { 42 match t { 43 Direction::Right => match self { 44 Direction::Up => Direction::Right, 45 Direction::Right => Direction::Down, 46 Direction::Down => Direction::Left, 47 Direction::Left => Direction::Up 48 }, 49 Direction::Left => match self { 50 Direction::Up => Direction::Left, 51 Direction::Left => Direction::Down, 52 Direction::Down => Direction::Right, 53 Direction::Right => Direction::Up 54 } 55 _ => panic!("cannot turn up or down") 56 } 57 } 58 59 pub fn step(&self) -> (i64, i64) { 60 match self { 61 Direction::Up => (-1, 0), 62 Direction::Down => (1, 0), 63 Direction::Right => (0, 1), 64 Direction::Left => (0, -1) 65 } 66 } 67 68 pub fn value(&self) -> usize { 69 match self { 70 Direction::Right => 0, 71 Direction::Down => 1, 72 Direction::Left => 2, 73 Direction::Up => 3 74 } 75 } 76 77 pub fn opposite(&self) -> Direction { 78 match self { 79 Direction::Right => Direction::Left, 80 Direction::Left => Direction::Right, 81 Direction::Up => Direction::Down, 82 Direction::Down => Direction::Up 83 } 84 } 85 86 pub fn is_positive(&self) -> bool { 87 *self == Direction::Down || *self == Direction::Right 88 } 89 } 90 91 pub fn read_instruction_line_from_stdin() -> (Vec<Direction>, Vec<usize>) { 92 let mut dir = vec![]; 93 let mut step = vec![]; 94 let mut line = String::new(); 95 let _ = std::io::stdin().read_line(&mut line); 96 let mut i = 0; 97 while i < line.len()-1 { 98 match line.chars().nth(i).unwrap() { 99 '0'..='9' => { 100 let j = line[i..].find(|c: char| !c.is_digit(10)).unwrap() + i; 101 step.push(line[i..j].parse::<usize>().unwrap()); 102 i = j; 103 }, 104 c => { 105 dir.push(Direction::from_char(c)); 106 i += 1; 107 } 108 } 109 } 110 (dir, step) 111 }