Prettify source code
This commit is contained in:
parent
63cb497325
commit
8eefcf7032
@ -24,8 +24,8 @@ pub(crate) fn dump_latex_code(route: &[RunState], polys: &[Polygon]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if route[route.len()-1].pos.y()/SCALE > ymax {
|
if route[route.len() - 1].pos.y() / SCALE > ymax {
|
||||||
ymax = route[route.len()-1].pos.y()/SCALE;
|
ymax = route[route.len() - 1].pos.y() / SCALE;
|
||||||
}
|
}
|
||||||
println!("\\begin{{tikzpicture}}");
|
println!("\\begin{{tikzpicture}}");
|
||||||
println!("\\tkzInit[xmax={},ymax={}]", xmax + 0.3, ymax + 0.3);
|
println!("\\tkzInit[xmax={},ymax={}]", xmax + 0.3, ymax + 0.3);
|
||||||
@ -58,10 +58,15 @@ pub(crate) fn dump_latex_code(route: &[RunState], polys: &[Polygon]) {
|
|||||||
println!(")");
|
println!(")");
|
||||||
}
|
}
|
||||||
for (idx, s) in route.iter().enumerate() {
|
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() {
|
for idx in 1..route.len() {
|
||||||
println!("\\tkzDrawSegment(R{},R{})", idx-1, idx);
|
println!("\\tkzDrawSegment(R{},R{})", idx - 1, idx);
|
||||||
}
|
}
|
||||||
for idx in 0..route.len() {
|
for idx in 0..route.len() {
|
||||||
println!("\\tkzDrawPoint[fill=red,color=black,size=13](R{})", idx);
|
println!("\\tkzDrawPoint[fill=red,color=black,size=13](R{})", idx);
|
||||||
|
78
src/main.rs
78
src/main.rs
@ -52,9 +52,6 @@ fn main() {
|
|||||||
let data = input::read_input();
|
let data = input::read_input();
|
||||||
let house = data.start;
|
let house = data.start;
|
||||||
let polys = data.polys;
|
let polys = data.polys;
|
||||||
for p in &polys {
|
|
||||||
assert!(p.interiors.is_empty());
|
|
||||||
}
|
|
||||||
// alle Ecken der Hindernisse bestimmen
|
// alle Ecken der Hindernisse bestimmen
|
||||||
let points = polys
|
let points = polys
|
||||||
.iter()
|
.iter()
|
||||||
@ -62,7 +59,7 @@ fn main() {
|
|||||||
.flatten()
|
.flatten()
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
// Startzustand
|
// Startzustand: Lisa ist an ihrem Haus, Bus noch nicht losgefahren
|
||||||
let start = RunState {
|
let start = RunState {
|
||||||
pos: house,
|
pos: house,
|
||||||
bus: bus,
|
bus: bus,
|
||||||
@ -71,62 +68,69 @@ fn main() {
|
|||||||
|
|
||||||
eprintln!("Maximum: {:?}", delay_to_time(start.delay));
|
eprintln!("Maximum: {:?}", delay_to_time(start.delay));
|
||||||
|
|
||||||
|
// Zustände in Max-Heap sortieren
|
||||||
let mut states = BinaryHeap::new();
|
let mut states = BinaryHeap::new();
|
||||||
states.push(vec![start]);
|
states.push(vec![start]);
|
||||||
|
|
||||||
|
// beste Lösung speichern
|
||||||
let mut best_delay = 0.0;
|
let mut best_delay = 0.0;
|
||||||
let mut best = vec![];
|
let mut best = vec![];
|
||||||
|
// Zwischenlösungen speichern
|
||||||
let save_prefix = "tmp_";
|
let save_prefix = "tmp_";
|
||||||
let mut save_counter = 0;
|
let mut save_counter = 0;
|
||||||
|
|
||||||
// weitersuchen, bis kein besserer Zustand mehr vorhanden ist
|
// weitersuchen, bis kein besserer Zustand mehr vorhanden ist
|
||||||
while states.peek().map(|x| x[0].delay > best_delay) == Some(true) {
|
while states.peek().map(|x| x[0].delay > best_delay) == Some(true) {
|
||||||
let s = states.pop().unwrap();
|
// besten Zustand einlesen
|
||||||
let last = &s[0];
|
let state = states.pop().unwrap();
|
||||||
|
let last = &state[0];
|
||||||
|
|
||||||
// neue Zustände
|
// neue Zustände
|
||||||
let mut all = vec![];
|
let mut all = vec![];
|
||||||
|
|
||||||
// versuche zu jeder anderen Ecke zu gehen
|
// versuche, zu jeder anderen Ecke zu gehen
|
||||||
for next in points
|
for next in points
|
||||||
.iter()
|
.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);
|
// Lisa könnte zu dieser Ecke rennen
|
||||||
if next != last.pos && none_intersect(&polys, &Line::new(last.pos, next)) {
|
let bus_next = last.bus.translate(0.0, distance(last.pos, next) * 2.0);
|
||||||
// Lisa könnte zu dieser Ecke rennen
|
let delay = max_possible_delay(bus_next, next);
|
||||||
let bus_next = last.bus.translate(0.0, distance(last.pos, next) * 2.0);
|
if delay > best_delay {
|
||||||
let delay = max_possible_delay(bus_next, next);
|
let mut route = state.clone();
|
||||||
if delay > best_delay {
|
route.insert(
|
||||||
let mut route = s.clone();
|
0,
|
||||||
route.insert(
|
RunState {
|
||||||
0,
|
pos: next,
|
||||||
RunState {
|
bus: bus_next,
|
||||||
pos: next,
|
delay,
|
||||||
bus: bus_next,
|
},
|
||||||
delay,
|
);
|
||||||
},
|
all.push(route);
|
||||||
);
|
|
||||||
all.push(route);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// versuche, direkt zum Bus zu gehen
|
// versuche, direkt zum Bus zu gehen
|
||||||
let bus = last.bus;
|
let bus = last.bus;
|
||||||
let range = to_bus(bus, last.pos);
|
let range = to_bus(bus, last.pos);
|
||||||
if range.len() == 2 {
|
if range.len() == 2 {
|
||||||
|
// Lisa trifft Bus mit 60°-Winkel
|
||||||
let next = Point::new(
|
let next = Point::new(
|
||||||
0.0,
|
0.0,
|
||||||
last.pos.y() + 30.0f64.to_radians().tan() * last.pos.x(),
|
last.pos.y() + 30.0f64.to_radians().tan() * last.pos.x(),
|
||||||
);
|
);
|
||||||
let line = Line::new(last.pos, next);
|
let line = Line::new(last.pos, next);
|
||||||
|
// freier Weg?
|
||||||
if none_intersect(&polys, &line) {
|
if none_intersect(&polys, &line) {
|
||||||
let delay = line.end.y
|
let delay = line.end.y
|
||||||
- bus.y() - line.end_point().euclidean_distance(&line.start_point())
|
- bus.y() - line.end_point().euclidean_distance(&line.start_point())
|
||||||
* 2.0;
|
* 2.0;
|
||||||
if delay > best_delay {
|
if delay > best_delay {
|
||||||
// neue beste Wartezeit
|
// neue beste Wartezeit
|
||||||
let mut route = s.clone();
|
let mut route = state.clone();
|
||||||
route.insert(
|
route.insert(
|
||||||
0,
|
0,
|
||||||
RunState {
|
RunState {
|
||||||
@ -135,8 +139,9 @@ fn main() {
|
|||||||
delay,
|
delay,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
// Verbesserung anzeigen und speichern
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"Verbesserung: {:?} ({:?} Zustände verbleiben)",
|
"Verbesserung: {:?} ({:?}+ Zustände verbleiben)",
|
||||||
delay_to_time(delay),
|
delay_to_time(delay),
|
||||||
states.len()
|
states.len()
|
||||||
);
|
);
|
||||||
@ -152,12 +157,16 @@ fn main() {
|
|||||||
save_counter += 1;
|
save_counter += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// falls Bus überhaupt noch erreicht wird: neu gefundene Routen speichern
|
||||||
states.extend(all);
|
states.extend(all);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let route = best;
|
let route = best;
|
||||||
eprintln!("Startzeit: {:?}", delay_to_time(best_delay));
|
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());
|
eprintln!("Treffpunkt: y={:.0}", route.last().unwrap().pos.y());
|
||||||
let mut length = 0.0;
|
let mut length = 0.0;
|
||||||
let mut last = &house;
|
let mut last = &house;
|
||||||
@ -168,7 +177,13 @@ fn main() {
|
|||||||
} else if s.pos.x() == 0.0 {
|
} else if s.pos.x() == 0.0 {
|
||||||
eprint!("Treffpunkt: ")
|
eprint!("Treffpunkt: ")
|
||||||
} else {
|
} 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());
|
eprintln!("x={:.02} y={:.02}", s.pos.x(), s.pos.y());
|
||||||
length += last.euclidean_distance(&s.pos);
|
length += last.euclidean_distance(&s.pos);
|
||||||
@ -177,7 +192,8 @@ fn main() {
|
|||||||
eprintln!("Länge: {:.0}m", length);
|
eprintln!("Länge: {:.0}m", length);
|
||||||
let seconds = length / (15.0 / 3.6);
|
let seconds = length / (15.0 / 3.6);
|
||||||
eprintln!("Dauer: {:02.0}:{:02.0}", seconds / 60.0, seconds % 60.0);
|
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 {
|
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
|
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> {
|
fn to_bus(bus: Point, start: Point) -> Vec<Point> {
|
||||||
let x_l = start.x();
|
let x_l = start.x();
|
||||||
let y_l = start.y();
|
let y_l = start.y();
|
||||||
|
Loading…
Reference in New Issue
Block a user