Advertisement
Guest User

Untitled

a guest
Dec 4th, 2019
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 2.71 KB | None | 0 0
  1. use std::env;
  2. use std::collections::HashMap;
  3. use std::io::{self, prelude::*, BufReader};
  4. use std::fs::File;
  5. use std::cmp;
  6.  
  7. fn main() {
  8.     let args: Vec<String> = env::args().collect();
  9.     let filename = &args[1];
  10.     day03(&filename).unwrap();
  11. }
  12.  
  13. fn manhattan_distance(x0: i64, y0: i64, x1: i64, y1: i64) -> u64 {
  14.     (x1-x0).abs() as u64 + (y1-y0).abs() as u64
  15. }
  16.  
  17. fn day03(input: &str) -> io::Result<()> {
  18.     let file = File::open(input).expect("Input file not found.");
  19.     let reader = BufReader::new(file);
  20.  
  21.     let input: Vec<String> = match reader.lines().collect() {
  22.         Err(err) => panic!("Unknown error reading input: {}", err),
  23.         Ok(result) => result,
  24.     };
  25.  
  26.     let mut wires: Vec<_> = Vec::new();
  27.     let mut wire_map: HashMap<(i64,i64),u64> = HashMap::new(); // k,v = point, cross #
  28.     for line in input {
  29.         let parts = line.split(",");
  30.         let mut wire: HashMap<(i64,i64),u64> = HashMap::new(); // k,v = point, distance
  31.         let mut pos: (i64,i64) = (0, 0);
  32.         let mut d: u64 = 0;
  33.         // Build map of this wire
  34.         for segment in parts {
  35.             let dir = &segment[0..1];
  36.             let mag = segment[1..].parse::<i64>().unwrap();
  37.             let dir = match dir {
  38.                 "U" => ( 0,-1),
  39.                 "D" => ( 0, 1),
  40.                 "L" => (-1, 0),
  41.                 "R" => ( 1, 0),
  42.                 other => panic!("Unknown direction: {}", other),
  43.             };
  44.             for _ in 0..mag {
  45.                 pos.0 += dir.0;
  46.                 pos.1 += dir.1;
  47.                 d += 1;
  48.                 if !wire.contains_key(&pos) { wire.insert(pos,d); }
  49.             }
  50.         }
  51.         wires.push(wire.clone());
  52.         // Merge this wire's intersection into global wire map
  53.         for (pt,_) in wire {
  54.             match wire_map.insert(pt,1) {
  55.                 Some(wire) => { wire_map.insert(pt,wire+1); },
  56.                 None => {},
  57.             }
  58.         }
  59.     }
  60.  
  61.     // Part 1
  62.     let part1 = wire_map
  63.         .iter()
  64.         .filter(|(_,v)| **v == 2)
  65.         .min_by(|a, b| manhattan_distance(0,0,(a.0).0,(a.0).1).cmp(&manhattan_distance(0,0,(b.0).0,(b.0).1)))
  66.         .map(|pt| manhattan_distance(0,0,(pt.0).0,(pt.0).1))
  67.         .unwrap();
  68.     println!("Part 1: {}", part1); // 1211
  69.  
  70.     // Part 2
  71.     let mut part2 = std::u64::MAX;
  72.     for intersect in wire_map.iter().filter(|(_,v)| **v == 2).map(|(k,_)| k) {
  73.         let dist = wires
  74.             .iter()
  75.             .map(|x| x
  76.                 .iter()
  77.                 .filter(|(k,_)| k == &intersect)
  78.                 .map(|(_,v)| v).sum::<u64>())
  79.             .sum();
  80.         part2 = cmp::min(part2, dist);
  81.     }
  82.     println!("Part 2: {}", part2); // 101386
  83.  
  84.     Ok(())
  85. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement