1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
use std::env;
use std::io::BufReader;
use std::io::BufRead;
use std::fs::File;
use std::process;
use std::io::{stdin,stdout,Write};
#[macro_use] extern crate text_io;
struct Point {
x: i64,
y: i64,
vx: i64,
vy: i64
}
struct BoundingBox {
x: i64,
y: i64,
w: i64,
h: i64
}
static WIDTH: i64 = 200;
static HEIGHT: i64 = 20;
fn visualize(points: &Vec<Point>, bb: &BoundingBox) {
let mut grid: Vec<Vec<char>> = vec![vec!['.'; bb.w as usize]; bb.h as usize];
for point in points {
let (xi, yi) = transform(point, bb);
grid[yi][xi] = '#';
}
for row in &grid {
for elem in row {
print!("{}", elem);
}
print!("\n");
}
}
fn state(points: &Vec<Point>, time: i64) -> Vec<Point> {
points.iter().map(|p| Point {
x: p.x + time * p.vx,
y: p.y + time * p.vy,
vx: p.vx,
vy: p.vy
}).collect()
}
fn transform(point: &Point, bb: &BoundingBox) -> (usize, usize) {
let x = point.x - bb.x;
let y = point.y - bb.y;
(x as usize, y as usize)
}
fn calc_bounding_box(points: &Vec<Point>) -> BoundingBox {
let px_min = points.iter().min_by(|&a, &b| a.x.cmp(&b.x)).unwrap().x;
let px_max = points.iter().max_by(|&a, &b| a.x.cmp(&b.x)).unwrap().x;
let py_min = points.iter().min_by(|&a, &b| a.y.cmp(&b.y)).unwrap().y;
let py_max = points.iter().max_by(|&a, &b| a.y.cmp(&b.y)).unwrap().y;
let pw = px_max - px_min + 1;
let ph = py_max - py_min + 1;
let bb = BoundingBox {
x: px_min,
y: py_min,
w: pw,
h: ph
};
bb
}
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
println!("Wrong number of arguments. Provide a file name and worker count.");
process::exit(1);
}
let filename = &args[1];
println!("Using file {} as input.", filename);
let f = match File::open(filename) {
Ok(file) => file,
Err(e) => {
println!("Failed to open file {}. {:?}", filename, e);
process::exit(1);
}
};
let file = BufReader::new(&f);
let lines: Vec<String> = file.lines()
.map(|line| line.expect("Could not parse line."))
.collect();
let mut init_points: Vec<Point> = Vec::new();
for line in &lines {
let ln = line
.replace("< ", "<")
.replace(" ", " ");
let (x, y): (i64, i64);
let (vx, vy): (i64, i64);
scan!(ln.bytes() => "position=<{}, {}> velocity=<{}, {}>", x, y, vx, vy);
init_points.push(Point { x, y, vx, vy });
}
let mut time = 0;
let step = 1;
// println!("Time: {} s, step: {} s", time, step);
while time < 20000 {
let points = state(&init_points, time);
let bb = calc_bounding_box(&points);
if bb.w <= WIDTH && bb.h <= HEIGHT {
println!("Time: {} s", time);
visualize(&points, &bb);
}
time += step;
}
}
|