Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::env;
- use std::collections::HashMap;
- use std::io::{self, prelude::*, BufReader};
- use std::fs::File;
- use std::cmp;
- fn main() {
- let args: Vec<String> = env::args().collect();
- let filename = &args[1];
- day03(&filename).unwrap();
- }
- fn manhattan_distance(x0: i64, y0: i64, x1: i64, y1: i64) -> u64 {
- (x1-x0).abs() as u64 + (y1-y0).abs() as u64
- }
- fn day03(input: &str) -> io::Result<()> {
- let file = File::open(input).expect("Input file not found.");
- let reader = BufReader::new(file);
- let input: Vec<String> = match reader.lines().collect() {
- Err(err) => panic!("Unknown error reading input: {}", err),
- Ok(result) => result,
- };
- let mut wires: Vec<_> = Vec::new();
- let mut wire_map: HashMap<(i64,i64),u64> = HashMap::new(); // k,v = point, cross #
- for line in input {
- let parts = line.split(",");
- let mut wire: HashMap<(i64,i64),u64> = HashMap::new(); // k,v = point, distance
- let mut pos: (i64,i64) = (0, 0);
- let mut d: u64 = 0;
- // Build map of this wire
- for segment in parts {
- let dir = &segment[0..1];
- let mag = segment[1..].parse::<i64>().unwrap();
- let dir = match dir {
- "U" => ( 0,-1),
- "D" => ( 0, 1),
- "L" => (-1, 0),
- "R" => ( 1, 0),
- other => panic!("Unknown direction: {}", other),
- };
- for _ in 0..mag {
- pos.0 += dir.0;
- pos.1 += dir.1;
- d += 1;
- if !wire.contains_key(&pos) { wire.insert(pos,d); }
- }
- }
- wires.push(wire.clone());
- // Merge this wire's intersection into global wire map
- for (pt,_) in wire {
- match wire_map.insert(pt,1) {
- Some(wire) => { wire_map.insert(pt,wire+1); },
- None => {},
- }
- }
- }
- // Part 1
- let part1 = wire_map
- .iter()
- .filter(|(_,v)| **v == 2)
- .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)))
- .map(|pt| manhattan_distance(0,0,(pt.0).0,(pt.0).1))
- .unwrap();
- println!("Part 1: {}", part1); // 1211
- // Part 2
- let mut part2 = std::u64::MAX;
- for intersect in wire_map.iter().filter(|(_,v)| **v == 2).map(|(k,_)| k) {
- let dist = wires
- .iter()
- .map(|x| x
- .iter()
- .filter(|(k,_)| k == &intersect)
- .map(|(_,v)| v).sum::<u64>())
- .sum();
- part2 = cmp::min(part2, dist);
- }
- println!("Part 2: {}", part2); // 101386
- Ok(())
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement