use std::collections::HashMap; fn move_tail(head: &(isize, isize), mut tail: (isize, isize)) -> (isize, isize) { if head.0 == tail.0 && head.1 == tail.1 { // same spot, wich is fine } else if head.1 == tail.1 { // x coords are different -> horizontal movement if tail.0 + 2 == head.0 { tail.0 = tail.0 + 1; } else if tail.0 - 2 == head.0 { tail.0 = tail.0 - 1; } } else if head.0 == tail.0 { // y coords are different -> vertical movement if tail.1 + 2 == head.1 { tail.1 = tail.1 + 1; } else if tail.1 - 2 == head.1 { tail.1 = tail.1 - 1; } } else { // both coords are different -> horizontal and vertical movement if head.0 == tail.0 + 1 { if head.1 == tail.1 + 2 { tail.0 = tail.0 + 1; tail.1 = tail.1 + 1; } else if head.1 == tail.1 - 2 { tail.0 = tail.0 + 1; tail.1 = tail.1 - 1; } } else if head.0 == tail.0 - 1 { if head.1 == tail.1 + 2 { tail.0 = tail.0 - 1; tail.1 = tail.1 + 1; } else if head.1 == tail.1 - 2 { tail.0 = tail.0 - 1; tail.1 = tail.1 - 1; } } else if head.0 == tail.0 + 2 { if head.1 == tail.1 + 1 { tail.0 = tail.0 + 1; tail.1 = tail.1 + 1; } else if head.1 == tail.1 - 1 { tail.0 = tail.0 + 1; tail.1 = tail.1 - 1; } } else if head.0 == tail.0 - 2 { if head.1 == tail.1 + 1 { tail.0 = tail.0 - 1; tail.1 = tail.1 + 1; } else if head.1 == tail.1 - 1 { tail.0 = tail.0 - 1; tail.1 = tail.1 - 1; } } } tail } pub fn task_one(input: &str) -> String { let mut visited_places: HashMap<(isize, isize), u8> = HashMap::new(); let mut head = (0, 0); let mut tail = (0, 0); visited_places.insert(tail, 0); for line in input.trim().lines() { match line.split_once(" ").unwrap() { ("U", count) => { for _ in 1..=count.parse::().unwrap() { head.1 = head.1 + 1; tail = move_tail(&head, tail); visited_places.insert(tail, 0); } } ("R", count) => { for _ in 1..=count.parse::().unwrap() { head.0 = head.0 + 1; tail = move_tail(&head, tail); visited_places.insert(tail, 0); } } ("D", count) => { for _ in 1..=count.parse::().unwrap() { head.1 = head.1 - 1; tail = move_tail(&head, tail); visited_places.insert(tail, 0); } } ("L", count) => { for _ in 1..=count.parse::().unwrap() { head.0 = head.0 - 1; tail = move_tail(&head, tail); visited_places.insert(tail, 0); } } (_, _) => panic!(), } } visited_places.len().to_string() } pub fn task_two(input: &str) -> String { let mut visited_places: HashMap<(isize, isize), u8> = HashMap::new(); let mut knots: [(isize, isize); 10] = [(0, 0); 10]; visited_places.insert(knots[9], 0); for line in input.trim().lines() { match line.split_once(" ").unwrap() { ("U", count) => { for _ in 1..=count.parse::().unwrap() { knots[0].1 = knots[0].1 + 1; for i in 1..10 { knots[i] = move_tail(&knots[i - 1], knots[i]); } visited_places.insert(knots[9], 0); } } ("R", count) => { for _ in 1..=count.parse::().unwrap() { knots[0].0 = knots[0].0 + 1; for i in 1..10 { knots[i] = move_tail(&knots[i - 1], knots[i]); } visited_places.insert(knots[9], 0); } } ("D", count) => { for _ in 1..=count.parse::().unwrap() { knots[0].1 = knots[0].1 - 1; for i in 1..10 { knots[i] = move_tail(&knots[i - 1], knots[i]); } visited_places.insert(knots[9], 0); } } ("L", count) => { for _ in 1..=count.parse::().unwrap() { knots[0].0 = knots[0].0 - 1; for i in 1..10 { knots[i] = move_tail(&knots[i - 1], knots[i]); } visited_places.insert(knots[9], 0); } } (_, _) => panic!(), } } visited_places.len().to_string() }