Prettify source code

This commit is contained in:
Arne Keller 2019-02-03 14:49:48 +01:00
parent 63cb497325
commit 8eefcf7032
2 changed files with 56 additions and 35 deletions

View File

@ -58,7 +58,12 @@ pub(crate) fn dump_latex_code(route: &[RunState], polys: &[Polygon]) {
println!(")");
}
for (idx, s) in route.iter().enumerate() {
println!("\\tkzDefPoint({},{}){{R{}}}", s.pos.x()/SCALE, s.pos.y()/SCALE, idx);
println!(
"\\tkzDefPoint({},{}){{R{}}}",
s.pos.x() / SCALE,
s.pos.y() / SCALE,
idx
);
}
for idx in 1..route.len() {
println!("\\tkzDrawSegment(R{},R{})", idx - 1, idx);

View File

@ -52,9 +52,6 @@ fn main() {
let data = input::read_input();
let house = data.start;
let polys = data.polys;
for p in &polys {
assert!(p.interiors.is_empty());
}
// alle Ecken der Hindernisse bestimmen
let points = polys
.iter()
@ -62,7 +59,7 @@ fn main() {
.flatten()
.collect::<Vec<_>>();
// Startzustand
// Startzustand: Lisa ist an ihrem Haus, Bus noch nicht losgefahren
let start = RunState {
pos: house,
bus: bus,
@ -71,34 +68,40 @@ fn main() {
eprintln!("Maximum: {:?}", delay_to_time(start.delay));
// Zustände in Max-Heap sortieren
let mut states = BinaryHeap::new();
states.push(vec![start]);
// beste Lösung speichern
let mut best_delay = 0.0;
let mut best = vec![];
// Zwischenlösungen speichern
let save_prefix = "tmp_";
let mut save_counter = 0;
// weitersuchen, bis kein besserer Zustand mehr vorhanden ist
while states.peek().map(|x| x[0].delay > best_delay) == Some(true) {
let s = states.pop().unwrap();
let last = &s[0];
// besten Zustand einlesen
let state = states.pop().unwrap();
let last = &state[0];
// neue Zustände
let mut all = vec![];
// versuche zu jeder anderen Ecke zu gehen
// versuche, zu jeder anderen Ecke zu gehen
for next in points
.iter()
.filter(|next| !s.iter().any(|x| x.pos == (**next).into()))
// Ecke sollte nicht schon in Route sein
.filter(|next| !state.iter().any(|p| p.pos == (**next).into()))
.map(|x| Point::from(*x))
// Weg zu dieser Ecke sollte kein Polygon schneiden
.filter(|next| none_intersect(&polys, &Line::new(last.pos, *next)))
{
let next = Point::from(*next);
if next != last.pos && none_intersect(&polys, &Line::new(last.pos, next)) {
// Lisa könnte zu dieser Ecke rennen
let bus_next = last.bus.translate(0.0, distance(last.pos, next) * 2.0);
let delay = max_possible_delay(bus_next, next);
if delay > best_delay {
let mut route = s.clone();
let mut route = state.clone();
route.insert(
0,
RunState {
@ -110,23 +113,24 @@ fn main() {
all.push(route);
}
}
}
// versuche, direkt zum Bus zu gehen
let bus = last.bus;
let range = to_bus(bus, last.pos);
if range.len() == 2 {
// Lisa trifft Bus mit 60°-Winkel
let next = Point::new(
0.0,
last.pos.y() + 30.0f64.to_radians().tan() * last.pos.x(),
);
let line = Line::new(last.pos, next);
// freier Weg?
if none_intersect(&polys, &line) {
let delay = line.end.y
- bus.y() - line.end_point().euclidean_distance(&line.start_point())
* 2.0;
if delay > best_delay {
// neue beste Wartezeit
let mut route = s.clone();
let mut route = state.clone();
route.insert(
0,
RunState {
@ -135,8 +139,9 @@ fn main() {
delay,
},
);
// Verbesserung anzeigen und speichern
eprintln!(
"Verbesserung: {:?} ({:?} Zustände verbleiben)",
"Verbesserung: {:?} ({:?}+ Zustände verbleiben)",
delay_to_time(delay),
states.len()
);
@ -152,12 +157,16 @@ fn main() {
save_counter += 1;
}
}
// falls Bus überhaupt noch erreicht wird: neu gefundene Routen speichern
states.extend(all);
}
}
let route = best;
eprintln!("Startzeit: {:?}", delay_to_time(best_delay));
eprintln!("Zielzeit: {:?}", delay_to_time(route.last().unwrap().bus.y() - bus_start.y()));
eprintln!(
"Zielzeit: {:?}",
delay_to_time(route.last().unwrap().bus.y() - bus_start.y())
);
eprintln!("Treffpunkt: y={:.0}", route.last().unwrap().pos.y());
let mut length = 0.0;
let mut last = &house;
@ -168,7 +177,13 @@ fn main() {
} else if s.pos.x() == 0.0 {
eprint!("Treffpunkt: ")
} else {
eprint!("Polygon {:02}: ", polys.iter().position(|p| p.exterior.0.contains(&s.pos.into())).unwrap() + 1);
eprint!(
"Polygon {:02}: ",
polys
.iter()
.position(|p| p.exterior.0.contains(&s.pos.into()))
.unwrap() + 1
);
}
eprintln!("x={:.02} y={:.02}", s.pos.x(), s.pos.y());
length += last.euclidean_distance(&s.pos);
@ -177,7 +192,8 @@ fn main() {
eprintln!("Länge: {:.0}m", length);
let seconds = length / (15.0 / 3.6);
eprintln!("Dauer: {:02.0}:{:02.0}", seconds / 60.0, seconds % 60.0);
display::dump_latex_code(&route, &polys);
// beste Route grafisch ausgeben
display::dump_svg(&route, &polys);
}
fn none_intersect(polys: &[Polygon], line: &Line) -> bool {
@ -228,7 +244,7 @@ fn max_possible_delay(bus: Point, start: Point) -> f64 {
y_l - (3.0 * x_l.powi(2)).sqrt() - y_b
}
// Go straight to the bus. Returns the points where the bus can be reached.
/// Gehe direkt zum Bus. Gibt die Punkte zurück, bei denen Lisa nicht auf den Bus warten müsste.
fn to_bus(bus: Point, start: Point) -> Vec<Point> {
let x_l = start.x();
let y_l = start.y();