I have setup the docker container to run the model evaluation.
Write a self-contained Rust program that prints a JSON output of how often each word appears in a text file located in /tmp/file.txt. So if the file contains "This is is is, an example" then the program should print to stdout. {"This": 1, "is": 2, "is,": 1, "an": 1, "example": 1} Don't import any crates that would require a Cargo.toml file. I'll just compile it with `rustc yourfile.rs` and it should work. The program should be run by calling /path/to/rust_word_count with no arguments. Make it run in parallel on 4 cores at the same time, each job taking ~1/4 of the file. Print out 4 differnt json dicts, one per line. I'll do the merging. Do not import serde_json, write json output from scratch.
Write a self-contained Rust program that prints a JSON output of how often each word appears in a text file located in /tmp/file.txt. So if the file contains "This is is is, an example" then the program should print to stdout. {"This": 1, "is": 2, "is,": 1, "an": 1, "example": 1} Don't import any crates that would require a Cargo.toml file. I'll just compile it with `rustc yourfile.rs` and it should work. The program should be run by calling /path/to/rust_word_count with no arguments. Make it run in parallel on 4 cores at the same time, each job taking ~1/4 of the file. Print out 4 differnt json dicts, one per line. I'll do the merging. Do not import serde_json, write json output from scratch.
Here's a Rust program that meets your requirements:
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 | use std::fs::File; use std::io::{Read, BufReader}; use std::collections::HashMap; use std::thread; use std::sync::{Arc, Mutex}; fn count_words(text: &str) -> HashMap<String, usize> { let mut word_counts = HashMap::new(); let cleaned_text = text.replace(|c: char| !c.is_alphanumeric() && c != ' ', " "); for word in cleaned_text.split_whitespace() { let cleaned_word = word.trim().to_lowercase(); *word_counts.entry(cleaned_word).or_insert(0) += 1; } word_counts } fn json_from_map(map: &HashMap<String, usize>) -> String { let mut json = "{".to_string(); let mut first = true; for (word, count) in map { if !first { json.push_str(", "); } json.push_str(&format!("\"{}\":{}", word, count)); first = false; } json.push_str("}"); json } fn main() -> std::io::Result<()> { let file = File::open("/tmp/file.txt")?; let mut reader = BufReader::new(file); let mut contents = String::new(); reader.read_to_string(&mut contents)?; let file_length = contents.len(); let chunk_size = file_length / 4; let results = Arc::new(Mutex::new(Vec::new())); let mut handles = vec![]; for i in 0..4 { let start = i * chunk_size; let end = if i == 3 { file_length } else { (i + 1) * chunk_size }; let chunk = contents[start..end].to_string(); let results_clone = Arc::clone(&results); let handle = thread::spawn(move || { let word_counts = count_words(&chunk); let json = json_from_map(&word_counts); let mut results = results_clone.lock().unwrap(); results.push(json); }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } let final_results = results.lock().unwrap(); for result in final_results.iter() { println!("{}", result); } Ok(()) } |
1 2 | rustc word_count.rs
./word_count
|
I extracted the following code from that output:
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 | use std::fs::File; use std::io::{Read, BufReader}; use std::collections::HashMap; use std::thread; use std::sync::{Arc, Mutex}; fn count_words(text: &str) -> HashMap<String, usize> { let mut word_counts = HashMap::new(); let cleaned_text = text.replace(|c: char| !c.is_alphanumeric() && c != ' ', " "); for word in cleaned_text.split_whitespace() { let cleaned_word = word.trim().to_lowercase(); *word_counts.entry(cleaned_word).or_insert(0) += 1; } word_counts } fn json_from_map(map: &HashMap<String, usize>) -> String { let mut json = "{".to_string(); let mut first = true; for (word, count) in map { if !first { json.push_str(", "); } json.push_str(&format!("\"{}\":{}", word, count)); first = false; } json.push_str("}"); json } fn main() -> std::io::Result<()> { let file = File::open("/tmp/file.txt")?; let mut reader = BufReader::new(file); let mut contents = String::new(); reader.read_to_string(&mut contents)?; let file_length = contents.len(); let chunk_size = file_length / 4; let results = Arc::new(Mutex::new(Vec::new())); let mut handles = vec![]; for i in 0..4 { let start = i * chunk_size; let end = if i == 3 { file_length } else { (i + 1) * chunk_size }; let chunk = contents[start..end].to_string(); let results_clone = Arc::clone(&results); let handle = thread::spawn(move || { let word_counts = count_words(&chunk); let json = json_from_map(&word_counts); let mut results = results_clone.lock().unwrap(); results.push(json); }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } let final_results = results.lock().unwrap(); for result in final_results.iter() { println!("{}", result); } Ok(()) } |
Below is some student's code. I asked them to parallelize some code. Do not judge if it is correct, I have test cases for that. Logic errors are okay. So are synatx errors. Just tell me if they tried to parallelize it. use std::fs::File; use std::io::{Read, BufReader}; use std::collections::HashMap; use std::thread; use std::sync::{Arc, Mutex}; fn count_words(text: &str) -> HashMap<String, usize> { let mut word_counts = HashMap::new(); let cleaned_text = text.replace(|c: char| !c.is_alphanumeric() && c != ' ', " "); for word in cleaned_text.split_whitespace() { let cleaned_word = word.trim().to_lowercase(); *word_counts.entry(cleaned_word).or_insert(0) += 1; } word_counts } fn json_from_map(map: &HashMap<String, usize>) -> String { let mut json = "{".to_string(); let mut first = true; for (word, count) in map { if !first { json.push_str(", "); } json.push_str(&format!("\"{}\":{}", word, count)); first = false; } json.push_str("}"); json } fn main() -> std::io::Result<()> { let file = File::open("/tmp/file.txt")?; let mut reader = BufReader::new(file); let mut contents = String::new(); reader.read_to_string(&mut contents)?; let file_length = contents.len(); let chunk_size = file_length / 4; let results = Arc::new(Mutex::new(Vec::new())); let mut handles = vec![]; for i in 0..4 { let start = i * chunk_size; let end = if i == 3 { file_length } else { (i + 1) * chunk_size }; let chunk = contents[start..end].to_string(); let results_clone = Arc::clone(&results); let handle = thread::spawn(move || { let word_counts = count_words(&chunk); let json = json_from_map(&word_counts); let mut results = results_clone.lock().unwrap(); results.push(json); }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } let final_results = results.lock().unwrap(); for result in final_results.iter() { println!("{}", result); } Ok(()) } Answer either 'The student passes' or 'The student fails'.
The student passes.
Testing if the previous output contains the string student passes
: True
Running the following program:
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 | use std::fs::File; use std::io::{Read, BufReader}; use std::collections::HashMap; use std::thread; use std::sync::{Arc, Mutex}; fn count_words(text: &str) -> HashMap<String, usize> { let mut word_counts = HashMap::new(); let cleaned_text = text.replace(|c: char| !c.is_alphanumeric() && c != ' ', " "); for word in cleaned_text.split_whitespace() { let cleaned_word = word.trim().to_lowercase(); *word_counts.entry(cleaned_word).or_insert(0) += 1; } word_counts } fn json_from_map(map: &HashMap<String, usize>) -> String { let mut json = "{".to_string(); let mut first = true; for (word, count) in map { if !first { json.push_str(", "); } json.push_str(&format!("\"{}\":{}", word, count)); first = false; } json.push_str("}"); json } fn main() -> std::io::Result<()> { let file = File::open("/tmp/file.txt")?; let mut reader = BufReader::new(file); let mut contents = String::new(); reader.read_to_string(&mut contents)?; let file_length = contents.len(); let chunk_size = file_length / 4; let results = Arc::new(Mutex::new(Vec::new())); let mut handles = vec![]; for i in 0..4 { let start = i * chunk_size; let end = if i == 3 { file_length } else { (i + 1) * chunk_size }; let chunk = contents[start..end].to_string(); let results_clone = Arc::clone(&results); let handle = thread::spawn(move || { let word_counts = count_words(&chunk); let json = json_from_map(&word_counts); let mut results = results_clone.lock().unwrap(); results.push(json); }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } let final_results = results.lock().unwrap(); for result in final_results.iter() { println!("{}", result); } Ok(()) } |
{"it":4, "incredulity":1, "light":1, "the":3, "belief":1, "season":1, "was":4, "th":1, "epoch":2, "of":3, "ness":1}
{"foolish":1, "it":4, "was":4, "best":1, "of":4, "times":2, "age":2, "worst":1, "wisdom":1, "the":4}
{"before":1, "going":2, "the":1, "nothing":1, "all":2, "us":2, "other":1, "we":3, "were":2, "way":1, "to":1, "had":1, "heaven":1, "direct":2}
{"everything":1, "darkness":1, "before":1, "season":1, "winter":1, "we":1, "of":3, "the":2, "e":1, "had":1, "spring":1, "was":2, "it":2, "hope":1, "despair":1}
Resulting in output: [('age', 2), ('all', 2), ('before', 2), ('belief', 1), ('best', 1), ('darkness', 1), ('despair', 1), ('direct', 2), ('e', 1), ('epoch', 2), ('everything', 1), ('foolish', 1), ('going', 2), ('had', 2), ('heaven', 1), ('hope', 1), ('incredulity', 1), ('it', 10), ('light', 1), ('ness', 1), ('nothing', 1), ('of', 10), ('other', 1), ('season', 2), ('spring', 1), ('th', 1), ('the', 10), ('times', 2), ('to', 1), ('us', 2), ('was', 10), ('way', 1), ('we', 4), ('were', 2), ('winter', 1), ('wisdom', 1), ('worst', 1)]
Testing if the previous output equals the string [('Darkness,', 1), ('Heaven,', 1), ('Light,', 1), ('age', 2), ('all', 2), ('before', 2), ('belief,', 1), ('best', 1), ('despair,', 1), ('direct', 2), ('epoch', 2), ('everything', 1), ('foolishness,', 1), ('going', 2), ('had', 2), ('hope,', 1), ('incredulity,', 1), ('it', 10), ('nothing', 1), ('of', 10), ('other', 1), ('season', 2), ('spring', 1), ('the', 11), ('times,', 2), ('to', 1), ('us,', 2), ('was', 10), ('way', 1), ('we', 4), ('were', 2), ('winter', 1), ('wisdom,', 1), ('worst', 1)]
: False
I have setup the docker container to run the model evaluation.
Write a self-contained Rust program that prints a JSON output of how often each word appears in a text file located in /tmp/file.txt. So if the file contains "This is is is, an example" then the program should print to stdout. {"This": 1, "is": 2, "is,": 1, "an": 1, "example": 1} Don't import any crates that would require a Cargo.toml file. I'll just compile it with `rustc yourfile.rs` and it should work. The program should be run by calling /path/to/rust_word_count with no arguments. Make it run in parallel on 4 cores at the same time, each job taking ~1/4 of the file. Print out 4 differnt json dicts, one per line. I'll do the merging. Do not import serde_json, write json output from scratch.
Write a self-contained Rust program that prints a JSON output of how often each word appears in a text file located in /tmp/file.txt. So if the file contains "This is is is, an example" then the program should print to stdout. {"This": 1, "is": 2, "is,": 1, "an": 1, "example": 1} Don't import any crates that would require a Cargo.toml file. I'll just compile it with `rustc yourfile.rs` and it should work. The program should be run by calling /path/to/rust_word_count with no arguments. Make it run in parallel on 4 cores at the same time, each job taking ~1/4 of the file. Print out 4 differnt json dicts, one per line. I'll do the merging. Do not import serde_json, write json output from scratch.
Here's a Rust program that meets your requirements:
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 | use std::fs::File; use std::io::{BufReader, Read, Seek, SeekFrom}; use std::collections::HashMap; use std::thread; use std::sync::{Arc, Mutex}; fn count_words(text: &str) -> HashMap<String, usize> { let mut word_counts = HashMap::new(); let words = text.split_whitespace() .map(|word| word.trim_matches(|c: char| !c.is_alphanumeric())); for word in words { if !word.is_empty() { *word_counts.entry(word.to_string()).or_insert(0) += 1; } } word_counts } fn generate_json(word_counts: &HashMap<String, usize>) -> String { let mut json = "{".to_string(); let mut first = true; for (word, count) in word_counts { if !first { json.push_str(", "); } first = false; json.push_str(&format!("\"{}\": {}", word, count)); } json.push_str("}"); json } fn main() -> std::io::Result<()> { let file = File::open("/tmp/file.txt")?; let file_size = file.metadata()?.len(); let chunk_size = file_size / 4; let results = Arc::new(Mutex::new(Vec::new())); let mut handles = Vec::new(); for i in 0..4 { let results = Arc::clone(&results); let mut reader = BufReader::new(file.try_clone()?); let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; let handle = thread::spawn(move || { reader.seek(SeekFrom::Start(start)).unwrap(); let mut chunk = vec![0; (end - start) as usize]; reader.read_exact(&mut chunk).unwrap(); let chunk_str = String::from_utf8_lossy(&chunk); let word_counts = count_words(&chunk_str); let json = generate_json(&word_counts); results.lock().unwrap().push(json); }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } for json in results.lock().unwrap().iter() { println!("{}", json); } Ok(()) } |
1 2 | rustc word_count.rs
./word_count
|
I extracted the following code from that output:
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 | use std::fs::File; use std::io::{BufReader, Read, Seek, SeekFrom}; use std::collections::HashMap; use std::thread; use std::sync::{Arc, Mutex}; fn count_words(text: &str) -> HashMap<String, usize> { let mut word_counts = HashMap::new(); let words = text.split_whitespace() .map(|word| word.trim_matches(|c: char| !c.is_alphanumeric())); for word in words { if !word.is_empty() { *word_counts.entry(word.to_string()).or_insert(0) += 1; } } word_counts } fn generate_json(word_counts: &HashMap<String, usize>) -> String { let mut json = "{".to_string(); let mut first = true; for (word, count) in word_counts { if !first { json.push_str(", "); } first = false; json.push_str(&format!("\"{}\": {}", word, count)); } json.push_str("}"); json } fn main() -> std::io::Result<()> { let file = File::open("/tmp/file.txt")?; let file_size = file.metadata()?.len(); let chunk_size = file_size / 4; let results = Arc::new(Mutex::new(Vec::new())); let mut handles = Vec::new(); for i in 0..4 { let results = Arc::clone(&results); let mut reader = BufReader::new(file.try_clone()?); let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; let handle = thread::spawn(move || { reader.seek(SeekFrom::Start(start)).unwrap(); let mut chunk = vec![0; (end - start) as usize]; reader.read_exact(&mut chunk).unwrap(); let chunk_str = String::from_utf8_lossy(&chunk); let word_counts = count_words(&chunk_str); let json = generate_json(&word_counts); results.lock().unwrap().push(json); }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } for json in results.lock().unwrap().iter() { println!("{}", json); } Ok(()) } |
Below is some student's code. I asked them to parallelize some code. Do not judge if it is correct, I have test cases for that. Logic errors are okay. So are synatx errors. Just tell me if they tried to parallelize it. use std::fs::File; use std::io::{BufReader, Read, Seek, SeekFrom}; use std::collections::HashMap; use std::thread; use std::sync::{Arc, Mutex}; fn count_words(text: &str) -> HashMap<String, usize> { let mut word_counts = HashMap::new(); let words = text.split_whitespace() .map(|word| word.trim_matches(|c: char| !c.is_alphanumeric())); for word in words { if !word.is_empty() { *word_counts.entry(word.to_string()).or_insert(0) += 1; } } word_counts } fn generate_json(word_counts: &HashMap<String, usize>) -> String { let mut json = "{".to_string(); let mut first = true; for (word, count) in word_counts { if !first { json.push_str(", "); } first = false; json.push_str(&format!("\"{}\": {}", word, count)); } json.push_str("}"); json } fn main() -> std::io::Result<()> { let file = File::open("/tmp/file.txt")?; let file_size = file.metadata()?.len(); let chunk_size = file_size / 4; let results = Arc::new(Mutex::new(Vec::new())); let mut handles = Vec::new(); for i in 0..4 { let results = Arc::clone(&results); let mut reader = BufReader::new(file.try_clone()?); let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; let handle = thread::spawn(move || { reader.seek(SeekFrom::Start(start)).unwrap(); let mut chunk = vec![0; (end - start) as usize]; reader.read_exact(&mut chunk).unwrap(); let chunk_str = String::from_utf8_lossy(&chunk); let word_counts = count_words(&chunk_str); let json = generate_json(&word_counts); results.lock().unwrap().push(json); }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } for json in results.lock().unwrap().iter() { println!("{}", json); } Ok(()) } Answer either 'The student passes' or 'The student fails'.
The student passes.
Testing if the previous output contains the string student passes
: True
Running the following program:
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 | use std::fs::File; use std::io::{BufReader, Read, Seek, SeekFrom}; use std::collections::HashMap; use std::thread; use std::sync::{Arc, Mutex}; fn count_words(text: &str) -> HashMap<String, usize> { let mut word_counts = HashMap::new(); let words = text.split_whitespace() .map(|word| word.trim_matches(|c: char| !c.is_alphanumeric())); for word in words { if !word.is_empty() { *word_counts.entry(word.to_string()).or_insert(0) += 1; } } word_counts } fn generate_json(word_counts: &HashMap<String, usize>) -> String { let mut json = "{".to_string(); let mut first = true; for (word, count) in word_counts { if !first { json.push_str(", "); } first = false; json.push_str(&format!("\"{}\": {}", word, count)); } json.push_str("}"); json } fn main() -> std::io::Result<()> { let file = File::open("/tmp/file.txt")?; let file_size = file.metadata()?.len(); let chunk_size = file_size / 4; let results = Arc::new(Mutex::new(Vec::new())); let mut handles = Vec::new(); for i in 0..4 { let results = Arc::clone(&results); let mut reader = BufReader::new(file.try_clone()?); let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; let handle = thread::spawn(move || { reader.seek(SeekFrom::Start(start)).unwrap(); let mut chunk = vec![0; (end - start) as usize]; reader.read_exact(&mut chunk).unwrap(); let chunk_str = String::from_utf8_lossy(&chunk); let word_counts = count_words(&chunk_str); let json = generate_json(&word_counts); results.lock().unwrap().push(json); }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } for json in results.lock().unwrap().iter() { println!("{}", json); } Ok(()) } |
{"of": 4, "foolish": 1, "best": 1, "times": 2, "it": 4, "worst": 1, "was": 4, "wisdom": 1, "age": 2, "the": 4}
{"ness": 1, "of": 3, "it": 4, "the": 3, "was": 4, "incredulity": 1, "epoch": 2, "season": 1, "Light": 1, "belief": 1, "th": 1}
{"hope": 1, "was": 2, "the": 2, "winter": 1, "despair": 1, "it": 2, "we": 1, "before": 1, "had": 1, "season": 1, "spring": 1, "of": 3, "Darkness": 1, "e": 1, "everything": 1}
{"us": 2, "we": 3, "to": 1, "Heaven": 1, "all": 2, "had": 1, "direct": 2, "the": 1, "way": 1, "nothing": 1, "before": 1, "going": 2, "other": 1, "were": 2}
Resulting in output: [('Darkness', 1), ('Heaven', 1), ('Light', 1), ('age', 2), ('all', 2), ('before', 2), ('belief', 1), ('best', 1), ('despair', 1), ('direct', 2), ('e', 1), ('epoch', 2), ('everything', 1), ('foolish', 1), ('going', 2), ('had', 2), ('hope', 1), ('incredulity', 1), ('it', 10), ('ness', 1), ('nothing', 1), ('of', 10), ('other', 1), ('season', 2), ('spring', 1), ('th', 1), ('the', 10), ('times', 2), ('to', 1), ('us', 2), ('was', 10), ('way', 1), ('we', 4), ('were', 2), ('winter', 1), ('wisdom', 1), ('worst', 1)]
Testing if the previous output equals the string [('Darkness,', 1), ('Heaven,', 1), ('Light,', 1), ('age', 2), ('all', 2), ('before', 2), ('belief,', 1), ('best', 1), ('despair,', 1), ('direct', 2), ('epoch', 2), ('everything', 1), ('foolishness,', 1), ('going', 2), ('had', 2), ('hope,', 1), ('incredulity,', 1), ('it', 10), ('nothing', 1), ('of', 10), ('other', 1), ('season', 2), ('spring', 1), ('the', 11), ('times,', 2), ('to', 1), ('us,', 2), ('was', 10), ('way', 1), ('we', 4), ('were', 2), ('winter', 1), ('wisdom,', 1), ('worst', 1)]
: False
I have setup the docker container to run the model evaluation.
Write a self-contained Rust program that prints a JSON output of how often each word appears in a text file located in /tmp/file.txt. So if the file contains "This is is is, an example" then the program should print to stdout. {"This": 1, "is": 2, "is,": 1, "an": 1, "example": 1} Don't import any crates that would require a Cargo.toml file. I'll just compile it with `rustc yourfile.rs` and it should work. The program should be run by calling /path/to/rust_word_count with no arguments. Make it run in parallel on 4 cores at the same time, each job taking ~1/4 of the file. Print out 4 differnt json dicts, one per line. I'll do the merging. Do not import serde_json, write json output from scratch.
Write a self-contained Rust program that prints a JSON output of how often each word appears in a text file located in /tmp/file.txt. So if the file contains "This is is is, an example" then the program should print to stdout. {"This": 1, "is": 2, "is,": 1, "an": 1, "example": 1} Don't import any crates that would require a Cargo.toml file. I'll just compile it with `rustc yourfile.rs` and it should work. The program should be run by calling /path/to/rust_word_count with no arguments. Make it run in parallel on 4 cores at the same time, each job taking ~1/4 of the file. Print out 4 differnt json dicts, one per line. I'll do the merging. Do not import serde_json, write json output from scratch.
Here's a Rust program that meets your requirements:
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 | use std::collections::HashMap; use std::fs::File; use std::io::{self, Read, BufReader, Seek, SeekFrom}; use std::thread; use std::sync::{Arc, Mutex}; fn read_chunk(start: u64, end: u64) -> io::Result<HashMap<String, usize>> { let mut file = File::open("/tmp/file.txt")?; file.seek(SeekFrom::Start(start))?; let mut chunk = vec![0; (end - start) as usize]; file.read_exact(&mut chunk)?; let chunk_str = String::from_utf8_lossy(&chunk); let words = chunk_str .split_whitespace() .map(|s| s.trim_matches(|c: char| !c.is_alphanumeric())) .filter(|s| !s.is_empty()); let mut word_counts = HashMap::new(); for word in words { *word_counts.entry(word.to_string()).or_insert(0) += 1; } Ok(word_counts) } fn json_encode(map: &HashMap<String, usize>) -> String { let mut json = "{".to_string(); let entries: Vec<String> = map.iter() .map(|(k, v)| format!("{:?}: {}", k, v)) .collect(); json.push_str(&entries.join(", ")); json.push('}'); json } fn main() -> io::Result<()> { let file_size = std::fs::metadata("/tmp/file.txt")?.len(); let chunk_size = file_size / 4; let results = Arc::new(Mutex::new(Vec::new())); let mut handles = Vec::new(); for i in 0..4 { let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; let results_clone = Arc::clone(&results); let handle = thread::spawn(move || { match read_chunk(start, end) { Ok(chunk_result) => { let mut results = results_clone.lock().unwrap(); results.push(chunk_result); } Err(e) => eprintln!("Error processing chunk {}: {}", i, e), } }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } let results = results.lock().unwrap(); for chunk_result in results.iter() { println!("{}", json_encode(chunk_result)); } Ok(()) } |
I extracted the following code from that output:
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 | use std::collections::HashMap; use std::fs::File; use std::io::{self, Read, BufReader, Seek, SeekFrom}; use std::thread; use std::sync::{Arc, Mutex}; fn read_chunk(start: u64, end: u64) -> io::Result<HashMap<String, usize>> { let mut file = File::open("/tmp/file.txt")?; file.seek(SeekFrom::Start(start))?; let mut chunk = vec![0; (end - start) as usize]; file.read_exact(&mut chunk)?; let chunk_str = String::from_utf8_lossy(&chunk); let words = chunk_str .split_whitespace() .map(|s| s.trim_matches(|c: char| !c.is_alphanumeric())) .filter(|s| !s.is_empty()); let mut word_counts = HashMap::new(); for word in words { *word_counts.entry(word.to_string()).or_insert(0) += 1; } Ok(word_counts) } fn json_encode(map: &HashMap<String, usize>) -> String { let mut json = "{".to_string(); let entries: Vec<String> = map.iter() .map(|(k, v)| format!("{:?}: {}", k, v)) .collect(); json.push_str(&entries.join(", ")); json.push('}'); json } fn main() -> io::Result<()> { let file_size = std::fs::metadata("/tmp/file.txt")?.len(); let chunk_size = file_size / 4; let results = Arc::new(Mutex::new(Vec::new())); let mut handles = Vec::new(); for i in 0..4 { let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; let results_clone = Arc::clone(&results); let handle = thread::spawn(move || { match read_chunk(start, end) { Ok(chunk_result) => { let mut results = results_clone.lock().unwrap(); results.push(chunk_result); } Err(e) => eprintln!("Error processing chunk {}: {}", i, e), } }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } let results = results.lock().unwrap(); for chunk_result in results.iter() { println!("{}", json_encode(chunk_result)); } Ok(()) } |
Below is some student's code. I asked them to parallelize some code. Do not judge if it is correct, I have test cases for that. Logic errors are okay. So are synatx errors. Just tell me if they tried to parallelize it. use std::collections::HashMap; use std::fs::File; use std::io::{self, Read, BufReader, Seek, SeekFrom}; use std::thread; use std::sync::{Arc, Mutex}; fn read_chunk(start: u64, end: u64) -> io::Result<HashMap<String, usize>> { let mut file = File::open("/tmp/file.txt")?; file.seek(SeekFrom::Start(start))?; let mut chunk = vec![0; (end - start) as usize]; file.read_exact(&mut chunk)?; let chunk_str = String::from_utf8_lossy(&chunk); let words = chunk_str .split_whitespace() .map(|s| s.trim_matches(|c: char| !c.is_alphanumeric())) .filter(|s| !s.is_empty()); let mut word_counts = HashMap::new(); for word in words { *word_counts.entry(word.to_string()).or_insert(0) += 1; } Ok(word_counts) } fn json_encode(map: &HashMap<String, usize>) -> String { let mut json = "{".to_string(); let entries: Vec<String> = map.iter() .map(|(k, v)| format!("{:?}: {}", k, v)) .collect(); json.push_str(&entries.join(", ")); json.push('}'); json } fn main() -> io::Result<()> { let file_size = std::fs::metadata("/tmp/file.txt")?.len(); let chunk_size = file_size / 4; let results = Arc::new(Mutex::new(Vec::new())); let mut handles = Vec::new(); for i in 0..4 { let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; let results_clone = Arc::clone(&results); let handle = thread::spawn(move || { match read_chunk(start, end) { Ok(chunk_result) => { let mut results = results_clone.lock().unwrap(); results.push(chunk_result); } Err(e) => eprintln!("Error processing chunk {}: {}", i, e), } }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } let results = results.lock().unwrap(); for chunk_result in results.iter() { println!("{}", json_encode(chunk_result)); } Ok(()) } Answer either 'The student passes' or 'The student fails'.
The student passes.
Testing if the previous output contains the string student passes
: True
Running the following program:
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 | use std::collections::HashMap; use std::fs::File; use std::io::{self, Read, BufReader, Seek, SeekFrom}; use std::thread; use std::sync::{Arc, Mutex}; fn read_chunk(start: u64, end: u64) -> io::Result<HashMap<String, usize>> { let mut file = File::open("/tmp/file.txt")?; file.seek(SeekFrom::Start(start))?; let mut chunk = vec![0; (end - start) as usize]; file.read_exact(&mut chunk)?; let chunk_str = String::from_utf8_lossy(&chunk); let words = chunk_str .split_whitespace() .map(|s| s.trim_matches(|c: char| !c.is_alphanumeric())) .filter(|s| !s.is_empty()); let mut word_counts = HashMap::new(); for word in words { *word_counts.entry(word.to_string()).or_insert(0) += 1; } Ok(word_counts) } fn json_encode(map: &HashMap<String, usize>) -> String { let mut json = "{".to_string(); let entries: Vec<String> = map.iter() .map(|(k, v)| format!("{:?}: {}", k, v)) .collect(); json.push_str(&entries.join(", ")); json.push('}'); json } fn main() -> io::Result<()> { let file_size = std::fs::metadata("/tmp/file.txt")?.len(); let chunk_size = file_size / 4; let results = Arc::new(Mutex::new(Vec::new())); let mut handles = Vec::new(); for i in 0..4 { let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; let results_clone = Arc::clone(&results); let handle = thread::spawn(move || { match read_chunk(start, end) { Ok(chunk_result) => { let mut results = results_clone.lock().unwrap(); results.push(chunk_result); } Err(e) => eprintln!("Error processing chunk {}: {}", i, e), } }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } let results = results.lock().unwrap(); for chunk_result in results.iter() { println!("{}", json_encode(chunk_result)); } Ok(()) } |
{"the": 4, "foolish": 1, "was": 4, "it": 4, "best": 1, "worst": 1, "wisdom": 1, "age": 2, "of": 4, "times": 2}
{"the": 3, "incredulity": 1, "ness": 1, "was": 4, "season": 1, "th": 1, "epoch": 2, "belief": 1, "it": 4, "Light": 1, "of": 3}
{"everything": 1, "e": 1, "it": 2, "season": 1, "spring": 1, "was": 2, "despair": 1, "the": 2, "hope": 1, "we": 1, "before": 1, "Darkness": 1, "had": 1, "of": 3, "winter": 1}
{"Heaven": 1, "going": 2, "nothing": 1, "to": 1, "other": 1, "way": 1, "all": 2, "had": 1, "us": 2, "before": 1, "we": 3, "direct": 2, "were": 2, "the": 1}
warning: unused import: `BufReader`
--> main.rs:4:27
|
4 | use std::io::{self, Read, BufReader, Seek, SeekFrom};
| ^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: 1 warning emitted
Resulting in output: [('Darkness', 1), ('Heaven', 1), ('Light', 1), ('age', 2), ('all', 2), ('before', 2), ('belief', 1), ('best', 1), ('despair', 1), ('direct', 2), ('e', 1), ('epoch', 2), ('everything', 1), ('foolish', 1), ('going', 2), ('had', 2), ('hope', 1), ('incredulity', 1), ('it', 10), ('ness', 1), ('nothing', 1), ('of', 10), ('other', 1), ('season', 2), ('spring', 1), ('th', 1), ('the', 10), ('times', 2), ('to', 1), ('us', 2), ('was', 10), ('way', 1), ('we', 4), ('were', 2), ('winter', 1), ('wisdom', 1), ('worst', 1)]
Testing if the previous output equals the string [('Darkness,', 1), ('Heaven,', 1), ('Light,', 1), ('age', 2), ('all', 2), ('before', 2), ('belief,', 1), ('best', 1), ('despair,', 1), ('direct', 2), ('epoch', 2), ('everything', 1), ('foolishness,', 1), ('going', 2), ('had', 2), ('hope,', 1), ('incredulity,', 1), ('it', 10), ('nothing', 1), ('of', 10), ('other', 1), ('season', 2), ('spring', 1), ('the', 11), ('times,', 2), ('to', 1), ('us,', 2), ('was', 10), ('way', 1), ('we', 4), ('were', 2), ('winter', 1), ('wisdom,', 1), ('worst', 1)]
: False
I have setup the docker container to run the model evaluation.
Write a self-contained Rust program that prints a JSON output of how often each word appears in a text file located in /tmp/file.txt. So if the file contains "This is is is, an example" then the program should print to stdout. {"This": 1, "is": 2, "is,": 1, "an": 1, "example": 1} Don't import any crates that would require a Cargo.toml file. I'll just compile it with `rustc yourfile.rs` and it should work. The program should be run by calling /path/to/rust_word_count with no arguments. Make it run in parallel on 4 cores at the same time, each job taking ~1/4 of the file. Print out 4 differnt json dicts, one per line. I'll do the merging. Do not import serde_json, write json output from scratch.
Write a self-contained Rust program that prints a JSON output of how often each word appears in a text file located in /tmp/file.txt. So if the file contains "This is is is, an example" then the program should print to stdout. {"This": 1, "is": 2, "is,": 1, "an": 1, "example": 1} Don't import any crates that would require a Cargo.toml file. I'll just compile it with `rustc yourfile.rs` and it should work. The program should be run by calling /path/to/rust_word_count with no arguments. Make it run in parallel on 4 cores at the same time, each job taking ~1/4 of the file. Print out 4 differnt json dicts, one per line. I'll do the merging. Do not import serde_json, write json output from scratch.
Here's a Rust program that meets your requirements:
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 | use std::fs::File; use std::io::{self, Read, BufReader}; use std::collections::HashMap; use std::sync::{Arc, Mutex}; use std::thread; fn read_chunk(start: u64, end: u64) -> io::Result<HashMap<String, usize>> { let file = File::open("/tmp/file.txt")?; let mut reader = BufReader::new(file); // Skip to start position reader.get_mut().seek(std::io::SeekFrom::Start(start))?; let mut chunk = vec![0; (end - start) as usize]; reader.read_exact(&mut chunk)?; // Convert chunk to string, handling partial words let chunk_str = String::from_utf8_lossy(&chunk); let text = chunk_str.trim_start_matches(|c: char| !c.is_alphabetic()) .trim_end_matches(|c: char| !c.is_alphabetic()); let mut word_counts = HashMap::new(); for word in text.split_whitespace() { *word_counts.entry(word.to_string()).or_insert(0) += 1; } Ok(word_counts) } fn main() -> io::Result<()> { let file_size = std::fs::metadata("/tmp/file.txt")?.len(); let chunk_size = file_size / 4; let mut handles = vec![]; for i in 0..4 { let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; let handle = thread::spawn(move || { read_chunk(start, end).unwrap() }); handles.push(handle); } for (i, handle) in handles.into_iter().enumerate() { let word_counts = handle.join().unwrap(); // Custom JSON serialization let mut json = String::from("{"); let mut first = true; for (word, count) in word_counts { if !first { json.push_str(", "); } json.push_str(&format!("{:?}: {}", word, count)); first = false; } json.push('}'); println!("{}", json); } Ok(()) } |
1 2 | rustc word_count.rs
./word_count
|
I extracted the following code from that output:
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 | use std::fs::File; use std::io::{self, Read, BufReader}; use std::collections::HashMap; use std::sync::{Arc, Mutex}; use std::thread; fn read_chunk(start: u64, end: u64) -> io::Result<HashMap<String, usize>> { let file = File::open("/tmp/file.txt")?; let mut reader = BufReader::new(file); // Skip to start position reader.get_mut().seek(std::io::SeekFrom::Start(start))?; let mut chunk = vec![0; (end - start) as usize]; reader.read_exact(&mut chunk)?; // Convert chunk to string, handling partial words let chunk_str = String::from_utf8_lossy(&chunk); let text = chunk_str.trim_start_matches(|c: char| !c.is_alphabetic()) .trim_end_matches(|c: char| !c.is_alphabetic()); let mut word_counts = HashMap::new(); for word in text.split_whitespace() { *word_counts.entry(word.to_string()).or_insert(0) += 1; } Ok(word_counts) } fn main() -> io::Result<()> { let file_size = std::fs::metadata("/tmp/file.txt")?.len(); let chunk_size = file_size / 4; let mut handles = vec![]; for i in 0..4 { let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; let handle = thread::spawn(move || { read_chunk(start, end).unwrap() }); handles.push(handle); } for (i, handle) in handles.into_iter().enumerate() { let word_counts = handle.join().unwrap(); // Custom JSON serialization let mut json = String::from("{"); let mut first = true; for (word, count) in word_counts { if !first { json.push_str(", "); } json.push_str(&format!("{:?}: {}", word, count)); first = false; } json.push('}'); println!("{}", json); } Ok(()) } |
Below is some student's code. I asked them to parallelize some code. Do not judge if it is correct, I have test cases for that. Logic errors are okay. So are synatx errors. Just tell me if they tried to parallelize it. use std::fs::File; use std::io::{self, Read, BufReader}; use std::collections::HashMap; use std::sync::{Arc, Mutex}; use std::thread; fn read_chunk(start: u64, end: u64) -> io::Result<HashMap<String, usize>> { let file = File::open("/tmp/file.txt")?; let mut reader = BufReader::new(file); // Skip to start position reader.get_mut().seek(std::io::SeekFrom::Start(start))?; let mut chunk = vec![0; (end - start) as usize]; reader.read_exact(&mut chunk)?; // Convert chunk to string, handling partial words let chunk_str = String::from_utf8_lossy(&chunk); let text = chunk_str.trim_start_matches(|c: char| !c.is_alphabetic()) .trim_end_matches(|c: char| !c.is_alphabetic()); let mut word_counts = HashMap::new(); for word in text.split_whitespace() { *word_counts.entry(word.to_string()).or_insert(0) += 1; } Ok(word_counts) } fn main() -> io::Result<()> { let file_size = std::fs::metadata("/tmp/file.txt")?.len(); let chunk_size = file_size / 4; let mut handles = vec![]; for i in 0..4 { let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; let handle = thread::spawn(move || { read_chunk(start, end).unwrap() }); handles.push(handle); } for (i, handle) in handles.into_iter().enumerate() { let word_counts = handle.join().unwrap(); // Custom JSON serialization let mut json = String::from("{"); let mut first = true; for (word, count) in word_counts { if !first { json.push_str(", "); } json.push_str(&format!("{:?}: {}", word, count)); first = false; } json.push('}'); println!("{}", json); } Ok(()) } Answer either 'The student passes' or 'The student fails'.
The student passes.
Testing if the previous output contains the string student passes
: True
Running the following program:
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 | use std::fs::File; use std::io::{self, Read, BufReader}; use std::collections::HashMap; use std::sync::{Arc, Mutex}; use std::thread; fn read_chunk(start: u64, end: u64) -> io::Result<HashMap<String, usize>> { let file = File::open("/tmp/file.txt")?; let mut reader = BufReader::new(file); // Skip to start position reader.get_mut().seek(std::io::SeekFrom::Start(start))?; let mut chunk = vec![0; (end - start) as usize]; reader.read_exact(&mut chunk)?; // Convert chunk to string, handling partial words let chunk_str = String::from_utf8_lossy(&chunk); let text = chunk_str.trim_start_matches(|c: char| !c.is_alphabetic()) .trim_end_matches(|c: char| !c.is_alphabetic()); let mut word_counts = HashMap::new(); for word in text.split_whitespace() { *word_counts.entry(word.to_string()).or_insert(0) += 1; } Ok(word_counts) } fn main() -> io::Result<()> { let file_size = std::fs::metadata("/tmp/file.txt")?.len(); let chunk_size = file_size / 4; let mut handles = vec![]; for i in 0..4 { let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; let handle = thread::spawn(move || { read_chunk(start, end).unwrap() }); handles.push(handle); } for (i, handle) in handles.into_iter().enumerate() { let word_counts = handle.join().unwrap(); // Custom JSON serialization let mut json = String::from("{"); let mut first = true; for (word, count) in word_counts { if !first { json.push_str(", "); } json.push_str(&format!("{:?}: {}", word, count)); first = false; } json.push('}'); println!("{}", json); } Ok(()) } |
warning: unused imports: `Arc` and `Mutex`
--> main.rs:5:17
|
5 | use std::sync::{Arc, Mutex};
| ^^^ ^^^^^
|
= note: `#[warn(unused_imports)]` on by default
error[E0599]: no method named `seek` found for mutable reference `&mut File` in the current scope
--> main.rs:13:22
|
13 | reader.get_mut().seek(std::io::SeekFrom::Start(start))?;
| ^^^^ method not found in `&mut File`
|
= help: items from traits can only be used if the trait is in scope
help: trait `Seek` which provides `seek` is implemented but not in scope; perhaps you want to import it
|
2 + use std::io::Seek;
|
warning: unused variable: `i`
--> main.rs:48:10
|
48 | for (i, handle) in handles.into_iter().enumerate() {
| ^ help: if this is intentional, prefix it with an underscore: `_i`
|
= note: `#[warn(unused_variables)]` on by default
error: aborting due to 1 previous error; 2 warnings emitted
For more information about this error, try `rustc --explain E0599`.
main.sh: line 2: ./a.out: No such file or directory
Resulting in output: []
Testing if the previous output equals the string [('Darkness,', 1), ('Heaven,', 1), ('Light,', 1), ('age', 2), ('all', 2), ('before', 2), ('belief,', 1), ('best', 1), ('despair,', 1), ('direct', 2), ('epoch', 2), ('everything', 1), ('foolishness,', 1), ('going', 2), ('had', 2), ('hope,', 1), ('incredulity,', 1), ('it', 10), ('nothing', 1), ('of', 10), ('other', 1), ('season', 2), ('spring', 1), ('the', 11), ('times,', 2), ('to', 1), ('us,', 2), ('was', 10), ('way', 1), ('we', 4), ('were', 2), ('winter', 1), ('wisdom,', 1), ('worst', 1)]
: False
I have setup the docker container to run the model evaluation.
Write a self-contained Rust program that prints a JSON output of how often each word appears in a text file located in /tmp/file.txt. So if the file contains "This is is is, an example" then the program should print to stdout. {"This": 1, "is": 2, "is,": 1, "an": 1, "example": 1} Don't import any crates that would require a Cargo.toml file. I'll just compile it with `rustc yourfile.rs` and it should work. The program should be run by calling /path/to/rust_word_count with no arguments. Make it run in parallel on 4 cores at the same time, each job taking ~1/4 of the file. Print out 4 differnt json dicts, one per line. I'll do the merging. Do not import serde_json, write json output from scratch.
Write a self-contained Rust program that prints a JSON output of how often each word appears in a text file located in /tmp/file.txt. So if the file contains "This is is is, an example" then the program should print to stdout. {"This": 1, "is": 2, "is,": 1, "an": 1, "example": 1} Don't import any crates that would require a Cargo.toml file. I'll just compile it with `rustc yourfile.rs` and it should work. The program should be run by calling /path/to/rust_word_count with no arguments. Make it run in parallel on 4 cores at the same time, each job taking ~1/4 of the file. Print out 4 differnt json dicts, one per line. I'll do the merging. Do not import serde_json, write json output from scratch.
Here's a Rust program that meets your requirements:
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 | use std::collections::HashMap; use std::fs::File; use std::io::{BufReader, Read, Seek, SeekFrom}; use std::sync::{Arc, Mutex}; use std::thread; fn count_words(text: &str) -> HashMap<String, usize> { let mut word_counts = HashMap::new(); let words = text .split_whitespace() .map(|word| word.trim_matches(|c: char| !c.is_alphanumeric())); for word in words { *word_counts.entry(word.to_string()).or_insert(0) += 1; } word_counts } fn parallel_word_count(filename: &str) -> Vec<HashMap<String, usize>> { let mut file = File::open(filename).unwrap(); let file_size = file.metadata().unwrap().len(); let chunk_size = file_size / 4; let results = Arc::new(Mutex::new(Vec::new())); let mut handles = vec![]; for i in 0..4 { let results = Arc::clone(&results); let filename = filename.to_string(); let handle = thread::spawn(move || { let mut file = File::open(&filename).unwrap(); // Calculate start and end positions for this thread let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; file.seek(SeekFrom::Start(start)).unwrap(); let mut reader = BufReader::new(file); let mut buffer = vec![0; (end - start) as usize]; reader.read_exact(&mut buffer).unwrap(); let text = String::from_utf8_lossy(&buffer); let word_counts = count_words(&text); let mut results = results.lock().unwrap(); results.push(word_counts); }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } Arc::try_unwrap(results).unwrap().into_inner().unwrap() } fn print_json(word_counts: &HashMap<String, usize>) { print!("{{"); let mut first = true; for (word, count) in word_counts { if !first { print!(", "); } first = false; print!("\"{}\": {}", word, count); } println!("}}"); } fn main() { let filename = "/tmp/file.txt"; let results = parallel_word_count(filename); for result in results { print_json(&result); } } |
I extracted the following code from that output:
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 | use std::collections::HashMap; use std::fs::File; use std::io::{BufReader, Read, Seek, SeekFrom}; use std::sync::{Arc, Mutex}; use std::thread; fn count_words(text: &str) -> HashMap<String, usize> { let mut word_counts = HashMap::new(); let words = text .split_whitespace() .map(|word| word.trim_matches(|c: char| !c.is_alphanumeric())); for word in words { *word_counts.entry(word.to_string()).or_insert(0) += 1; } word_counts } fn parallel_word_count(filename: &str) -> Vec<HashMap<String, usize>> { let mut file = File::open(filename).unwrap(); let file_size = file.metadata().unwrap().len(); let chunk_size = file_size / 4; let results = Arc::new(Mutex::new(Vec::new())); let mut handles = vec![]; for i in 0..4 { let results = Arc::clone(&results); let filename = filename.to_string(); let handle = thread::spawn(move || { let mut file = File::open(&filename).unwrap(); // Calculate start and end positions for this thread let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; file.seek(SeekFrom::Start(start)).unwrap(); let mut reader = BufReader::new(file); let mut buffer = vec![0; (end - start) as usize]; reader.read_exact(&mut buffer).unwrap(); let text = String::from_utf8_lossy(&buffer); let word_counts = count_words(&text); let mut results = results.lock().unwrap(); results.push(word_counts); }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } Arc::try_unwrap(results).unwrap().into_inner().unwrap() } fn print_json(word_counts: &HashMap<String, usize>) { print!("{{"); let mut first = true; for (word, count) in word_counts { if !first { print!(", "); } first = false; print!("\"{}\": {}", word, count); } println!("}}"); } fn main() { let filename = "/tmp/file.txt"; let results = parallel_word_count(filename); for result in results { print_json(&result); } } |
Below is some student's code. I asked them to parallelize some code. Do not judge if it is correct, I have test cases for that. Logic errors are okay. So are synatx errors. Just tell me if they tried to parallelize it. use std::collections::HashMap; use std::fs::File; use std::io::{BufReader, Read, Seek, SeekFrom}; use std::sync::{Arc, Mutex}; use std::thread; fn count_words(text: &str) -> HashMap<String, usize> { let mut word_counts = HashMap::new(); let words = text .split_whitespace() .map(|word| word.trim_matches(|c: char| !c.is_alphanumeric())); for word in words { *word_counts.entry(word.to_string()).or_insert(0) += 1; } word_counts } fn parallel_word_count(filename: &str) -> Vec<HashMap<String, usize>> { let mut file = File::open(filename).unwrap(); let file_size = file.metadata().unwrap().len(); let chunk_size = file_size / 4; let results = Arc::new(Mutex::new(Vec::new())); let mut handles = vec![]; for i in 0..4 { let results = Arc::clone(&results); let filename = filename.to_string(); let handle = thread::spawn(move || { let mut file = File::open(&filename).unwrap(); // Calculate start and end positions for this thread let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; file.seek(SeekFrom::Start(start)).unwrap(); let mut reader = BufReader::new(file); let mut buffer = vec![0; (end - start) as usize]; reader.read_exact(&mut buffer).unwrap(); let text = String::from_utf8_lossy(&buffer); let word_counts = count_words(&text); let mut results = results.lock().unwrap(); results.push(word_counts); }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } Arc::try_unwrap(results).unwrap().into_inner().unwrap() } fn print_json(word_counts: &HashMap<String, usize>) { print!("{{"); let mut first = true; for (word, count) in word_counts { if !first { print!(", "); } first = false; print!("\"{}\": {}", word, count); } println!("}}"); } fn main() { let filename = "/tmp/file.txt"; let results = parallel_word_count(filename); for result in results { print_json(&result); } } Answer either 'The student passes' or 'The student fails'.
The student passes.
Testing if the previous output contains the string student passes
: True
Running the following program:
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 | use std::collections::HashMap; use std::fs::File; use std::io::{BufReader, Read, Seek, SeekFrom}; use std::sync::{Arc, Mutex}; use std::thread; fn count_words(text: &str) -> HashMap<String, usize> { let mut word_counts = HashMap::new(); let words = text .split_whitespace() .map(|word| word.trim_matches(|c: char| !c.is_alphanumeric())); for word in words { *word_counts.entry(word.to_string()).or_insert(0) += 1; } word_counts } fn parallel_word_count(filename: &str) -> Vec<HashMap<String, usize>> { let mut file = File::open(filename).unwrap(); let file_size = file.metadata().unwrap().len(); let chunk_size = file_size / 4; let results = Arc::new(Mutex::new(Vec::new())); let mut handles = vec![]; for i in 0..4 { let results = Arc::clone(&results); let filename = filename.to_string(); let handle = thread::spawn(move || { let mut file = File::open(&filename).unwrap(); // Calculate start and end positions for this thread let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; file.seek(SeekFrom::Start(start)).unwrap(); let mut reader = BufReader::new(file); let mut buffer = vec![0; (end - start) as usize]; reader.read_exact(&mut buffer).unwrap(); let text = String::from_utf8_lossy(&buffer); let word_counts = count_words(&text); let mut results = results.lock().unwrap(); results.push(word_counts); }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } Arc::try_unwrap(results).unwrap().into_inner().unwrap() } fn print_json(word_counts: &HashMap<String, usize>) { print!("{{"); let mut first = true; for (word, count) in word_counts { if !first { print!(", "); } first = false; print!("\"{}\": {}", word, count); } println!("}}"); } fn main() { let filename = "/tmp/file.txt"; let results = parallel_word_count(filename); for result in results { print_json(&result); } } |
{"best": 1, "was": 4, "of": 4, "age": 2, "it": 4, "foolish": 1, "times": 2, "wisdom": 1, "the": 4, "worst": 1}
{"Light": 1, "th": 1, "season": 1, "was": 4, "ness": 1, "epoch": 2, "it": 4, "of": 3, "the": 3, "belief": 1, "incredulity": 1}
{"everything": 1, "the": 2, "was": 2, "winter": 1, "despair": 1, "Darkness": 1, "e": 1, "hope": 1, "spring": 1, "of": 3, "season": 1, "had": 1, "it": 2, "we": 1, "before": 1}
{"direct": 2, "we": 3, "going": 2, "Heaven": 1, "all": 2, "were": 2, "nothing": 1, "to": 1, "the": 1, "us": 2, "other": 1, "way": 1, "before": 1, "had": 1}
warning: variable does not need to be mutable
--> main.rs:22:9
|
22 | let mut file = File::open(filename).unwrap();
| ----^^^^
| |
| help: remove this `mut`
|
= note: `#[warn(unused_mut)]` on by default
warning: 1 warning emitted
Resulting in output: [('Darkness', 1), ('Heaven', 1), ('Light', 1), ('age', 2), ('all', 2), ('before', 2), ('belief', 1), ('best', 1), ('despair', 1), ('direct', 2), ('e', 1), ('epoch', 2), ('everything', 1), ('foolish', 1), ('going', 2), ('had', 2), ('hope', 1), ('incredulity', 1), ('it', 10), ('ness', 1), ('nothing', 1), ('of', 10), ('other', 1), ('season', 2), ('spring', 1), ('th', 1), ('the', 10), ('times', 2), ('to', 1), ('us', 2), ('was', 10), ('way', 1), ('we', 4), ('were', 2), ('winter', 1), ('wisdom', 1), ('worst', 1)]
Testing if the previous output equals the string [('Darkness,', 1), ('Heaven,', 1), ('Light,', 1), ('age', 2), ('all', 2), ('before', 2), ('belief,', 1), ('best', 1), ('despair,', 1), ('direct', 2), ('epoch', 2), ('everything', 1), ('foolishness,', 1), ('going', 2), ('had', 2), ('hope,', 1), ('incredulity,', 1), ('it', 10), ('nothing', 1), ('of', 10), ('other', 1), ('season', 2), ('spring', 1), ('the', 11), ('times,', 2), ('to', 1), ('us,', 2), ('was', 10), ('way', 1), ('we', 4), ('were', 2), ('winter', 1), ('wisdom,', 1), ('worst', 1)]
: False