Run rustfmt

This commit is contained in:
Arne Keller 2019-01-27 14:24:18 +01:00
parent af280353cc
commit 460e0749ad
4 changed files with 197 additions and 81 deletions

1
rustfmt.toml Normal file
View File

@ -0,0 +1 @@
hard_tabs = true

View File

@ -1,14 +1,20 @@
use svg::node::element::path::Data;
use svg::node::element::Path;
use svg::node::element::{AnimateMotion, Circle, MotionPath};
use svg::Document; use svg::Document;
use svg::Node; use svg::Node;
use svg::node::element::{AnimateMotion, MotionPath, Circle};
use svg::node::element::Path;
use svg::node::element::path::Data;
use std::io; use std::io;
use super::*; use super::*;
pub(crate) fn dump_svg(points: &[(Point, &'static str)], lines: &[(Line, &'static str)], polys: &[Polygon], route1: &[Point], route2_start: Point) { pub(crate) fn dump_svg(
points: &[(Point, &'static str)],
lines: &[(Line, &'static str)],
polys: &[Polygon],
route1: &[Point],
route2_start: Point,
) {
let mut document = Document::new() let mut document = Document::new()
// view box at (0, -200), w*h (200, 200) // view box at (0, -200), w*h (200, 200)
.set("viewBox", (0, -1100, 2100, 2100)) .set("viewBox", (0, -1100, 2100, 2100))
@ -45,8 +51,7 @@ pub(crate) fn dump_svg(points: &[(Point, &'static str)], lines: &[(Line, &'stati
let first = coords[0].x_y(); let first = coords[0].x_y();
let mut first: (f64, f64) = (first.0.into(), first.1.into()); let mut first: (f64, f64) = (first.0.into(), first.1.into());
first.1 *= -1.0; first.1 *= -1.0;
let mut data = Data::new() let mut data = Data::new().move_to(first);
.move_to(first);
for c in &coords[1..] { for c in &coords[1..] {
let c = c.x_y(); let c = c.x_y();
let mut c: (f64, f64) = (c.0.into(), c.1.into()); let mut c: (f64, f64) = (c.0.into(), c.1.into());
@ -66,8 +71,7 @@ pub(crate) fn dump_svg(points: &[(Point, &'static str)], lines: &[(Line, &'stati
let mut first: (f64, f64) = (route1[0].x().into(), route1[0].y().into()); let mut first: (f64, f64) = (route1[0].x().into(), route1[0].y().into());
first.1 *= -1.0; first.1 *= -1.0;
let mut data = Data::new() let mut data = Data::new().move_to(first);
.move_to(first);
for point in &route1[1..] { for point in &route1[1..] {
let c = point.x_y(); let c = point.x_y();
let mut c: (f64, f64) = (c.0.into(), c.1.into()); let mut c: (f64, f64) = (c.0.into(), c.1.into());
@ -87,7 +91,9 @@ pub(crate) fn dump_svg(points: &[(Point, &'static str)], lines: &[(Line, &'stati
.set("r", 25.2) .set("r", 25.2)
.set("opacity", 0.75) .set("opacity", 0.75)
.set("fill", "gray"); .set("fill", "gray");
let mut motion1 = AnimateMotion::new().set("dur", "2s").set("repeatCount", "indefinite"); let mut motion1 = AnimateMotion::new()
.set("dur", "2s")
.set("repeatCount", "indefinite");
let path = MotionPath::new().set("xlink:href", "#route1"); let path = MotionPath::new().set("xlink:href", "#route1");
motion1.append(path); motion1.append(path);
dot1.append(motion1); dot1.append(motion1);
@ -95,10 +101,9 @@ pub(crate) fn dump_svg(points: &[(Point, &'static str)], lines: &[(Line, &'stati
let mut first: (f64, f64) = (route2_start.x().into(), route2_start.y().into()); let mut first: (f64, f64) = (route2_start.x().into(), route2_start.y().into());
first.1 *= -1.0; first.1 *= -1.0;
let mut data = Data::new() let mut data = Data::new().move_to(first);
.move_to(first);
let last = route1.last().unwrap(); let last = route1.last().unwrap();
data = data.line_to::<(f64, f64)>((last.x().into(), (|x:f64|-x)(last.y().into()))); data = data.line_to::<(f64, f64)>((last.x().into(), (|x: f64| -x)(last.y().into())));
let path = Path::new() let path = Path::new()
.set("id", "route2") .set("id", "route2")
.set("fill", "none") .set("fill", "none")
@ -112,7 +117,9 @@ pub(crate) fn dump_svg(points: &[(Point, &'static str)], lines: &[(Line, &'stati
.set("r", 25.2) .set("r", 25.2)
.set("opacity", 0.75) .set("opacity", 0.75)
.set("fill", "gray"); .set("fill", "gray");
let mut motion1 = AnimateMotion::new().set("dur", "2s").set("repeatCount", "indefinite"); let mut motion1 = AnimateMotion::new()
.set("dur", "2s")
.set("repeatCount", "indefinite");
let path = MotionPath::new().set("xlink:href", "#route2"); let path = MotionPath::new().set("xlink:href", "#route2");
motion1.append(path); motion1.append(path);
dot1.append(motion1); dot1.append(motion1);

View File

@ -5,7 +5,7 @@ use std::io::prelude::*;
pub(crate) struct InputData { pub(crate) struct InputData {
pub start: Point, pub start: Point,
pub polys: Vec<Polygon> pub polys: Vec<Polygon>,
} }
pub(crate) fn read_input() -> InputData { pub(crate) fn read_input() -> InputData {
@ -23,30 +23,87 @@ fn read_stdin() -> InputData {
for _ in 0..polygon_count { for _ in 0..polygon_count {
let line = lines.next().unwrap(); let line = lines.next().unwrap();
let numbers = line.trim().split(' ').map(|x| x.parse::<usize>().unwrap()).collect::<Vec<_>>(); let numbers = line
.trim()
.split(' ')
.map(|x| x.parse::<usize>().unwrap())
.collect::<Vec<_>>();
let corner_count = numbers[0]; let corner_count = numbers[0];
polygons.push(Polygon::new((0..corner_count).map(|idx| ((numbers[idx*2+1] as f32).into(), (numbers[idx*2+2] as f32).into())).collect::<Vec<_>>().into(), vec![])); polygons.push(Polygon::new(
(0..corner_count)
.map(|idx| {
(
(numbers[idx * 2 + 1] as f32).into(),
(numbers[idx * 2 + 2] as f32).into(),
)
})
.collect::<Vec<_>>()
.into(),
vec![],
));
} }
let home = lines.next().unwrap().trim().split(' ').map(|x| x.parse::<f32>().unwrap().into()).collect::<Vec<_>>(); let home = lines
.next()
.unwrap()
.trim()
.split(' ')
.map(|x| x.parse::<f32>().unwrap().into())
.collect::<Vec<_>>();
InputData { InputData {
start: Point::new(home[0], home[1]), start: Point::new(home[0], home[1]),
polys: polygons polys: polygons,
} }
} }
fn custom_input() -> InputData { fn custom_input() -> InputData {
let mut polys = vec![]; let mut polys = vec![];
polys.push(Polygon::new(vec![[2.0.into(), 0.0.into()], [6.0.into(), 0.0.into()], [6.0.into(), 6.0.into()], [2.0.into(), 5.0.into()]].into(), vec![])); polys.push(Polygon::new(
polys.push(Polygon::new(vec![[1.0.into(), 20.0.into()], [2.0.into(), 20.0.into()], [2.0.into(), 23.0.into()], [1.0.into(), 23.0.into()]].into(), vec![])); vec![
polys.push(Polygon::new(vec![[1.0.into(), 25.0.into()], [2.0.into(), 25.0.into()], [2.0.into(), 28.0.into()], [1.0.into(), 28.0.into()]].into(), vec![])); [2.0.into(), 0.0.into()],
let mut stick = Polygon::new(vec![[1.0.into(), 115.0.into()], [2.0.into(), 115.0.into()], [2.0.into(), 130.0.into()], [1.0.into(), 130.0.into()]].into(), vec![]); [6.0.into(), 0.0.into()],
[6.0.into(), 6.0.into()],
[2.0.into(), 5.0.into()],
]
.into(),
vec![],
));
polys.push(Polygon::new(
vec![
[1.0.into(), 20.0.into()],
[2.0.into(), 20.0.into()],
[2.0.into(), 23.0.into()],
[1.0.into(), 23.0.into()],
]
.into(),
vec![],
));
polys.push(Polygon::new(
vec![
[1.0.into(), 25.0.into()],
[2.0.into(), 25.0.into()],
[2.0.into(), 28.0.into()],
[1.0.into(), 28.0.into()],
]
.into(),
vec![],
));
let mut stick = Polygon::new(
vec![
[1.0.into(), 115.0.into()],
[2.0.into(), 115.0.into()],
[2.0.into(), 130.0.into()],
[1.0.into(), 130.0.into()],
]
.into(),
vec![],
);
polys.push(stick.clone()); polys.push(stick.clone());
stick = stick.translate(35.0.into(), (-20.0).into()); stick = stick.translate(35.0.into(), (-20.0).into());
polys.push(stick); polys.push(stick);
InputData { InputData {
start: Point::new(45.0.into(), 95.0.into()), start: Point::new(45.0.into(), 95.0.into()),
polys polys,
} }
} }

View File

@ -1,4 +1,3 @@
use geo::*;
use geo::prelude::*; use geo::prelude::*;
use std::cmp; use std::cmp;
@ -22,7 +21,7 @@ struct RunState {
/// Our current location /// Our current location
pos: Point, pos: Point,
/// Current location of the bus, not including any delays /// Current location of the bus, not including any delays
bus: Point bus: Point,
} }
impl cmp::Eq for RunState {} impl cmp::Eq for RunState {}
impl cmp::Ord for RunState { impl cmp::Ord for RunState {
@ -37,7 +36,7 @@ impl cmp::PartialOrd for RunState {
} }
fn main() { fn main() {
let bus = Point::new(0.0.into(), (-2000.0).into()); let bus = Point::new(0.0, -2000.0);
let data = input::read_input(); let data = input::read_input();
let house = data.start; let house = data.start;
@ -46,19 +45,20 @@ fn main() {
eprintln!("{:?}", polys); eprintln!("{:?}", polys);
for p in &polys { for p in &polys {
assert!(p.interiors.is_empty()); assert!(p.interiors.is_empty());
//assert!(p.is_convex());
} }
let points = polys.iter().map(|x| x.exterior.0.clone()).flatten().collect::<Vec<_>>(); let points = polys
.iter()
.map(|x| x.exterior.0.clone())
.flatten()
.collect::<Vec<_>>();
let start = RunState { let start = RunState {
pos: house, pos: house,
bus: bus, bus: bus,
delay: max_possible_delay(bus, house) delay: max_possible_delay(bus, house),
//route: vec![house],
//length: 0.0.into()
}; };
eprintln!("# Max delay possible: {:?}", start.delay); eprintln!("# Max. delay possible: {:?}", start.delay);
let mut states = BinaryHeap::new(); let mut states = BinaryHeap::new();
states.push(vec![start]); states.push(vec![start]);
@ -68,18 +68,9 @@ fn main() {
while states.peek().map(|x| x[0].delay > best_delay) == Some(true) { while states.peek().map(|x| x[0].delay > best_delay) == Some(true) {
eprintln!(". {:?} states left:", states.len()); eprintln!(". {:?} states left:", states.len());
/*
if states.len() > 10 {
for s in &states {
eprintln!("{:?}", s);
}
panic!();
}
*/
let s = states.pop().unwrap(); let s = states.pop().unwrap();
let last = &s[0]; //s.last().unwrap(); let last = &s[0]; //s.last().unwrap();
eprintln!("{},{}", last.pos.x(), last.pos.y()); eprintln!("{},{}", last.pos.x(), last.pos.y());
//eprintln!("{:?}", states.peek());
// new states // new states
let mut all = vec![]; let mut all = vec![];
@ -92,11 +83,14 @@ fn main() {
let bus_next = last.bus.translate(0.0, distance(last.pos, next) * 2.0); let bus_next = last.bus.translate(0.0, distance(last.pos, next) * 2.0);
let mut route = s.clone(); let mut route = s.clone();
//eprintln!("{},{} would go {},{}", last.pos.x(), last.pos.y(), next.x(), next.y()); //eprintln!("{},{} would go {},{}", last.pos.x(), last.pos.y(), next.x(), next.y());
route.insert(0, RunState { route.insert(
0,
RunState {
pos: next, pos: next,
bus: bus_next, bus: bus_next,
delay: max_possible_delay(bus_next, next) delay: max_possible_delay(bus_next, next),
}); },
);
all.push(route); all.push(route);
} }
} }
@ -117,11 +111,14 @@ fn main() {
if delay > best_delay { if delay > best_delay {
// new high score! // new high score!
let mut route = s.clone(); let mut route = s.clone();
route.insert(0, RunState { route.insert(
0,
RunState {
pos: next, pos: next,
bus: next, bus: next,
delay delay,
}); },
);
eprintln!("# New best delay {:?}", delay); eprintln!("# New best delay {:?}", delay);
best = route; best = route;
best.reverse(); best.reverse();
@ -137,7 +134,6 @@ fn main() {
//eprintln!("-> adding all to queue"); //eprintln!("-> adding all to queue");
states.extend(all); states.extend(all);
} }
} }
eprintln!("d = {:?}", best_delay); eprintln!("d = {:?}", best_delay);
let route = best; let route = best;
@ -147,19 +143,33 @@ fn main() {
} }
let first = route.first().unwrap(); let first = route.first().unwrap();
let last = route.last().unwrap(); let last = route.last().unwrap();
let points = vec![(house, "red"), (first.bus.translate(0.0.into(), best_delay), "yellow"), (last.bus, "orange")]; let points = vec![
let lines = route.iter().map(|x| x.pos).collect::<LineString>().lines().map(|x| { (house, "red"),
(x, "gray") (first.bus.translate(0.0.into(), best_delay), "yellow"),
}).collect::<Vec<_>>(); (last.bus, "orange"),
];
let lines = route
.iter()
.map(|x| x.pos)
.collect::<LineString>()
.lines()
.map(|x| (x, "gray"))
.collect::<Vec<_>>();
display::dump_svg(&points, &lines, &polys, &route.iter().map(|x| x.pos).collect::<Vec<_>>(), first.bus.translate(0.0.into(), best_delay)); display::dump_svg(
&points,
&lines,
&polys,
&route.iter().map(|x| x.pos).collect::<Vec<_>>(),
first.bus.translate(0.0.into(), best_delay),
);
} }
/// [a; b] /// [a; b]
fn float_range(a: f32, b: f32) -> impl Iterator<Item = f32> { fn float_range(a: f32, b: f32) -> impl Iterator<Item = f32> {
const STEPS: usize = 25; const STEPS: usize = 25;
let d = b - a; let d = b - a;
(0..=STEPS).map(move |s| a + ((s as f32) * d)/STEPS as f32) (0..=STEPS).map(move |s| a + ((s as f32) * d) / STEPS as f32)
} }
fn none_intersect(polys: &[Polygon], line: &Line) -> bool { fn none_intersect(polys: &[Polygon], line: &Line) -> bool {
@ -178,12 +188,21 @@ fn none_intersect(polys: &[Polygon], line: &Line) -> bool {
middle.y += line.dy() / 2.0; middle.y += line.dy() / 2.0;
let middle: Point = middle.into(); let middle: Point = middle.into();
'poly: for p in polys { 'poly: for p in polys {
for l in p.exterior.lines().chain(vec![Line::new(p.exterior.0[0], *p.exterior.0.last().unwrap())]) { for l in p.exterior.lines().chain(vec![Line::new(
if (l.start == line.start && l.end == line.end) || (l.start == line.end && l.end == line.start) { p.exterior.0[0],
*p.exterior.0.last().unwrap(),
)]) {
if (l.start == line.start && l.end == line.end)
|| (l.start == line.end && l.end == line.start)
{
// point is on polygon border // point is on polygon border
continue 'poly; continue 'poly;
} }
if l.start == line.start || l.end == line.end || l.start == line.end || l.end == line.start { if l.start == line.start
|| l.end == line.end
|| l.start == line.end
|| l.end == line.start
{
/* /*
if line.end.x > 0.0 { if line.end.x > 0.0 {
eprintln!("skipping {:?}", l); eprintln!("skipping {:?}", l);
@ -238,7 +257,8 @@ fn to_bus(bus: Point, start: Point) -> Vec<Point> {
let c = bus.x(); let c = bus.x();
let d = bus.y(); let d = bus.y();
let v = -a.powi(2) * (3.0) + (6.0) * a * c + b.powi(2) - (2.0) * b * d - (3.0) * c.powi(2) + d.powi(2); let v = -a.powi(2) * (3.0) + (6.0) * a * c + b.powi(2) - (2.0) * b * d - (3.0) * c.powi(2)
+ d.powi(2);
if v >= 0.0 { if v >= 0.0 {
// v = sqrt(-3 A^2 + 6 A C + B^2 - 2 B D - 3 C^2 + D^2) // v = sqrt(-3 A^2 + 6 A C + B^2 - 2 B D - 3 C^2 + D^2)
let v = v.sqrt(); let v = v.sqrt();
@ -246,7 +266,10 @@ fn to_bus(bus: Point, start: Point) -> Vec<Point> {
let x1 = (v + 2.0 * b - 2.0 * d) / 3.0; let x1 = (v + 2.0 * b - 2.0 * d) / 3.0;
let x2 = (-v + 2.0 * b - 2.0 * d) / 3.0; let x2 = (-v + 2.0 * b - 2.0 * d) / 3.0;
if x1 > (0.0) && x2 > (0.0) { if x1 > (0.0) && x2 > (0.0) {
vec![bus.translate(0.0, (2.0) * x1), bus.translate(0.0, (2.0) * x2)] vec![
bus.translate(0.0, (2.0) * x1),
bus.translate(0.0, (2.0) * x2),
]
} else { } else {
vec![] vec![]
} }
@ -258,6 +281,34 @@ fn to_bus(bus: Point, start: Point) -> Vec<Point> {
#[cfg(test)] #[cfg(test)]
#[test] #[test]
fn test_to_bus() { fn test_to_bus() {
assert!(to_bus(Coordinate { x: 0.0.into(), y: 0.0.into() }.into(), Coordinate { x: 1.0.into(), y: 23.0.into() }.into()).len() == 2); assert!(
assert_eq!(to_bus(Coordinate { x: 0.0.into(), y: 168.7601848778319.into() }.into(), Coordinate { x: 1.0.into(), y: 23.0.into() }.into()), vec![]); to_bus(
Coordinate {
x: 0.0.into(),
y: 0.0.into()
}
.into(),
Coordinate {
x: 1.0.into(),
y: 23.0.into()
}
.into()
)
.len() == 2
);
assert_eq!(
to_bus(
Coordinate {
x: 0.0.into(),
y: 168.7601848778319.into()
}
.into(),
Coordinate {
x: 1.0.into(),
y: 23.0.into()
}
.into()
),
vec![]
);
} }