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 self-contained Rust program that processes a text file in parallel and outputs word counts as JSON for each chunk:
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 | use std::collections::HashMap; use std::fs::File; use std::io::{BufRead, BufReader, Read, Seek, SeekFrom}; use std::sync::{Arc, Mutex}; use std::thread; fn make_json(map: &HashMap<String, usize>) -> String { let mut result = String::from("{"); let mut first = true; for (key, value) in map.iter() { if !first { result.push_str(", "); } first = false; result.push('"'); result.push_str(key); result.push('"'); result.push_str(": "); result.push_str(&value.to_string()); } result.push('}'); result } fn main() { let file = File::open("/tmp/file.txt").expect("Failed to open file"); let file_len = file.metadata().unwrap().len(); let chunk_size = file_len / 4; let file = Arc::new(Mutex::new(file)); let mut handles = vec![]; for i in 0..4 { let file = Arc::clone(&file); let handle = thread::spawn(move || { let mut word_counts: HashMap<String, usize> = HashMap::new(); let start_pos = i * chunk_size; let end_pos = if i == 3 { file_len } else { (i + 1) * chunk_size }; let mut file = file.lock().unwrap(); file.seek(SeekFrom::Start(start_pos)).unwrap(); let mut reader = BufReader::new(file.try_clone().unwrap()); let mut buffer = String::new(); if i > 0 { reader.read_line(&mut buffer).unwrap(); // Skip partial word buffer.clear(); } let mut current_pos = reader.stream_position().unwrap(); while current_pos < end_pos { if reader.read_line(&mut buffer).unwrap() == 0 { break; } for word in buffer.split_whitespace() { *word_counts.entry(word.to_string()).or_insert(0) += 1; } current_pos = reader.stream_position().unwrap(); buffer.clear(); } make_json(&word_counts) }); handles.push(handle); } for handle in handles { println!("{}", handle.join().unwrap()); } } |
1 2 | rustc wordcount.rs
./wordcount
|
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 | use std::collections::HashMap; use std::fs::File; use std::io::{BufRead, BufReader, Read, Seek, SeekFrom}; use std::sync::{Arc, Mutex}; use std::thread; fn make_json(map: &HashMap<String, usize>) -> String { let mut result = String::from("{"); let mut first = true; for (key, value) in map.iter() { if !first { result.push_str(", "); } first = false; result.push('"'); result.push_str(key); result.push('"'); result.push_str(": "); result.push_str(&value.to_string()); } result.push('}'); result } fn main() { let file = File::open("/tmp/file.txt").expect("Failed to open file"); let file_len = file.metadata().unwrap().len(); let chunk_size = file_len / 4; let file = Arc::new(Mutex::new(file)); let mut handles = vec![]; for i in 0..4 { let file = Arc::clone(&file); let handle = thread::spawn(move || { let mut word_counts: HashMap<String, usize> = HashMap::new(); let start_pos = i * chunk_size; let end_pos = if i == 3 { file_len } else { (i + 1) * chunk_size }; let mut file = file.lock().unwrap(); file.seek(SeekFrom::Start(start_pos)).unwrap(); let mut reader = BufReader::new(file.try_clone().unwrap()); let mut buffer = String::new(); if i > 0 { reader.read_line(&mut buffer).unwrap(); // Skip partial word buffer.clear(); } let mut current_pos = reader.stream_position().unwrap(); while current_pos < end_pos { if reader.read_line(&mut buffer).unwrap() == 0 { break; } for word in buffer.split_whitespace() { *word_counts.entry(word.to_string()).or_insert(0) += 1; } current_pos = reader.stream_position().unwrap(); buffer.clear(); } make_json(&word_counts) }); handles.push(handle); } for handle in handles { println!("{}", handle.join().unwrap()); } } |
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::{BufRead, BufReader, Read, Seek, SeekFrom}; use std::sync::{Arc, Mutex}; use std::thread; fn make_json(map: &HashMap<String, usize>) -> String { let mut result = String::from("{"); let mut first = true; for (key, value) in map.iter() { if !first { result.push_str(", "); } first = false; result.push('"'); result.push_str(key); result.push('"'); result.push_str(": "); result.push_str(&value.to_string()); } result.push('}'); result } fn main() { let file = File::open("/tmp/file.txt").expect("Failed to open file"); let file_len = file.metadata().unwrap().len(); let chunk_size = file_len / 4; let file = Arc::new(Mutex::new(file)); let mut handles = vec![]; for i in 0..4 { let file = Arc::clone(&file); let handle = thread::spawn(move || { let mut word_counts: HashMap<String, usize> = HashMap::new(); let start_pos = i * chunk_size; let end_pos = if i == 3 { file_len } else { (i + 1) * chunk_size }; let mut file = file.lock().unwrap(); file.seek(SeekFrom::Start(start_pos)).unwrap(); let mut reader = BufReader::new(file.try_clone().unwrap()); let mut buffer = String::new(); if i > 0 { reader.read_line(&mut buffer).unwrap(); // Skip partial word buffer.clear(); } let mut current_pos = reader.stream_position().unwrap(); while current_pos < end_pos { if reader.read_line(&mut buffer).unwrap() == 0 { break; } for word in buffer.split_whitespace() { *word_counts.entry(word.to_string()).or_insert(0) += 1; } current_pos = reader.stream_position().unwrap(); buffer.clear(); } make_json(&word_counts) }); handles.push(handle); } for handle in handles { println!("{}", handle.join().unwrap()); } } 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 | use std::collections::HashMap; use std::fs::File; use std::io::{BufRead, BufReader, Read, Seek, SeekFrom}; use std::sync::{Arc, Mutex}; use std::thread; fn make_json(map: &HashMap<String, usize>) -> String { let mut result = String::from("{"); let mut first = true; for (key, value) in map.iter() { if !first { result.push_str(", "); } first = false; result.push('"'); result.push_str(key); result.push('"'); result.push_str(": "); result.push_str(&value.to_string()); } result.push('}'); result } fn main() { let file = File::open("/tmp/file.txt").expect("Failed to open file"); let file_len = file.metadata().unwrap().len(); let chunk_size = file_len / 4; let file = Arc::new(Mutex::new(file)); let mut handles = vec![]; for i in 0..4 { let file = Arc::clone(&file); let handle = thread::spawn(move || { let mut word_counts: HashMap<String, usize> = HashMap::new(); let start_pos = i * chunk_size; let end_pos = if i == 3 { file_len } else { (i + 1) * chunk_size }; let mut file = file.lock().unwrap(); file.seek(SeekFrom::Start(start_pos)).unwrap(); let mut reader = BufReader::new(file.try_clone().unwrap()); let mut buffer = String::new(); if i > 0 { reader.read_line(&mut buffer).unwrap(); // Skip partial word buffer.clear(); } let mut current_pos = reader.stream_position().unwrap(); while current_pos < end_pos { if reader.read_line(&mut buffer).unwrap() == 0 { break; } for word in buffer.split_whitespace() { *word_counts.entry(word.to_string()).or_insert(0) += 1; } current_pos = reader.stream_position().unwrap(); buffer.clear(); } make_json(&word_counts) }); handles.push(handle); } for handle in handles { println!("{}", handle.join().unwrap()); } } |
{"worst": 1, "spring": 1, "epoch": 2, "direct": 2, "foolishness,": 1, "nothing": 1, "before": 2, "age": 2, "it": 10, "had": 2, "other": 1, "us,": 2, "wisdom,": 1, "of": 10, "everything": 1, "Light,": 1, "the": 11, "all": 2, "best": 1, "to": 1, "Heaven,": 1, "way": 1, "hope,": 1, "season": 2, "were": 2, "winter": 1, "we": 4, "going": 2, "belief,": 1, "incredulity,": 1, "Darkness,": 1, "times,": 2, "was": 10, "despair,": 1}
{}
{}
{}
warning: unused import: `Read`
--> main.rs:4:35
|
4 | use std::io::{BufRead, BufReader, Read, 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), ('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)]
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)]
: True
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 self-contained 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 84 85 86 87 88 89 | use std::collections::HashMap; use std::fs::File; use std::io::{BufRead, BufReader, Read, Seek, SeekFrom}; use std::sync::{Arc, Mutex}; use std::thread; fn get_file_size(file: &File) -> u64 { file.metadata().unwrap().len() } fn map_to_json(map: &HashMap<String, usize>) -> String { let mut result = String::from("{"); let mut first = true; for (key, value) in map.iter() { if !first { result.push_str(", "); } first = false; result.push('"'); result.push_str(key); result.push_str("\": "); result.push_str(&value.to_string()); } result.push('}'); result } fn process_chunk(content: String) -> HashMap<String, usize> { let mut word_count = HashMap::new(); for word in content.split_whitespace() { *word_count.entry(word.to_string()).or_insert(0) += 1; } word_count } fn main() { let file = File::open("/tmp/file.txt").unwrap(); let file_size = get_file_size(&file); let chunk_size = file_size / 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_size } else { (i + 1) * chunk_size }; let mut file_clone = File::open("/tmp/file.txt").unwrap(); let results = Arc::clone(&results); let handle = thread::spawn(move || { let mut content = String::new(); file_clone.seek(SeekFrom::Start(start)).unwrap(); let mut reader = BufReader::new(file_clone); // If not the first chunk, skip partial word if i > 0 { let mut first_word = String::new(); reader.read_line(&mut first_word).unwrap(); } let mut buffer = String::new(); while reader.read_line(&mut buffer).unwrap() > 0 { if reader.stream_position().unwrap() > end { break; } content.push_str(&buffer); buffer.clear(); } let word_count = process_chunk(content); results.lock().unwrap().push(word_count); }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } let results = results.lock().unwrap(); for result in results.iter() { println!("{}", map_to_json(result)); } } |
1 2 | rustc word_count.rs
./word_count
|
1 2 3 4 | {"word1": 5, "word2": 3} {"word3": 2, "word4": 4} {"word5": 1, "word2": 2} {"word6": 3, "word7": 1} |
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 84 85 86 87 88 89 | use std::collections::HashMap; use std::fs::File; use std::io::{BufRead, BufReader, Read, Seek, SeekFrom}; use std::sync::{Arc, Mutex}; use std::thread; fn get_file_size(file: &File) -> u64 { file.metadata().unwrap().len() } fn map_to_json(map: &HashMap<String, usize>) -> String { let mut result = String::from("{"); let mut first = true; for (key, value) in map.iter() { if !first { result.push_str(", "); } first = false; result.push('"'); result.push_str(key); result.push_str("\": "); result.push_str(&value.to_string()); } result.push('}'); result } fn process_chunk(content: String) -> HashMap<String, usize> { let mut word_count = HashMap::new(); for word in content.split_whitespace() { *word_count.entry(word.to_string()).or_insert(0) += 1; } word_count } fn main() { let file = File::open("/tmp/file.txt").unwrap(); let file_size = get_file_size(&file); let chunk_size = file_size / 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_size } else { (i + 1) * chunk_size }; let mut file_clone = File::open("/tmp/file.txt").unwrap(); let results = Arc::clone(&results); let handle = thread::spawn(move || { let mut content = String::new(); file_clone.seek(SeekFrom::Start(start)).unwrap(); let mut reader = BufReader::new(file_clone); // If not the first chunk, skip partial word if i > 0 { let mut first_word = String::new(); reader.read_line(&mut first_word).unwrap(); } let mut buffer = String::new(); while reader.read_line(&mut buffer).unwrap() > 0 { if reader.stream_position().unwrap() > end { break; } content.push_str(&buffer); buffer.clear(); } let word_count = process_chunk(content); results.lock().unwrap().push(word_count); }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } let results = results.lock().unwrap(); for result in results.iter() { println!("{}", map_to_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::{BufRead, BufReader, Read, Seek, SeekFrom}; use std::sync::{Arc, Mutex}; use std::thread; fn get_file_size(file: &File) -> u64 { file.metadata().unwrap().len() } fn map_to_json(map: &HashMap<String, usize>) -> String { let mut result = String::from("{"); let mut first = true; for (key, value) in map.iter() { if !first { result.push_str(", "); } first = false; result.push('"'); result.push_str(key); result.push_str("\": "); result.push_str(&value.to_string()); } result.push('}'); result } fn process_chunk(content: String) -> HashMap<String, usize> { let mut word_count = HashMap::new(); for word in content.split_whitespace() { *word_count.entry(word.to_string()).or_insert(0) += 1; } word_count } fn main() { let file = File::open("/tmp/file.txt").unwrap(); let file_size = get_file_size(&file); let chunk_size = file_size / 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_size } else { (i + 1) * chunk_size }; let mut file_clone = File::open("/tmp/file.txt").unwrap(); let results = Arc::clone(&results); let handle = thread::spawn(move || { let mut content = String::new(); file_clone.seek(SeekFrom::Start(start)).unwrap(); let mut reader = BufReader::new(file_clone); // If not the first chunk, skip partial word if i > 0 { let mut first_word = String::new(); reader.read_line(&mut first_word).unwrap(); } let mut buffer = String::new(); while reader.read_line(&mut buffer).unwrap() > 0 { if reader.stream_position().unwrap() > end { break; } content.push_str(&buffer); buffer.clear(); } let word_count = process_chunk(content); results.lock().unwrap().push(word_count); }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } let results = results.lock().unwrap(); for result in results.iter() { println!("{}", map_to_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 84 85 86 87 88 89 | use std::collections::HashMap; use std::fs::File; use std::io::{BufRead, BufReader, Read, Seek, SeekFrom}; use std::sync::{Arc, Mutex}; use std::thread; fn get_file_size(file: &File) -> u64 { file.metadata().unwrap().len() } fn map_to_json(map: &HashMap<String, usize>) -> String { let mut result = String::from("{"); let mut first = true; for (key, value) in map.iter() { if !first { result.push_str(", "); } first = false; result.push('"'); result.push_str(key); result.push_str("\": "); result.push_str(&value.to_string()); } result.push('}'); result } fn process_chunk(content: String) -> HashMap<String, usize> { let mut word_count = HashMap::new(); for word in content.split_whitespace() { *word_count.entry(word.to_string()).or_insert(0) += 1; } word_count } fn main() { let file = File::open("/tmp/file.txt").unwrap(); let file_size = get_file_size(&file); let chunk_size = file_size / 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_size } else { (i + 1) * chunk_size }; let mut file_clone = File::open("/tmp/file.txt").unwrap(); let results = Arc::clone(&results); let handle = thread::spawn(move || { let mut content = String::new(); file_clone.seek(SeekFrom::Start(start)).unwrap(); let mut reader = BufReader::new(file_clone); // If not the first chunk, skip partial word if i > 0 { let mut first_word = String::new(); reader.read_line(&mut first_word).unwrap(); } let mut buffer = String::new(); while reader.read_line(&mut buffer).unwrap() > 0 { if reader.stream_position().unwrap() > end { break; } content.push_str(&buffer); buffer.clear(); } let word_count = process_chunk(content); results.lock().unwrap().push(word_count); }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } let results = results.lock().unwrap(); for result in results.iter() { println!("{}", map_to_json(result)); } } |
{}
{}
{}
{}
warning: unused import: `Read`
--> main.rs:4:35
|
4 | use std::io::{BufRead, BufReader, Read, Seek, SeekFrom};
| ^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: 1 warning emitted
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 self-contained Rust program that processes a text file in parallel and outputs word counts as JSON for each chunk:
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 84 85 | use std::collections::HashMap; use std::fs::File; use std::io::{BufRead, BufReader, Read, Seek, SeekFrom}; use std::thread; fn count_words(text: &str) -> HashMap<String, usize> { let mut word_counts = HashMap::new(); for word in text.split_whitespace() { let count = word_counts.entry(word.to_string()).or_insert(0); *count += 1; } word_counts } fn to_json(map: &HashMap<String, usize>) -> String { let mut result = String::from("{"); let mut first = true; for (key, value) in map.iter() { if !first { result.push_str(", "); } first = false; result.push('"'); result.push_str(key); result.push_str("\": "); result.push_str(&value.to_string()); } result.push('}'); result } fn main() { let file = File::open("/tmp/file.txt").unwrap(); let file_size = file.metadata().unwrap().len(); let chunk_size = file_size / 4; let mut handles = vec![]; for i in 0..4 { let mut file = File::open("/tmp/file.txt").unwrap(); let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; let handle = thread::spawn(move || { file.seek(SeekFrom::Start(start)).unwrap(); let mut reader = BufReader::new(file); // If not at start of file, read and discard partial word if start > 0 { let mut partial = String::new(); reader.read_line(&mut partial).unwrap(); } let mut content = String::new(); let mut bytes_read = 0; while bytes_read < end - start { let mut line = String::new(); let read = reader.read_line(&mut line).unwrap(); if read == 0 { break; } bytes_read += read as u64; if bytes_read > end - start { // Trim the last line if we've read too much line.truncate((read - (bytes_read - (end - start)) as usize) as usize); } content.push_str(&line); } let counts = count_words(&content); to_json(&counts) }); handles.push(handle); } for handle in handles { match handle.join() { Ok(json) => println!("{}", json), Err(_) => eprintln!("Thread panicked"), } } } |
1 2 | rustc wordcount.rs
./wordcount
|
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 84 85 | use std::collections::HashMap; use std::fs::File; use std::io::{BufRead, BufReader, Read, Seek, SeekFrom}; use std::thread; fn count_words(text: &str) -> HashMap<String, usize> { let mut word_counts = HashMap::new(); for word in text.split_whitespace() { let count = word_counts.entry(word.to_string()).or_insert(0); *count += 1; } word_counts } fn to_json(map: &HashMap<String, usize>) -> String { let mut result = String::from("{"); let mut first = true; for (key, value) in map.iter() { if !first { result.push_str(", "); } first = false; result.push('"'); result.push_str(key); result.push_str("\": "); result.push_str(&value.to_string()); } result.push('}'); result } fn main() { let file = File::open("/tmp/file.txt").unwrap(); let file_size = file.metadata().unwrap().len(); let chunk_size = file_size / 4; let mut handles = vec![]; for i in 0..4 { let mut file = File::open("/tmp/file.txt").unwrap(); let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; let handle = thread::spawn(move || { file.seek(SeekFrom::Start(start)).unwrap(); let mut reader = BufReader::new(file); // If not at start of file, read and discard partial word if start > 0 { let mut partial = String::new(); reader.read_line(&mut partial).unwrap(); } let mut content = String::new(); let mut bytes_read = 0; while bytes_read < end - start { let mut line = String::new(); let read = reader.read_line(&mut line).unwrap(); if read == 0 { break; } bytes_read += read as u64; if bytes_read > end - start { // Trim the last line if we've read too much line.truncate((read - (bytes_read - (end - start)) as usize) as usize); } content.push_str(&line); } let counts = count_words(&content); to_json(&counts) }); handles.push(handle); } for handle in handles { match handle.join() { Ok(json) => println!("{}", json), Err(_) => eprintln!("Thread panicked"), } } } |
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::{BufRead, BufReader, Read, Seek, SeekFrom}; use std::thread; fn count_words(text: &str) -> HashMap<String, usize> { let mut word_counts = HashMap::new(); for word in text.split_whitespace() { let count = word_counts.entry(word.to_string()).or_insert(0); *count += 1; } word_counts } fn to_json(map: &HashMap<String, usize>) -> String { let mut result = String::from("{"); let mut first = true; for (key, value) in map.iter() { if !first { result.push_str(", "); } first = false; result.push('"'); result.push_str(key); result.push_str("\": "); result.push_str(&value.to_string()); } result.push('}'); result } fn main() { let file = File::open("/tmp/file.txt").unwrap(); let file_size = file.metadata().unwrap().len(); let chunk_size = file_size / 4; let mut handles = vec![]; for i in 0..4 { let mut file = File::open("/tmp/file.txt").unwrap(); let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; let handle = thread::spawn(move || { file.seek(SeekFrom::Start(start)).unwrap(); let mut reader = BufReader::new(file); // If not at start of file, read and discard partial word if start > 0 { let mut partial = String::new(); reader.read_line(&mut partial).unwrap(); } let mut content = String::new(); let mut bytes_read = 0; while bytes_read < end - start { let mut line = String::new(); let read = reader.read_line(&mut line).unwrap(); if read == 0 { break; } bytes_read += read as u64; if bytes_read > end - start { // Trim the last line if we've read too much line.truncate((read - (bytes_read - (end - start)) as usize) as usize); } content.push_str(&line); } let counts = count_words(&content); to_json(&counts) }); handles.push(handle); } for handle in handles { match handle.join() { Ok(json) => println!("{}", json), Err(_) => eprintln!("Thread panicked"), } } } 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 84 85 | use std::collections::HashMap; use std::fs::File; use std::io::{BufRead, BufReader, Read, Seek, SeekFrom}; use std::thread; fn count_words(text: &str) -> HashMap<String, usize> { let mut word_counts = HashMap::new(); for word in text.split_whitespace() { let count = word_counts.entry(word.to_string()).or_insert(0); *count += 1; } word_counts } fn to_json(map: &HashMap<String, usize>) -> String { let mut result = String::from("{"); let mut first = true; for (key, value) in map.iter() { if !first { result.push_str(", "); } first = false; result.push('"'); result.push_str(key); result.push_str("\": "); result.push_str(&value.to_string()); } result.push('}'); result } fn main() { let file = File::open("/tmp/file.txt").unwrap(); let file_size = file.metadata().unwrap().len(); let chunk_size = file_size / 4; let mut handles = vec![]; for i in 0..4 { let mut file = File::open("/tmp/file.txt").unwrap(); let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; let handle = thread::spawn(move || { file.seek(SeekFrom::Start(start)).unwrap(); let mut reader = BufReader::new(file); // If not at start of file, read and discard partial word if start > 0 { let mut partial = String::new(); reader.read_line(&mut partial).unwrap(); } let mut content = String::new(); let mut bytes_read = 0; while bytes_read < end - start { let mut line = String::new(); let read = reader.read_line(&mut line).unwrap(); if read == 0 { break; } bytes_read += read as u64; if bytes_read > end - start { // Trim the last line if we've read too much line.truncate((read - (bytes_read - (end - start)) as usize) as usize); } content.push_str(&line); } let counts = count_words(&content); to_json(&counts) }); handles.push(handle); } for handle in handles { match handle.join() { Ok(json) => println!("{}", json), Err(_) => eprintln!("Thread panicked"), } } } |
{"the": 4, "wisdom,": 1, "foolish": 1, "times,": 2, "it": 4, "was": 4, "of": 4, "worst": 1, "age": 2, "best": 1}
{}
{}
{}
warning: unused import: `Read`
--> main.rs:4:35
|
4 | use std::io::{BufRead, BufReader, Read, Seek, SeekFrom};
| ^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: 1 warning emitted
Resulting in output: [('age', 2), ('best', 1), ('foolish', 1), ('it', 4), ('of', 4), ('the', 4), ('times,', 2), ('was', 4), ('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 self-contained Rust program that processes a text file in parallel and outputs word counts as JSON for each chunk:
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 | use std::collections::HashMap; use std::fs::File; use std::io::{BufRead, BufReader, Read, Seek, SeekFrom}; use std::thread; fn main() { let file = File::open("/tmp/file.txt").expect("Failed to open file"); let file_size = file.metadata().expect("Failed to get metadata").len(); let chunk_size = file_size / 4; let mut handles = vec![]; for i in 0..4 { let mut file = file.try_clone().expect("Failed to clone file handle"); let handle = thread::spawn(move || { let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; file.seek(SeekFrom::Start(start)).expect("Failed to seek"); let mut reader = BufReader::new(file); // Skip partial word at start (except for first chunk) if i > 0 { let mut first_line = String::new(); reader.read_line(&mut first_line).expect("Failed to read line"); } let mut word_counts = HashMap::new(); let mut content = String::new(); reader.take(end - start).read_to_string(&mut content).expect("Failed to read chunk"); for word in content.split_whitespace() { *word_counts.entry(word.to_string()).or_insert(0) += 1; } // Convert HashMap to JSON string manually let mut json = String::from("{"); let mut first = true; for (word, count) in word_counts.iter() { if !first { json.push_str(", "); } first = false; json.push('"'); json.push_str(word); json.push_str("\": "); json.push_str(&count.to_string()); } json.push('}'); json }); handles.push(handle); } // Print results from each thread for handle in handles { match handle.join() { Ok(json) => println!("{}", json), Err(_) => eprintln!("Thread panicked"), } } } |
1 2 | rustc wordcount.rs
./wordcount
|
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 | use std::collections::HashMap; use std::fs::File; use std::io::{BufRead, BufReader, Read, Seek, SeekFrom}; use std::thread; fn main() { let file = File::open("/tmp/file.txt").expect("Failed to open file"); let file_size = file.metadata().expect("Failed to get metadata").len(); let chunk_size = file_size / 4; let mut handles = vec![]; for i in 0..4 { let mut file = file.try_clone().expect("Failed to clone file handle"); let handle = thread::spawn(move || { let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; file.seek(SeekFrom::Start(start)).expect("Failed to seek"); let mut reader = BufReader::new(file); // Skip partial word at start (except for first chunk) if i > 0 { let mut first_line = String::new(); reader.read_line(&mut first_line).expect("Failed to read line"); } let mut word_counts = HashMap::new(); let mut content = String::new(); reader.take(end - start).read_to_string(&mut content).expect("Failed to read chunk"); for word in content.split_whitespace() { *word_counts.entry(word.to_string()).or_insert(0) += 1; } // Convert HashMap to JSON string manually let mut json = String::from("{"); let mut first = true; for (word, count) in word_counts.iter() { if !first { json.push_str(", "); } first = false; json.push('"'); json.push_str(word); json.push_str("\": "); json.push_str(&count.to_string()); } json.push('}'); json }); handles.push(handle); } // Print results from each thread for handle in handles { match handle.join() { Ok(json) => println!("{}", json), Err(_) => eprintln!("Thread panicked"), } } } |
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::{BufRead, BufReader, Read, Seek, SeekFrom}; use std::thread; fn main() { let file = File::open("/tmp/file.txt").expect("Failed to open file"); let file_size = file.metadata().expect("Failed to get metadata").len(); let chunk_size = file_size / 4; let mut handles = vec![]; for i in 0..4 { let mut file = file.try_clone().expect("Failed to clone file handle"); let handle = thread::spawn(move || { let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; file.seek(SeekFrom::Start(start)).expect("Failed to seek"); let mut reader = BufReader::new(file); // Skip partial word at start (except for first chunk) if i > 0 { let mut first_line = String::new(); reader.read_line(&mut first_line).expect("Failed to read line"); } let mut word_counts = HashMap::new(); let mut content = String::new(); reader.take(end - start).read_to_string(&mut content).expect("Failed to read chunk"); for word in content.split_whitespace() { *word_counts.entry(word.to_string()).or_insert(0) += 1; } // Convert HashMap to JSON string manually let mut json = String::from("{"); let mut first = true; for (word, count) in word_counts.iter() { if !first { json.push_str(", "); } first = false; json.push('"'); json.push_str(word); json.push_str("\": "); json.push_str(&count.to_string()); } json.push('}'); json }); handles.push(handle); } // Print results from each thread for handle in handles { match handle.join() { Ok(json) => println!("{}", json), Err(_) => eprintln!("Thread panicked"), } } } 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 | use std::collections::HashMap; use std::fs::File; use std::io::{BufRead, BufReader, Read, Seek, SeekFrom}; use std::thread; fn main() { let file = File::open("/tmp/file.txt").expect("Failed to open file"); let file_size = file.metadata().expect("Failed to get metadata").len(); let chunk_size = file_size / 4; let mut handles = vec![]; for i in 0..4 { let mut file = file.try_clone().expect("Failed to clone file handle"); let handle = thread::spawn(move || { let start = i * chunk_size; let end = if i == 3 { file_size } else { (i + 1) * chunk_size }; file.seek(SeekFrom::Start(start)).expect("Failed to seek"); let mut reader = BufReader::new(file); // Skip partial word at start (except for first chunk) if i > 0 { let mut first_line = String::new(); reader.read_line(&mut first_line).expect("Failed to read line"); } let mut word_counts = HashMap::new(); let mut content = String::new(); reader.take(end - start).read_to_string(&mut content).expect("Failed to read chunk"); for word in content.split_whitespace() { *word_counts.entry(word.to_string()).or_insert(0) += 1; } // Convert HashMap to JSON string manually let mut json = String::from("{"); let mut first = true; for (word, count) in word_counts.iter() { if !first { json.push_str(", "); } first = false; json.push('"'); json.push_str(word); json.push_str("\": "); json.push_str(&count.to_string()); } json.push('}'); json }); handles.push(handle); } // Print results from each thread for handle in handles { match handle.join() { Ok(json) => println!("{}", json), Err(_) => eprintln!("Thread panicked"), } } } |
{"worst": 1, "was": 4, "age": 2, "times,": 2, "of": 4, "wisdom,": 1, "the": 4, "foolish": 1, "best": 1, "it": 4}
{}
{"us,": 2, "going": 2, "nothing": 1, "had": 1, "the": 1, "to": 1, "other": 1, "way": 1, "before": 1, "were": 2, "all": 2, "direct": 2, "Heaven,": 1, "we": 3}
{}
Resulting in output: [('Heaven,', 1), ('age', 2), ('all', 2), ('before', 1), ('best', 1), ('direct', 2), ('foolish', 1), ('going', 2), ('had', 1), ('it', 4), ('nothing', 1), ('of', 4), ('other', 1), ('the', 5), ('times,', 2), ('to', 1), ('us,', 2), ('was', 4), ('way', 1), ('we', 3), ('were', 2), ('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 those 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::collections::HashMap; use std::fs::File; use std::io::{BufRead, BufReader, Seek, SeekFrom}; use std::sync::{Arc, Mutex}; use std::thread; fn main() { // Open the file let file = File::open("/tmp/file.txt").expect("Could not open file"); let file_len = file.metadata().expect("Could not get metadata").len(); // Calculate chunk sizes let chunk_size = file_len / 4; let mut handles = vec![]; // Create 4 threads for i in 0..4 { let mut file = file.try_clone().expect("Could not clone file handle"); let handle = thread::spawn(move || { let mut word_counts = HashMap::new(); let start_pos = i * chunk_size; let end_pos = if i == 3 { file_len } else { (i + 1) * chunk_size }; // Seek to the starting position file.seek(SeekFrom::Start(start_pos)).expect("Could not seek"); let reader = BufReader::new(file); // Read and count words let mut current_pos = start_pos; for line in reader.lines() { if current_pos >= end_pos { break; } if let Ok(line) = line { current_pos += line.len() as u64 + 1; // +1 for newline for word in line.split_whitespace() { *word_counts.entry(word.to_string()).or_insert(0) += 1; } } } // Convert HashMap to JSON string manually 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_str("}"); json }); handles.push(handle); } // Wait for all threads and print results for handle in handles { if let Ok(json) = handle.join() { println!("{}", json); } } } |
1 2 | rustc wordcount.rs
./wordcount
|
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 | use std::collections::HashMap; use std::fs::File; use std::io::{BufRead, BufReader, Seek, SeekFrom}; use std::thread; fn main() { // Open the file let file = File::open("/tmp/file.txt").expect("Could not open file"); let file_len = file.metadata().expect("Could not get metadata").len(); // Calculate chunk sizes let chunk_size = file_len / 4; let mut handles = vec![]; // Create 4 threads for i in 0..4 { let mut file = file.try_clone().expect("Could not clone file handle"); let handle = thread::spawn(move || { let mut word_counts = HashMap::new(); let start_pos = i * chunk_size; let end_pos = if i == 3 { file_len } else { (i + 1) * chunk_size }; // Seek to the starting position file.seek(SeekFrom::Start(start_pos)).expect("Could not seek"); let reader = BufReader::new(file); // Read and count words let mut current_pos = start_pos; for line in reader.lines() { if current_pos >= end_pos { break; } if let Ok(line) = line { current_pos += line.len() as u64 + 1; // +1 for newline for word in line.split_whitespace() { *word_counts.entry(word.to_string()).or_insert(0) += 1; } } } // Convert HashMap to JSON string manually 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_str("}"); json }); handles.push(handle); } // Wait for all threads and print results for handle in handles { if let Ok(json) = handle.join() { println!("{}", json); } } } |
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::{BufRead, BufReader, Seek, SeekFrom}; use std::thread; fn main() { // Open the file let file = File::open("/tmp/file.txt").expect("Could not open file"); let file_len = file.metadata().expect("Could not get metadata").len(); // Calculate chunk sizes let chunk_size = file_len / 4; let mut handles = vec![]; // Create 4 threads for i in 0..4 { let mut file = file.try_clone().expect("Could not clone file handle"); let handle = thread::spawn(move || { let mut word_counts = HashMap::new(); let start_pos = i * chunk_size; let end_pos = if i == 3 { file_len } else { (i + 1) * chunk_size }; // Seek to the starting position file.seek(SeekFrom::Start(start_pos)).expect("Could not seek"); let reader = BufReader::new(file); // Read and count words let mut current_pos = start_pos; for line in reader.lines() { if current_pos >= end_pos { break; } if let Ok(line) = line { current_pos += line.len() as u64 + 1; // +1 for newline for word in line.split_whitespace() { *word_counts.entry(word.to_string()).or_insert(0) += 1; } } } // Convert HashMap to JSON string manually 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_str("}"); json }); handles.push(handle); } // Wait for all threads and print results for handle in handles { if let Ok(json) = handle.join() { println!("{}", json); } } } 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 | use std::collections::HashMap; use std::fs::File; use std::io::{BufRead, BufReader, Seek, SeekFrom}; use std::thread; fn main() { // Open the file let file = File::open("/tmp/file.txt").expect("Could not open file"); let file_len = file.metadata().expect("Could not get metadata").len(); // Calculate chunk sizes let chunk_size = file_len / 4; let mut handles = vec![]; // Create 4 threads for i in 0..4 { let mut file = file.try_clone().expect("Could not clone file handle"); let handle = thread::spawn(move || { let mut word_counts = HashMap::new(); let start_pos = i * chunk_size; let end_pos = if i == 3 { file_len } else { (i + 1) * chunk_size }; // Seek to the starting position file.seek(SeekFrom::Start(start_pos)).expect("Could not seek"); let reader = BufReader::new(file); // Read and count words let mut current_pos = start_pos; for line in reader.lines() { if current_pos >= end_pos { break; } if let Ok(line) = line { current_pos += line.len() as u64 + 1; // +1 for newline for word in line.split_whitespace() { *word_counts.entry(word.to_string()).or_insert(0) += 1; } } } // Convert HashMap to JSON string manually 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_str("}"); json }); handles.push(handle); } // Wait for all threads and print results for handle in handles { if let Ok(json) = handle.join() { println!("{}", json); } } } |
{"epoch": 2, "the": 11, "best": 1, "spring": 1, "us,": 2, "had": 2, "to": 1, "age": 2, "foolishness,": 1, "despair,": 1, "all": 2, "of": 10, "direct": 2, "before": 2, "Darkness,": 1, "was": 10, "everything": 1, "times,": 2, "nothing": 1, "wisdom,": 1, "we": 4, "worst": 1, "incredulity,": 1, "Light,": 1, "winter": 1, "Heaven,": 1, "going": 2, "way": 1, "it": 10, "hope,": 1, "were": 2, "belief,": 1, "season": 2, "other": 1}
{}
{"was": 2, "spring": 1, "Darkness,": 1, "winter": 1, "the": 3, "we": 4, "everything": 1, "all": 2, "going": 2, "direct": 2, "despair,": 1, "to": 1, "way": 1, "season": 1, "Heaven,": 1, "other": 1, "had": 2, "e": 1, "of": 3, "it": 2, "hope,": 1, "before": 2, "us,": 2, "nothing": 1, "were": 2}
{"belief,": 1, "ness,": 1, "of": 6, "it": 6, "was": 6, "Darkness,": 1, "epoch": 2, "incredulity,": 1, "nothing": 1, "spring": 1, "were": 2, "us,": 2, "season": 2, "had": 2, "direct": 2, "Light,": 1, "everything": 1, "all": 2, "hope,": 1, "despair,": 1, "Heaven,": 1, "other": 1, "the": 7, "winter": 1, "before": 2, "going": 2, "way": 1, "to": 1, "we": 4}
Resulting in output: [('Darkness,', 3), ('Heaven,', 3), ('Light,', 2), ('age', 2), ('all', 6), ('before', 6), ('belief,', 2), ('best', 1), ('despair,', 3), ('direct', 6), ('e', 1), ('epoch', 4), ('everything', 3), ('foolishness,', 1), ('going', 6), ('had', 6), ('hope,', 3), ('incredulity,', 2), ('it', 18), ('ness,', 1), ('nothing', 3), ('of', 19), ('other', 3), ('season', 5), ('spring', 3), ('the', 21), ('times,', 2), ('to', 3), ('us,', 6), ('was', 18), ('way', 3), ('we', 12), ('were', 6), ('winter', 3), ('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