a.rs (2225B)
1 use std::cmp::max; 2 mod common; 3 use common::*; 4 5 #[derive(Copy, Clone, Debug)] 6 pub struct Position { 7 pub i: usize, 8 pub j: usize, 9 pub d: Direction 10 } 11 12 pub struct Map { 13 pub tiles: Vec<Vec<Tile>> 14 } 15 16 type StepFn = fn(&Map, Position) -> Position; 17 18 impl Map { 19 pub fn from_stdin() -> Map { 20 let mut maxlen = 0; 21 let mut tiles = vec![]; 22 let mut line = String::new(); 23 while std::io::stdin().read_line(&mut line).unwrap() > 1 { 24 let v = line[0..line.len()-1].as_bytes().iter() 25 .map(|b| Tile::from_byte(*b)).collect::<Vec<_>>(); 26 maxlen = max(maxlen, v.len()); 27 tiles.push(v); 28 line.clear(); 29 } 30 for v in &mut tiles { 31 while v.len() < maxlen { v.push(Tile::Skip); } 32 } 33 Map { tiles } 34 } 35 36 pub fn start_position(&self) -> Position { 37 let first_valid = self.tiles[0].iter() 38 .position(|t| *t == Tile::Walk).unwrap(); 39 Position { i: 0, j: first_valid, d: Direction::Right } 40 } 41 42 pub fn walk(&self, pos: Position, n: usize, step: StepFn) -> Position { 43 let mut p = pos; 44 for _ in 0..n { p = step(self, p); } 45 p 46 } 47 } 48 49 fn step(map: &Map, position: Position) -> Position { 50 let imax = map.tiles.len(); 51 let jmax = map.tiles[0].len(); 52 let s = position.d.step(); 53 let mut p = position; 54 loop { 55 let inext = ((s.0 + imax as i64) as usize + p.i) % imax; 56 let jnext = ((s.1 + jmax as i64) as usize + p.j) % jmax; 57 p = Position { i: inext, j: jnext, d: p.d }; 58 match map.tiles[p.i][p.j] { 59 Tile::Walk => return p, 60 Tile::Wall => return position, 61 Tile::Skip => () 62 } 63 } 64 } 65 66 fn password(p: Position) -> usize { 67 1000 * (p.i+1) + 4 * (p.j+1) + p.d.value() 68 } 69 70 fn main() { 71 let map = Map::from_stdin(); 72 let (turns, steps) = read_instruction_line_from_stdin(); 73 let mut position = map.start_position(); 74 75 for i in 0..turns.len() { 76 position = map.walk(position, steps[i], step); 77 position.d = position.d.turn(turns[i]); 78 } 79 position = map.walk(position, steps[steps.len()-1], step); 80 println!("{}", password(position)); 81 }