Last active
December 3, 2019 12:14
-
-
Save hellow554/6b66f62fc5d9efffc3a2c1ab57847c13 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::collections::{HashMap, HashSet}; | |
const INPUT: &str = include_str!("../input"); | |
#[derive(Clone)] | |
enum Movement { | |
Up, | |
Down, | |
Left, | |
Right, | |
} | |
use Movement::*; // never do this in production, kids! | |
type Wire = Vec<Movement>; | |
fn parse(s: &str) -> Vec<Wire> { | |
s.lines() | |
.map(|l| { | |
l.split(',') | |
.flat_map(|v| { | |
let mov = match &v[..1] { | |
"U" => Up, | |
"D" => Down, | |
"L" => Left, | |
"R" => Right, | |
_ => unreachable!(), | |
}; | |
vec![mov; v[1..].parse().unwrap()] | |
}) | |
.collect() | |
}) | |
.collect() | |
} | |
fn solve_a(wires: &[Wire]) -> i32 { | |
// grids is a Vec<HashSet<(i32, i32)>> | |
// in each hashset we insert the position a wire has | |
// in the end we just calculate the intersection and calculate | |
// the manhatten distance to origin (0, 0) | |
let grids = wires | |
.iter() | |
.map(|wire| { | |
wire.iter() | |
.scan((0_i32, 0_i32), |a, mov| { | |
match mov { | |
Right => a.0 += 1, | |
Left => a.0 -= 1, | |
Up => a.1 += 1, | |
Down => a.1 -= 1, | |
} | |
Some(*a) | |
}) | |
.collect::<HashSet<_>>() | |
}) | |
.collect::<Vec<_>>(); | |
assert_eq!(grids.len(), 2); | |
let hs = grids[0].intersection(&grids[1]); | |
hs.map(|x| x.0.abs() + x.1.abs()).min().unwrap() | |
} | |
fn solve_b(wires: &[Wire]) -> i32 { | |
// similar to `solve_a`, but in this case our Hashset contains a | |
// triple where the third value is the signal delay | |
let grids = wires | |
.iter() | |
.map(|wire| { | |
wire.iter() | |
.enumerate() | |
.scan((0_i32, 0_i32), |a, (step, mov)| { | |
match mov { | |
Right => a.0 += 1, | |
Left => a.0 -= 1, | |
Up => a.1 += 1, | |
Down => a.1 -= 1, | |
} | |
Some((a.0, a.1, step)) | |
}) | |
.collect::<HashSet<_>>() | |
}) | |
.collect::<Vec<_>>(); | |
// in step two we only take the min signal delays in account | |
// and then convert it into a hashmap | |
let mut grids = grids | |
.into_iter() | |
.map(|grid| { | |
let mut new_grid: HashMap<_, usize> = HashMap::new(); | |
for (x, y, s) in grid { | |
new_grid | |
.entry((x, y)) | |
.and_modify(|entry| *entry = s.min(*entry)) | |
.or_insert(s); | |
} | |
new_grid | |
}) | |
.collect::<Vec<_>>(); | |
// last step, do a insersect (`g2.get(_)?`) and then calculate the minimum signal delay | |
assert_eq!(2, grids.len()); | |
let (g2, g1) = (grids.pop().unwrap(), grids.pop().unwrap()); | |
g1.into_iter() | |
.filter_map(|x| Some((x, (x.0, *g2.get(&x.0)?)))) | |
.map(|(e1, e2)| { | |
// +2 because we don't take origin into account | |
// in our original calculation (+1 for each wire) | |
e1.1 + e2.1 + 2 | |
}) | |
.min() | |
.unwrap() as i32 | |
} | |
fn main() { | |
let input = parse(INPUT); | |
println!("A: {}", solve_a(&input)); | |
println!("B: {}", solve_b(&input)); | |
} | |
#[test] | |
fn ta() { | |
let input = "R8,U5,L5,D3 | |
U7,R6,D4,L4"; | |
let input = parse(input); | |
assert_eq!(solve_a(&input), 6); | |
let input = "R75,D30,R83,U83,L12,D49,R71,U7,L72 | |
U62,R66,U55,R34,D71,R55,D58,R83"; | |
let input = parse(input); | |
assert_eq!(solve_a(&input), 159); | |
let input = "R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51 | |
U98,R91,D20,R16,D67,R40,U7,R15,U6,R7"; | |
let input = parse(input); | |
assert_eq!(solve_a(&input), 135); | |
} | |
#[test] | |
fn tb() { | |
let input = "R8,U5,L5,D3 | |
U7,R6,D4,L4"; | |
let input = parse(input); | |
assert_eq!(solve_b(&input), 30); | |
let input = "R75,D30,R83,U83,L12,D49,R71,U7,L72 | |
U62,R66,U55,R34,D71,R55,D58,R83"; | |
let input = parse(input); | |
assert_eq!(solve_b(&input), 610); | |
let input = "R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51 | |
U98,R91,D20,R16,D67,R40,U7,R15,U6,R7"; | |
let input = parse(input); | |
assert_eq!(solve_b(&input), 410); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment