Compare commits

...

1 commit

Author SHA1 Message Date
9d1d057e09 Refactor to struct and enumerate steps 2019-12-15 23:18:00 +01:00

View file

@ -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,50 @@ 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);
println!("{:?}", (c, other));
(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 +115,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));
}