@_CG_ClementHammel
Top level code
use std::io;
// Previously this would be repeated every time
fn read_line() -> String {
let mut input_line = String::new();
io::stdin().read_line(&mut input_line).unwrap();
input_line.trim_end_matches('\n').to_owned()
}
// I have no idea how booleans were previously handled,
// so here's a somewhat hacky solution,
// the braces are necessary to make {bool} not a type
macro_rules! parse_input {
($x:expr, {bool}) => {
$x == "1"
};
($x:expr, $t:ty) => {
$x.parse::<$t>().unwrap()
}
}
// Possibly unnecessary
macro_rules! read_parse {
($($i:ident: $t:tt),*) => {
let input_line = read_line();
let mut inputs = input_line.split(' ');
$(
let $i = parse_input!{inputs.next().unwrap(), $t};
)*
}
}
read v:string
let v = read_line();
Previously it was already a special case (input_line.trim_matches('\n').to_string()
) so this is an improvement.
read <variable sequence>
Two examples:
/* read a:int */
read_parse!{a:i32};
/* read b:float c:long d:word(32) e:bool */
read_parse!{b:f32, c:i64, d:String, e:{bool}};
Types are the same, except bool
; by default there would a ParseBoolError
. An actual implementation would use more line breaks so that comments can be added.
read_parse
feels a little bit extra. It expands to
let input_line = read_line();
let mut inputs = input_line.split(' ');
let b = parse_input!(inputs.next().unwrap(), f32);
let c = parse_input!(inputs.next().unwrap(), i64);
let d = parse_input!(inputs.next().unwrap(), String);
//etc
for speed, but if read_parse
isnāt used then really the old version (+read_line
) is better
let input_line = read_line();
let inputs = input_line.split(' ').collect::<Vec<_>>();
let b = parse_input!(inputs[0], f32);
let c = parse_input!(inputs[1], i64);
let d = parse_input!(inputs[2], String);
//etc
The old solution uses split(" ")
but classically, this causes a clippy::perf::single_char_pattern lint which says to use split(' ')
because itās faster (50% faster but by nanoseconds).
let input_line = read_line();
canāt be inlined ugh
gameloop
same as before
loop { /* stuff */ }
loop <amount> <command>
same as before
for i in 0..v as usize {
/* stuff */
}
loopline <amount> <variable sequence>
let inputs = read_line();
// prev
for i in inputs.split_whitespace() {
let state = parse_input!(i, i32);
}
// now
for i in inputs.split(' ') {
let state = parse_input!(i, i32);
}
write
same as before
another thing (Rust debug optimizations)
Separately, really want to mention thereās a way to compile in optimized debug mode, with all the debug features!
Simply
[profile.dev]
opt-level = 3
in the Cargo.toml
https://doc.rust-lang.org/cargo/reference/profiles.html
Edit: Turns out itās always in (non-optimized) debug mode even when submitting.