advent-of-code

Perserverance, or the lack thereof

git clone git://git.shimmy1996.com/advent-of-code.git

main.rs (2189B)

    1 use std::cmp::Ordering;
    2 use std::collections::HashSet;
    3 
    4 #[derive(Debug)]
    5 enum Dir {
    6     Left,
    7     Right,
    8     Up,
    9     Down,
   10 }
   11 
   12 impl Dir {
   13     fn from_str(s: &str) -> Self {
   14         match s {
   15             "L" => Self::Left,
   16             "R" => Self::Right,
   17             "U" => Self::Up,
   18             "D" => Self::Down,
   19             _ => unreachable!(),
   20         }
   21     }
   22 }
   23 
   24 fn sign(x: i32) -> i32 {
   25     match x.cmp(&0) {
   26         Ordering::Greater => 1,
   27         Ordering::Equal => 0,
   28         Ordering::Less => -1,
   29     }
   30 }
   31 
   32 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
   33 struct Coord(i32, i32);
   34 
   35 impl Coord {
   36     fn move_in(&mut self, dir: &Dir) {
   37         match dir {
   38             Dir::Left => self.0 = self.0 - 1,
   39             Dir::Right => self.0 = self.0 + 1,
   40             Dir::Up => self.1 = self.1 + 1,
   41             Dir::Down => self.1 = self.1 - 1,
   42         }
   43     }
   44 
   45     fn is_touching(&self, other: &Coord) -> bool {
   46         return (other.0 - self.0).abs() <= 1 && (other.1 - self.1).abs() <= 1;
   47     }
   48 
   49     fn follow(&mut self, other: &Coord) {
   50         self.0 = self.0 + sign(other.0 - self.0);
   51         self.1 = self.1 + sign(other.1 - self.1);
   52     }
   53 }
   54 
   55 fn main() {
   56     let input = std::fs::read_to_string("input.txt")
   57         .unwrap()
   58         .trim()
   59         .split("\n")
   60         .map(|x| {
   61             let tmp = x.split(' ').collect::<Vec<_>>();
   62             (Dir::from_str(tmp[0]), tmp[1].parse::<i32>().unwrap())
   63         })
   64         .collect::<Vec<(Dir, i32)>>();
   65     // 6087
   66     println!("Part 1: {}", part_1(&input, 2));
   67     // 2493
   68     println!("Part 2: {}", part_1(&input, 10));
   69 }
   70 
   71 fn part_1(input: &Vec<(Dir, i32)>, rope_length: usize) -> usize {
   72     let mut rope = vec![Coord(0, 0); rope_length];
   73     let mut visited = HashSet::new();
   74     visited.insert(rope.last().unwrap().clone());
   75     for (dir, step) in input {
   76         for _ in 0..*step {
   77             rope[0].move_in(dir);
   78             for i in 1..rope_length {
   79                 if !rope[i].is_touching(&rope[i - 1]) {
   80                     let tmp = rope[i - 1].clone();
   81                     rope[i].follow(&tmp);
   82                 }
   83             }
   84             visited.insert(rope.last().unwrap().clone());
   85         }
   86     }
   87     visited.len()
   88 }