aboutsummaryrefslogtreecommitdiff
path: root/2022/09/common.rs
blob: 45048da7033e9b2cf2a4127c92ff3b27ba6043a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
use std::collections::HashSet;

fn get_dir(c: char) -> (i64, i64) {
    match c {
        'R' => (1, 0),
        'L' => (-1, 0),
        'U' => (0, 1),
        'D' => (0, -1),
        _ => panic!("Unexpected char")
    }
}

fn follow(lead: (i64, i64), trail: (i64, i64)) -> (i64, i64) {
    let max1 = |x: i64| x / (2 - (x%2).abs());
    let d = (max1(lead.0 - trail.0), max1(lead.1 - trail.1));
    (trail.0 + d.0, trail.1 + d.1)
}

fn step(r: &mut Vec<(i64, i64)>, d: (i64, i64)) {
    r[0] = (r[0].0 + d.0, r[0].1 + d.1);
    for i in 1..r.len() {
        if (r[i].0 - r[i-1].0).abs() > 1 || (r[i].1 - r[i-1].1).abs() > 1 {
            r[i] = follow(r[i-1], r[i]);
        } else {
            break;
        }
    }
}

pub fn simulate(n: usize) -> HashSet<(i64, i64)> {
    let mut r = vec![(0, 0); n];
    let mut visited = HashSet::<(i64, i64)>::new();
    visited.insert(r[n-1]);

    let mut line = String::new();
    while std::io::stdin().read_line(&mut line).unwrap() > 0 {
        let dir = get_dir(line.chars().nth(0).unwrap());
        let l = line[2..line.len()-1].parse::<usize>().unwrap();
        for _ in 0..l {
            step(&mut r, dir);
            visited.insert(r[n-1]);
        }
        line.clear();
    }
    visited
}

Generated with cgit - Back to sebastiano.tronto.net