summaryrefslogtreecommitdiff
path: root/2016/aoc1/src/main.rs
blob: e9b413823de73a2be28565b00b4059f61c5020c8 (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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use std::io::Read;
use std::fs::File;

#[derive(Clone, Copy, Debug)]
enum Direction {
    Up,
    Left,
    Down,
    Right
}

impl Direction {
    fn turn_right(self) -> Direction {
        match self {
            Direction::Up => Direction::Right,
            Direction::Right => Direction::Down,
            Direction::Down => Direction::Left,
            Direction::Left => Direction::Up
        }
    }
    fn turn_left(self) -> Direction {
        //not an ambiturner
        self.turn_right().turn_right().turn_right()
    }

    fn as_vector(self, dist: i32) -> (i32,i32) {
        match self {
            Direction::Up => (0, -dist),
            Direction::Right => (dist, 0),
            Direction::Down => (0, dist),
            Direction::Left => (-dist, 0)
        }
    }
}

fn main() {
    let content = read_file().expect("Failed to read file");
    let (_, dist_x, dist_y) = first_repeated_dest(content);
    println!("Total: ({}, {})", dist_x, dist_y);
    println!("Net: {}", dist_x+dist_y);
}

fn net_distance(content: String) -> (Direction, i32, i32) {
    content.trim().split(", ")
        .map(|action|
             (
                 action.chars().nth(0).unwrap(),
                 action.chars().skip(1).collect::<String>().parse::<i32>().unwrap()
             ))
        .fold((Direction::Up, 0,0), |(facing, acc_x, acc_y), (dir, dist)| {
            let new_facing = match dir {
                'R' => facing.turn_right(),
                'L' => facing.turn_left(),
                _ => panic!("bad input")
            };
              
            let (new_x, new_y) = new_facing.as_vector(dist);
            (new_facing, acc_x+new_x, acc_y+new_y)
        })
}

fn first_repeated_dest(content: String) -> (Direction, i32, i32) {
    let mut stops: Vec<(i32, i32)> = Vec::new();
    let actions = content.trim().split(", ")
        .map(|action|
             (
                 action.chars().nth(0).unwrap(),
                 action.chars().skip(1).collect::<String>().parse::<i32>().unwrap()
             ));
    let mut current_facing = Direction::Up;
    let (mut acc_x, mut acc_y) = (0, 0);
    for (dir, dist) in actions {
        current_facing = match dir {
                'R' => current_facing.turn_right(),
                'L' => current_facing.turn_left(),
                _ => panic!("bad input")
            };

        for _ in 0..dist {
            let (new_x, new_y) = current_facing.as_vector(1);
            acc_x += new_x;
            acc_y += new_y;

            if stops.iter().any(|&(x, y)| x==acc_x && y==acc_y) {
                return (current_facing, acc_x, acc_y);
            }
            stops.push((acc_x, acc_y));
        }
    }
    (current_facing, acc_x, acc_y)
}

fn read_file() -> Result<String, String> {
    let mut file = try!(File::open("input.txt").map_err(|e| e.to_string()));
    let mut content = String::new();
    try!(file.read_to_string(&mut content).map_err(|e| e.to_string()));
    Ok(content)
}