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