Skip to content

Commit 94e1640

Browse files
committed
Merge pull request #8 from Signez/rust
Add a simple Rust version to the mix
2 parents efb4234 + b51842b commit 94e1640

File tree

4 files changed

+142
-0
lines changed

4 files changed

+142
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ csa_hs
44
csa_cpp
55
csa_go
66
*.class
7+
target/
8+
Cargo.lock

Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "csa_rs"
3+
version = "0.1.0"
4+
authors = ["Stanislas Signoud <[email protected]>"]
5+
6+
[[bin]]
7+
name = "csa_rs"
8+
path = "csa.rs"
9+

csa.rs

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
use std::io;
2+
use std::iter::repeat;
3+
4+
const MAX_STATIONS: usize = 100000;
5+
6+
#[derive(Debug)]
7+
struct Connection {
8+
departure_station: usize,
9+
arrival_station: usize,
10+
departure_timestamp: u32,
11+
arrival_timestamp: u32
12+
}
13+
14+
impl Connection {
15+
fn parse(line: &str) -> Connection {
16+
let mut splitted = line.split(" ").map(|bite| { bite.parse::<u32>().unwrap() });
17+
18+
Connection {
19+
departure_station: splitted.next().unwrap() as usize,
20+
arrival_station: splitted.next().unwrap() as usize,
21+
departure_timestamp: splitted.next().unwrap(),
22+
arrival_timestamp: splitted.next().unwrap(),
23+
}
24+
}
25+
}
26+
27+
fn csa_main_loop(timetable: &[Connection], arrival_station: usize, earliest_arrival: &mut [u32], in_connection: &mut [usize]) {
28+
let mut earliest = std::u32::MAX;
29+
30+
for (i, connection) in timetable.iter().enumerate() {
31+
if connection.departure_timestamp >= earliest_arrival[connection.departure_station] &&
32+
connection.arrival_timestamp < earliest_arrival[connection.arrival_station] {
33+
earliest_arrival[connection.arrival_station] = connection.arrival_timestamp;
34+
in_connection[connection.arrival_station] = i;
35+
36+
if connection.arrival_station == arrival_station && connection.arrival_timestamp < earliest {
37+
earliest = connection.arrival_timestamp;
38+
}
39+
} else if connection.arrival_timestamp > earliest {
40+
break;
41+
}
42+
}
43+
}
44+
45+
fn csa_print_result(timetable: &Vec<Connection>, in_connection: &[usize], arrival_station: usize) {
46+
if in_connection[arrival_station] == std::u32::MAX as usize {
47+
println!("NO_SOLUTION");
48+
} else {
49+
let mut route = Vec::new();
50+
let mut last_connection_index = in_connection[arrival_station];
51+
52+
while last_connection_index != std::u32::MAX as usize {
53+
let ref connection = timetable[last_connection_index];
54+
route.push(connection);
55+
last_connection_index = in_connection[connection.departure_station];
56+
}
57+
58+
for connection in route.iter().rev() {
59+
println!("{} {} {} {}", connection.departure_station, connection.arrival_station, connection.departure_timestamp, connection.arrival_timestamp);
60+
}
61+
}
62+
println!("");
63+
}
64+
65+
fn csa_compute(timetable: &Vec<Connection>, departure_station: usize, arrival_station: usize, departure_time: u32)
66+
{
67+
let mut in_connection = Vec::new();
68+
in_connection.extend(repeat(std::u32::MAX as usize).take(MAX_STATIONS));
69+
let mut earliest_arrival = Vec::new();
70+
earliest_arrival.extend(repeat(std::u32::MAX).take(MAX_STATIONS));
71+
72+
earliest_arrival[departure_station as usize] = departure_time;
73+
74+
if departure_station < MAX_STATIONS && arrival_station < MAX_STATIONS {
75+
csa_main_loop(&timetable, arrival_station, &mut earliest_arrival, &mut in_connection);
76+
}
77+
78+
csa_print_result(&timetable, &in_connection, arrival_station);
79+
}
80+
81+
fn main() {
82+
let mut timetable = Vec::<Connection>::new();
83+
84+
// Importing connections
85+
86+
loop {
87+
let raw_line = {
88+
let mut line = String::new();
89+
io::stdin().read_line(&mut line).ok().expect("failed to read connection line");
90+
line
91+
};
92+
let input_line = raw_line.trim_right();
93+
94+
if input_line.is_empty() {
95+
break;
96+
} else {
97+
timetable.push(Connection::parse(input_line));
98+
};
99+
}
100+
101+
// Responding to requests from stdin
102+
103+
loop {
104+
let raw_line = {
105+
let mut line = String::new();
106+
io::stdin().read_line(&mut line).ok().expect("failed to read connection line");
107+
line
108+
};
109+
let input_line = raw_line.trim_right();
110+
111+
if input_line.is_empty() {
112+
break;
113+
} else {
114+
let params = input_line.split(" ")
115+
.map(|bite| { bite.parse().ok().expect(&format!("failed to read {} as integer", bite)) })
116+
.collect::<Vec<u32>>();
117+
118+
let departure_station = params[0] as usize;
119+
let arrival_station = params[1] as usize;
120+
let departure_time = params[2];
121+
122+
csa_compute(&timetable, departure_station, arrival_station, departure_time);
123+
}
124+
}
125+
}

readme.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,12 @@ Run the test with ```ruby test.rb "java CSA"```
129129

130130
Run the test with ```ruby test.rb "luajit csa.lua"```
131131

132+
## Rust implementation
133+
134+
Build: ```cargo build --release```
135+
136+
Run the test with ```ruby test.rb ./target/release/csa_rs```
137+
132138
## Challenge
133139

134140
Try to write:

0 commit comments

Comments
 (0)