Rust

Premise

At to date, HackerRank does not give you anything more than a Write you code here. If you take into account that the version of the compiler is a bit old, it is a bit slow to compile, no completion or rustfmt… It is not exactly a pleasure to code in Rust on HackerRank.

So… let’s open your favorite IDE/Editor on steroids and copy-paste your solution to HR! You can also try The Rust Playground! :wink:

A starting point

Maybe the empty prompt is a bit… too empty. Here something better:

 1 2 3 4 5 6 7 8 fn main() { use std::io; let stdin = io::stdin(); let mut stdin_lock = stdin.lock(); // Play with your stdin_lock! }

Reading an array of N elements

A classic: the first line contains N, the number of elements. The next line contains N space-separated integers.

Let’s try the easy way:

 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 fn main() { use std::io::{self, BufRead}; let stdin = io::stdin(); let mut lines = stdin.lock().lines().map(Result::unwrap); let n_elements: usize = lines.next().unwrap().parse().unwrap(); let elements: Vec = lines .next() .unwrap() .split(' ') .map(|x| x.parse().unwrap()) .collect(); assert_eq!(n_elements, elements.len()); }

Ouch! In real-life problems, Rust’s explicit error handling is awesome, but in this case it is just cumbersome.

We can write down a small set of utility functions, that can help us in many HR exercises. Here a practical example:

 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 use std::{fmt::Debug, iter::FromIterator, str::FromStr}; fn parse_line_into(lines: &mut L) -> T where L: Iterator, T: FromStr, ::Err: Debug, { lines.next().unwrap().parse().unwrap() } fn next_parsed_line(lines: &mut L) -> C where L: Iterator, C: FromIterator, T: FromStr, ::Err: Debug, { lines .next() .unwrap() .split(' ') .map(|x| x.parse().unwrap()) .collect() }

It is a bit of boilerplate, but it can be easily reusable. And the main becomes cleaner:

 1 2 3 4 5 6 7 8 9 10 11 12 fn main() { use std::io::{self, BufRead}; let stdin = io::stdin(); let mut lines = stdin.lock().lines().map(Result::unwrap); let n_elements: usize = parse_line_into(&mut lines); let elements: Vec = next_parsed_line(&mut lines); assert_eq!(n_elements, elements.len()); // Use elements! }

Collect all the things!!!

Remember that most of the time collect is your friend! Do you need to collect numbers in a BTreeSet?

 1 let elements: BTreeSet = next_parsed_line(&mut lines);

Easy!!!

Output

In Rust, printing is pretty easy thanks to println! macro:

 1 2 3 4 println!("This is a string: {}", the_string); println!("This is a vector, debug style: {:?}", the_vec); println!("This is a pretty printed vector: {:#?}", the_vec); println!("This is a float with 16 precision digits: {:.16}", the_float);