Prettify source code
This commit is contained in:
parent
63cb497325
commit
8eefcf7032
@ -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);
|
||||
|
52
src/main.rs
52
src/main.rs
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user