common.rs (1250B)
1 use std::collections::HashSet; 2 3 fn get_dir(c: char) -> (i64, i64) { 4 match c { 5 'R' => (1, 0), 6 'L' => (-1, 0), 7 'U' => (0, 1), 8 'D' => (0, -1), 9 _ => panic!("Unexpected char") 10 } 11 } 12 13 fn follow(lead: (i64, i64), trail: (i64, i64)) -> (i64, i64) { 14 let max1 = |x: i64| x / (2 - (x%2).abs()); 15 let d = (max1(lead.0 - trail.0), max1(lead.1 - trail.1)); 16 (trail.0 + d.0, trail.1 + d.1) 17 } 18 19 fn step(r: &mut Vec<(i64, i64)>, d: (i64, i64)) { 20 r[0] = (r[0].0 + d.0, r[0].1 + d.1); 21 for i in 1..r.len() { 22 if (r[i].0 - r[i-1].0).abs() > 1 || (r[i].1 - r[i-1].1).abs() > 1 { 23 r[i] = follow(r[i-1], r[i]); 24 } else { 25 break; 26 } 27 } 28 } 29 30 pub fn simulate(n: usize) -> HashSet<(i64, i64)> { 31 let mut r = vec![(0, 0); n]; 32 let mut visited = HashSet::<(i64, i64)>::new(); 33 visited.insert(r[n-1]); 34 35 let mut line = String::new(); 36 while std::io::stdin().read_line(&mut line).unwrap() > 0 { 37 let dir = get_dir(line.chars().nth(0).unwrap()); 38 let l = line[2..line.len()-1].parse::<usize>().unwrap(); 39 for _ in 0..l { 40 step(&mut r, dir); 41 visited.insert(r[n-1]); 42 } 43 line.clear(); 44 } 45 visited 46 }