Hello,
I’m very new to rust.
Solving the bottle song exercice, I was curious about building verses in parallel.
I used into_par_iter and added something to print in threads to verify it’s printed in a nearly random order :
Here is the test: (I’ll past the full code at the end)
let millis = time::Duration::from_millis(bottles as u64 * 30);
thread::sleep(millis);
println!("recite_verse {}", bottles);
However I get some incoherent outputs.
For the “All verses” test (input 10,10) for example, I get :
recite_verse 5
recite_verse 4
recite_verse 10
recite_verse 3
recite_verse 2
recite_verse 1
recite_verse 9
recite_verse 8
recite_verse 7
recite_verse 6
recite_verse 10
recite_verse 9
It’s like verse 10 and 9 are built two times.
But the final song is correct so I guess it’s a printing issue. (I just altered it a bit for the test to fail and have an output)
I checked on forums it seems println is “synchronized” So I wonder what is happening. Does someone have an idea?
The full code :
use rayon::prelude::*;
use std::{thread, time};
fn in_english(number : u32) -> &'static str {
static NUMBERS_AS_WORDS: [&str; 11] = [
"No",
"One",
"Two",
"Three",
"Four",
"Five",
"Six",
"Seven",
"Eight",
"Nine",
"Ten",
];
NUMBERS_AS_WORDS[number as usize]
}
fn write_bottles(bottles: u32) -> String {
format!("bottle{}", if bottles == 1 {""} else {"s"})
}
fn recite_first_sentence(bottles: u32) -> String {
format!("{} green {} hanging on the wall,\n", in_english(bottles), write_bottles(bottles))
}
fn recite_last_sentence(bottles: u32) -> String {
format!("There'll be {} green {} hanging on the wall.",
in_english(bottles-1).to_lowercase(),
write_bottles(bottles-1)
)
}
fn recite_verse(bottles: u32) -> String {
//TEST here
let millis = time::Duration::from_millis(bottles as u64 * 30);
thread::sleep(millis);
println!("recite_verse {}", bottles);
format!("{first_sentence}\
{first_sentence}\
WRONG And if one green bottle should accidentally fall,\n\
{last_sentence}",
first_sentence = recite_first_sentence(bottles),
last_sentence = recite_last_sentence(bottles))
}
pub fn recite(start_bottles: u32, take_down: u32) -> String {
((start_bottles-take_down+1)..start_bottles+1)
.into_par_iter()
.rev()
.map(recite_verse)
.collect::<Vec<String>>()
.join("\n\n")
}
Thanks for your help