Refactor to struct and enumerate steps
This commit is contained in:
		
							parent
							
								
									6acbdc53f1
								
							
						
					
					
						commit
						7e4a7641ff
					
				
					 1 changed files with 75 additions and 40 deletions
				
			
		
							
								
								
									
										115
									
								
								src/day_three.rs
									
										
									
									
									
								
							
							
						
						
									
										115
									
								
								src/day_three.rs
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,50 +1,60 @@
 | 
			
		|||
use std::cmp::Ordering;
 | 
			
		||||
use std::collections::BTreeSet;
 | 
			
		||||
use std::io;
 | 
			
		||||
use std::iter::{repeat, successors};
 | 
			
		||||
 | 
			
		||||
fn next(c: (i32, i32), direction: &str) -> (i32, i32) {
 | 
			
		||||
#[derive(Copy, Clone, Eq, Debug)]
 | 
			
		||||
struct Coord(usize, (i32, i32));
 | 
			
		||||
 | 
			
		||||
impl PartialEq for Coord {
 | 
			
		||||
    fn eq(&self, other: &Self) -> bool {
 | 
			
		||||
        self.1 == other.1
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Ord for Coord {
 | 
			
		||||
    fn cmp(&self, other: &Self) -> Ordering {
 | 
			
		||||
        (self.1).cmp(&(other.1))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl PartialOrd for Coord {
 | 
			
		||||
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
 | 
			
		||||
        self.1.partial_cmp(&other.1)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn next(c: (i32, i32), direction: char) -> (i32, i32) {
 | 
			
		||||
    match direction {
 | 
			
		||||
        "R" => (c.0 + 1, c.1),
 | 
			
		||||
        "L" => (c.0 - 1, c.1),
 | 
			
		||||
        "U" => (c.0, c.1 + 1),
 | 
			
		||||
        "D" => (c.0, c.1 - 1),
 | 
			
		||||
        'R' => (c.0 + 1, c.1),
 | 
			
		||||
        'L' => (c.0 - 1, c.1),
 | 
			
		||||
        'U' => (c.0, c.1 + 1),
 | 
			
		||||
        'D' => (c.0, c.1 - 1),
 | 
			
		||||
        _ => panic!("Wrong direction format!"),
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn direction_length(entry: String) -> (String, usize) {
 | 
			
		||||
    (
 | 
			
		||||
        entry.chars().nth(0).unwrap().to_string(),
 | 
			
		||||
        entry[1..].parse().unwrap(),
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn to_coordinates(entries: Vec<String>) -> BTreeSet<(i32, i32)> {
 | 
			
		||||
fn to_coordinates(entries: Vec<String>) -> BTreeSet<Coord> {
 | 
			
		||||
    let mut wire = BTreeSet::new();
 | 
			
		||||
 | 
			
		||||
    let mut it = entries
 | 
			
		||||
        .into_iter()
 | 
			
		||||
        .map(direction_length)
 | 
			
		||||
        .map(|entry| (entry.chars().nth(0).unwrap(), entry[1..].parse().unwrap()))
 | 
			
		||||
        .flat_map(|(direction, length)| repeat(direction).take(length));
 | 
			
		||||
 | 
			
		||||
    successors(
 | 
			
		||||
        it.next()
 | 
			
		||||
            .map(|direction| (next((0, 0), direction.as_ref()))),
 | 
			
		||||
        |c| it.next().map(|direction| (next(*c, direction.as_ref()))),
 | 
			
		||||
    )
 | 
			
		||||
    successors(it.next().map(|direction| (next((0, 0), direction))), |c| {
 | 
			
		||||
        it.next().map(|direction| (next(*c, direction)))
 | 
			
		||||
    })
 | 
			
		||||
    .enumerate()
 | 
			
		||||
    .for_each(|c| {
 | 
			
		||||
        wire.insert(c);
 | 
			
		||||
        wire.insert(Coord(c.0 + 1, c.1));
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    wire
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn distance(position: (i32, i32)) -> i32 {
 | 
			
		||||
    position.0.abs() + position.1.abs()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn closest(input: String) -> Option<i32> {
 | 
			
		||||
    let entries: Vec<BTreeSet<(i32, i32)>> = input
 | 
			
		||||
fn closest(input: &str) -> Option<i32> {
 | 
			
		||||
    let entries: Vec<BTreeSet<Coord>> = input
 | 
			
		||||
        .trim()
 | 
			
		||||
        .split("\n")
 | 
			
		||||
        .map(|line| line.split(",").map(String::from).collect())
 | 
			
		||||
| 
						 | 
				
			
			@ -54,32 +64,49 @@ fn closest(input: String) -> Option<i32> {
 | 
			
		|||
    entries[0]
 | 
			
		||||
        .intersection(&entries[1])
 | 
			
		||||
        .cloned()
 | 
			
		||||
        .map(distance)
 | 
			
		||||
        .map(|c| (c.1).0.abs() + (c.1).1.abs())
 | 
			
		||||
        .min()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn first(input: String) -> Option<i32> {}
 | 
			
		||||
fn first(input: &str) -> Option<i32> {
 | 
			
		||||
    let entries: Vec<BTreeSet<Coord>> = input
 | 
			
		||||
        .trim()
 | 
			
		||||
        .split("\n")
 | 
			
		||||
        .map(|line| line.split(",").map(String::from).collect())
 | 
			
		||||
        .map(to_coordinates)
 | 
			
		||||
        .collect();
 | 
			
		||||
 | 
			
		||||
    entries[0]
 | 
			
		||||
        .intersection(&entries[1])
 | 
			
		||||
        .cloned()
 | 
			
		||||
        .map(|c| {
 | 
			
		||||
            let other = entries[1].get(&c);
 | 
			
		||||
            (c.0 + other.unwrap().0) as i32
 | 
			
		||||
        })
 | 
			
		||||
        .min()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn main() -> io::Result<()> {
 | 
			
		||||
    let closest = closest(std::include_str!("../day3-input.txt").to_owned());
 | 
			
		||||
    println!("{:?}", closest);
 | 
			
		||||
    let input = std::include_str!("../day3-input.txt");
 | 
			
		||||
    println!("{:?}", closest(input));
 | 
			
		||||
    println!("{:?}", first(input));
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_coordinates_for_entry() {
 | 
			
		||||
    let mut expected: BTreeSet<(i32, i32)> = BTreeSet::new();
 | 
			
		||||
    let mut expected: BTreeSet<Coord> = BTreeSet::new();
 | 
			
		||||
    for i in 1..11 {
 | 
			
		||||
        expected.insert((i, 0));
 | 
			
		||||
        expected.insert(Coord(i - 1, (i as i32, 0)));
 | 
			
		||||
    }
 | 
			
		||||
    assert_eq!(to_coordinates(vec!["R10".to_owned()]), expected);
 | 
			
		||||
 | 
			
		||||
    expected = BTreeSet::new();
 | 
			
		||||
    expected.insert((1, 0));
 | 
			
		||||
    expected.insert((2, 0));
 | 
			
		||||
    expected.insert((2, 1));
 | 
			
		||||
    expected.insert((2, 2));
 | 
			
		||||
    expected.insert(Coord(0, (1, 0)));
 | 
			
		||||
    expected.insert(Coord(1, (2, 0)));
 | 
			
		||||
    expected.insert(Coord(2, (2, 1)));
 | 
			
		||||
    expected.insert(Coord(3, (2, 2)));
 | 
			
		||||
    let input = "R2,U2".to_owned().split(",").map(String::from).collect();
 | 
			
		||||
    assert_eq!(to_coordinates(input), expected);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -87,11 +114,19 @@ fn test_coordinates_for_entry() {
 | 
			
		|||
#[test]
 | 
			
		||||
fn test_part_one() {
 | 
			
		||||
    let input = "R75,D30,R83,U83,L12,D49,R71,U7,L72\n\
 | 
			
		||||
                 U62,R66,U55,R34,D71,R55,D58,R83"
 | 
			
		||||
        .to_owned();
 | 
			
		||||
                 U62,R66,U55,R34,D71,R55,D58,R83";
 | 
			
		||||
    assert_eq!(closest(input), Some(159));
 | 
			
		||||
    let input = "R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51\n\
 | 
			
		||||
                 U98,R91,D20,R16,D67,R40,U7,R15,U6,R7"
 | 
			
		||||
        .to_owned();
 | 
			
		||||
                 U98,R91,D20,R16,D67,R40,U7,R15,U6,R7";
 | 
			
		||||
    assert_eq!(closest(input), Some(135));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_part_two() {
 | 
			
		||||
    let input = "R75,D30,R83,U83,L12,D49,R71,U7,L72\n\
 | 
			
		||||
                 U62,R66,U55,R34,D71,R55,D58,R83";
 | 
			
		||||
    assert_eq!(first(input), Some(610));
 | 
			
		||||
    let input = "R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51\n\
 | 
			
		||||
                 U98,R91,D20,R16,D67,R40,U7,R15,U6,R7";
 | 
			
		||||
    assert_eq!(first(input), Some(464));
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue