use core::panic; use std::collections::HashSet; type Pt = (i32, i32); /** * how should the tail move to catch up with the head? */ fn catchup(head: Pt, tail: Pt) -> Pt { let (hx, hy) = head; let (tx, ty) = tail; let xdiff = hx - tx; let ydiff = hy - ty; // only move if we're not adjescent (incl diagonally) if xdiff.abs() > 1 || ydiff.abs() > 1 { // only move 1 square (x and or y) in the direction of the head (tail.0 + xdiff.signum(), tail.1 + ydiff.signum()) } else { (tail.0, tail.1) } } pub fn run(input: String) { // series of steps // let mut head: Pt = (0,0); // let mut tail: Pt = (0,0); // let mut htrail: Vec = Vec::new(); let mut rope: Vec = (0..10).map(|_| { (0,0) as Pt}).collect(); let mut trail: Vec = Vec::new(); for line in input.lines() { let mut toks = line.split_whitespace(); let dir: &str = toks.next().expect("expected a direction!"); let reps: u32 = toks.next().expect("expected a reps!").parse().expect("reps wasn't a number!"); for _ in 0..reps { let head = rope[0]; let newhead = match dir { "U" => (head.0, head.1+1), "D" => (head.0, head.1-1), "L" => (head.0-1, head.1), "R" => (head.0+1, head.1), dir => panic!("unexpected direction {}", dir), }; rope[0] = newhead; for l in 1..rope.len() { rope[l] = catchup(rope[l-1], rope[l]); } let tail = rope.last().unwrap(); // htrail.push(head); // tail = catchup(head, tail); trail.push(*tail); } } //println!("htrail {:?}", htrail); //println!("trail {:?}", trail); let trailsz = trail.into_iter().collect::>().len(); println!("Day 9: {}", trailsz); }