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::collections::BTreeSet; | ||||||
| use std::io; | use std::io; | ||||||
| use std::iter::{repeat, successors}; | 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 { |     match direction { | ||||||
|         "R" => (c.0 + 1, c.1), |         'R' => (c.0 + 1, c.1), | ||||||
|         "L" => (c.0 - 1, c.1), |         'L' => (c.0 - 1, c.1), | ||||||
|         "U" => (c.0, c.1 + 1), |         'U' => (c.0, c.1 + 1), | ||||||
|         "D" => (c.0, c.1 - 1), |         'D' => (c.0, c.1 - 1), | ||||||
|         _ => panic!("Wrong direction format!"), |         _ => panic!("Wrong direction format!"), | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn direction_length(entry: String) -> (String, usize) { | fn to_coordinates(entries: Vec<String>) -> BTreeSet<Coord> { | ||||||
|     ( |  | ||||||
|         entry.chars().nth(0).unwrap().to_string(), |  | ||||||
|         entry[1..].parse().unwrap(), |  | ||||||
|     ) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn to_coordinates(entries: Vec<String>) -> BTreeSet<(i32, i32)> { |  | ||||||
|     let mut wire = BTreeSet::new(); |     let mut wire = BTreeSet::new(); | ||||||
| 
 | 
 | ||||||
|     let mut it = entries |     let mut it = entries | ||||||
|         .into_iter() |         .into_iter() | ||||||
|         .map(direction_length) |         .map(|entry| (entry.chars().nth(0).unwrap(), entry[1..].parse().unwrap())) | ||||||
|         .flat_map(|(direction, length)| repeat(direction).take(length)); |         .flat_map(|(direction, length)| repeat(direction).take(length)); | ||||||
| 
 | 
 | ||||||
|     successors( |     successors(it.next().map(|direction| (next((0, 0), direction))), |c| { | ||||||
|         it.next() |         it.next().map(|direction| (next(*c, direction))) | ||||||
|             .map(|direction| (next((0, 0), direction.as_ref()))), |     }) | ||||||
|         |c| it.next().map(|direction| (next(*c, direction.as_ref()))), |     .enumerate() | ||||||
|     ) |  | ||||||
|     .for_each(|c| { |     .for_each(|c| { | ||||||
|         wire.insert(c); |         wire.insert(Coord(c.0 + 1, c.1)); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     wire |     wire | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn distance(position: (i32, i32)) -> i32 { | fn closest(input: &str) -> Option<i32> { | ||||||
|     position.0.abs() + position.1.abs() |     let entries: Vec<BTreeSet<Coord>> = input | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn closest(input: String) -> Option<i32> { |  | ||||||
|     let entries: Vec<BTreeSet<(i32, i32)>> = input |  | ||||||
|         .trim() |         .trim() | ||||||
|         .split("\n") |         .split("\n") | ||||||
|         .map(|line| line.split(",").map(String::from).collect()) |         .map(|line| line.split(",").map(String::from).collect()) | ||||||
|  | @ -54,32 +64,49 @@ fn closest(input: String) -> Option<i32> { | ||||||
|     entries[0] |     entries[0] | ||||||
|         .intersection(&entries[1]) |         .intersection(&entries[1]) | ||||||
|         .cloned() |         .cloned() | ||||||
|         .map(distance) |         .map(|c| (c.1).0.abs() + (c.1).1.abs()) | ||||||
|         .min() |         .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<()> { | pub fn main() -> io::Result<()> { | ||||||
|     let closest = closest(std::include_str!("../day3-input.txt").to_owned()); |     let input = std::include_str!("../day3-input.txt"); | ||||||
|     println!("{:?}", closest); |     println!("{:?}", closest(input)); | ||||||
|  |     println!("{:?}", first(input)); | ||||||
| 
 | 
 | ||||||
|     Ok(()) |     Ok(()) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[test] | #[test] | ||||||
| fn test_coordinates_for_entry() { | 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 { |     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); |     assert_eq!(to_coordinates(vec!["R10".to_owned()]), expected); | ||||||
| 
 | 
 | ||||||
|     expected = BTreeSet::new(); |     expected = BTreeSet::new(); | ||||||
|     expected.insert((1, 0)); |     expected.insert(Coord(0, (1, 0))); | ||||||
|     expected.insert((2, 0)); |     expected.insert(Coord(1, (2, 0))); | ||||||
|     expected.insert((2, 1)); |     expected.insert(Coord(2, (2, 1))); | ||||||
|     expected.insert((2, 2)); |     expected.insert(Coord(3, (2, 2))); | ||||||
|     let input = "R2,U2".to_owned().split(",").map(String::from).collect(); |     let input = "R2,U2".to_owned().split(",").map(String::from).collect(); | ||||||
|     assert_eq!(to_coordinates(input), expected); |     assert_eq!(to_coordinates(input), expected); | ||||||
| } | } | ||||||
|  | @ -87,11 +114,19 @@ fn test_coordinates_for_entry() { | ||||||
| #[test] | #[test] | ||||||
| fn test_part_one() { | fn test_part_one() { | ||||||
|     let input = "R75,D30,R83,U83,L12,D49,R71,U7,L72\n\ |     let input = "R75,D30,R83,U83,L12,D49,R71,U7,L72\n\ | ||||||
|                  U62,R66,U55,R34,D71,R55,D58,R83" |                  U62,R66,U55,R34,D71,R55,D58,R83";
 | ||||||
|         .to_owned(); |  | ||||||
|     assert_eq!(closest(input), Some(159)); |     assert_eq!(closest(input), Some(159)); | ||||||
|     let input = "R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51\n\ |     let input = "R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51\n\ | ||||||
|                  U98,R91,D20,R16,D67,R40,U7,R15,U6,R7" |                  U98,R91,D20,R16,D67,R40,U7,R15,U6,R7";
 | ||||||
|         .to_owned(); |  | ||||||
|     assert_eq!(closest(input), Some(135)); |     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