Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Write is_palindrome(s: &str) -> bool. Consider only ASCII letters and digits, ignoring ASCII case and every other character. A string with none of those characters is a palindrome.
pub fn is_palindrome(s: &str) -> bool {
let chars: Vec<char> = s
.chars()
.filter(|c| c.is_ascii_alphanumeric())
.map(|c| c.to_ascii_lowercase())
.collect();
let len = chars.len();
for i in 0..len / 2 {
if chars[i] != chars[len - 1 - i] {
return false;
}
}
true
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Write is_palindrome(s: &str) -> bool. Consider only ASCII letters and digits, ignoring ASCII case and every other character. A string with none of those characters is a palindrome.
pub fn is_palindrome(s: &str) -> bool {
let chars: Vec<char> = s
.chars()
.filter(|c| c.is_ascii_alphanumeric())
.flat_map(|c| {
if c.is_ascii_uppercase() {
vec![c.to_ascii_lowercase()]
} else if c.is_ascii_lowercase() {
vec![c]
} else {
vec![]
}
})
.collect();
let len = chars.len();
for i in 0..len / 2 {
if chars[i] != chars[len - 1 - i] {
return false;
}
}
true
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Write is_palindrome(s: &str) -> bool. Consider only ASCII letters and digits, ignoring ASCII case and every other character. A string with none of those characters is a palindrome.
pub fn is_palindrome(s: &str) -> bool {
let mut chars: Vec<char> = s
.chars()
.filter(|c| c.is_ascii_alphanumeric())
.map(|c| c.to_ascii_lowercase())
.collect();
let mut left = 0;
let mut right = chars.len().checked_sub(1).unwrap_or(0);
while left < right {
if chars[left] != chars[right] {
return false;
}
left += 1;
right -= 1;
}
true
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Write word_count(text: &str) -> HashMap<String, usize>, importing HashMap yourself. Words are separated by any whitespace and compared in lowercase, and the map's keys are lowercase. Punctuation is part of a word.
use std::collections::HashMap;
use std::str::Chars;
pub fn word_count(text: &str) -> HashMap<String, usize> {
let mut counts: HashMap<String, usize> = HashMap::new();
let mut current_word = String::new();
let mut chars = text.chars();
while let Some(ch) = chars.next() {
if !ch.is_whitespace() {
current_word.push(ch);
} else if !current_word.is_empty() {
let word = current_word.to_lowercase();
*counts.entry(word).or_insert(0) += 1;
current_word.clear();
}
}
if !current_word.is_empty() {
let word = current_word.to_lowercase();
*counts.entry(word).or_insert(0) += 1;
}
counts
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Write word_count(text: &str) -> HashMap<String, usize>, importing HashMap yourself. Words are separated by any whitespace and compared in lowercase, and the map's keys are lowercase. Punctuation is part of a word.
use std::collections::HashMap;
pub fn word_count(text: &str) -> HashMap<String, usize> {
let mut counts = HashMap::new();
for word in text.split_whitespace() {
let key = word.to_lowercase();
*counts.entry(key).or_insert(0) += 1;
}
counts
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Write word_count(text: &str) -> HashMap<String, usize>, importing HashMap yourself. Words are separated by any whitespace and compared in lowercase, and the map's keys are lowercase. Punctuation is part of a word.
use std::collections::HashMap;
pub fn word_count(text: &str) -> HashMap<String, usize> {
let mut counts = HashMap::new();
let chars: Vec<char> = text.chars().filter(|c| !c.is_whitespace()).collect();
let mut current_word = String::new();
for c in chars {
if c == '\n' || c == '\r' || c == '\t' || c == ' ' || c == '\u{0009}' || c == '\u{000b}' || c == '\u{000c}' {
if !current_word.is_empty() {
let key = current_word.to_lowercase();
*counts.entry(key).or_insert(0) += 1;
current_word.clear();
}
} else if c.is_alphabetic() || c.is_ascii_punctuation() {
if c.is_ascii_punctuation() {
// Punctuation is kept as part of the word
} else {
if !current_word.is_ascii_alphabetic() {
// If we have non-alpha chars that aren't punctuation, we still treat as part of word based on "punctuation is part of a word" but whitespace separates.
// Wait, re-reading: "Punctuation is part of a word".
// Usually this means 'don't split on punctuation'.
// But what about digits or symbols? The prompt implies standard words.
// Let's assume alphanumeric + punctuation forms a token, separated by whitespace.
// However, standard interpretation of "word" usually implies alphanumeric.
// Given "Punctuation is part of a word", let's include alphanumeric and punctuation.
// But wait, if I have "hello-world", is that one word? Yes, hyphen is punctuation.
// If I have "hello123", is that one word? Yes.
// So the rule is: split ONLY on whitespace. Everything else is part of the word.
// Then convert the whole thing to lowercase.
}
}
current_word.push(c);
} else {
// This handles characters that are not whitespace and not explicitly alpha/punc?
// Actually, the prompt says "Words are separated by any whitespace".
// It implies that anything non-whitespace is part of a word.
// So we just accumulate until we hit whitespace.
// But we need to handle the separation correctly.
// Let's simplify: iterate chars. If whitespace, flush. Else, append.
// Then flush at end.
// The condition "Punctuation is part of a word" confirms we don't split on punctuation.
// So simply: split by whitespace, then lowercase each chunk.
flush(&mut counts, &mut current_word);
}
}
flush(&mut counts, &mut current_word);
counts
}
fn flush(counts: &mut HashMap<String, usize>, word: &mut String) {
if !word.is_empty() {
let key = word.to_lowercase();
*counts.entry(key).or_insert(0) += 1;
word.clear();
}
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Write longest, which takes two string slices and returns the longer one by str::len without allocating. On a tie, it returns the first. Its result must be usable as long as both inputs are alive.
pub fn longest<'a>(a: &'a str, b: &'a str) -> &'a str {
if a.len() >= b.len() {
a
} else {
b
}
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Write longest, which takes two string slices and returns the longer one by str::len without allocating. On a tie, it returns the first. Its result must be usable as long as both inputs are alive.
pub fn longest(a: &str, b: &str) -> &str {
if a.len() >= b.len() {
a
} else {
b
}
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Write longest, which takes two string slices and returns the longer one by str::len without allocating. On a tie, it returns the first. Its result must be usable as long as both inputs are alive.
pub fn longest<'a>(a: &'a str, b: &'a str) -> &'a str {
if a.len() >= b.len() {
a
} else {
b
}
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Write parse_pair<T: FromStr>(s: &str, sep: char) -> Option<(T, T)>, importing FromStr yourself. Split s at the first occurrence of sep and parse both sides as T. Return None if sep does not occur or if either side fails to parse. sep may be any Unicode character. parse_pair::<u32>("400x600", 'x') returns Some((400, 600)).
use std::str::FromStr;
pub fn parse_pair<T: FromStr>(s: &str, sep: char) -> Option<(T, T)> {
match s.find(sep) {
Some(index) => {
let (left_str, right_str) = s.split_at(index);
let (left_str, right_str) = (right_str.trim_start(), left_str.trim_end());
match T::from_str(left_str) {
Ok(left) => {
match T::from_str(right_str) {
Ok(right) => Some((left, right)),
Err(_) => None,
}
}
Err(_) => None,
}
}
None => None,
}
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Write parse_pair<T: FromStr>(s: &str, sep: char) -> Option<(T, T)>, importing FromStr yourself. Split s at the first occurrence of sep and parse both sides as T. Return None if sep does not occur or if either side fails to parse. sep may be any Unicode character. parse_pair::<u32>("400x600", 'x') returns Some((400, 600)).
use std::str::FromStr;
pub fn parse_pair<T: FromStr>(s: &str, sep: char) -> Option<(T, T)> {
let parts: Vec<&str> = s.splitn(2, sep).collect();
if parts.len() != 2 {
return None;
}
match (T::from_str(parts[0]), T::from_str(parts[1])) {
(Ok(a), Ok(b)) => Some((a, b)),
_ => None,
}
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Write parse_pair<T: FromStr>(s: &str, sep: char) -> Option<(T, T)>, importing FromStr yourself. Split s at the first occurrence of sep and parse both sides as T. Return None if sep does not occur or if either side fails to parse. sep may be any Unicode character. parse_pair::<u32>("400x600", 'x') returns Some((400, 600)).
use std::str::FromStr;
#[inline]
pub fn parse_pair<T: FromStr>(s: &str, sep: char) -> Option<(T, T)> {
let mut parts = s.splitn(2, sep);
let first = parts.next()?;
let second = parts.next()?;
if first.is_empty() || second.is_empty() {
return None;
}
let left = T::from_str(first).ok()?;
let right = T::from_str(second).ok()?;
Some((left, right))
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Write compose(f, g), generic over the argument and result types. f and g are closures implementing Fn. It returns a closure implementing Fn that maps x to g(f(x)), and the returned closure must be usable after the function that called compose has returned.
pub fn compose<F, G, A, R>(f: F, g: G) -> impl Fn(A) -> R + 'static
where
F: Fn(A) -> R + 'static,
G: Fn(R) -> R + 'static,
{
move |x: A| g(f(x))
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Write compose(f, g), generic over the argument and result types. f and g are closures implementing Fn. It returns a closure implementing Fn that maps x to g(f(x)), and the returned closure must be usable after the function that called compose has returned.
pub fn compose<F, G, A, B>(f: F, g: G) -> impl Fn(A) -> B + 'static
where
F: Fn(A) -> B + 'static,
G: Fn(B) -> A + 'static,
{
move |x| g(f(x))
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Write compose(f, g), generic over the argument and result types. f and g are closures implementing Fn. It returns a closure implementing Fn that maps x to g(f(x)), and the returned closure must be usable after the function that called compose has returned.
pub fn compose<F, G, A, B>(f: F, g: G) -> impl Fn(A) -> B
where
F: Fn(B) -> A + 'static,
G: Fn(A) -> B + 'static,
{
move |x| g(f(x))
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Define Fib, with a constructor Fib::new(), and implement Iterator<Item = u64> for it. It yields the Fibonacci numbers 0, 1, 1, 2, 3, 5, and so on. It yields every Fibonacci number that fits in a u64, then None from then on. Tests run with overflow checks on.
pub struct Fib {
state: [u64; 3],
}
impl Fib {
pub fn new() -> Self {
Fib {
state: [0, 1, 0],
}
}
}
impl Iterator for Fib {
type Item = u64;
fn next(&mut self) -> Option<Self::Item> {
let a = self.state[0];
let b = self.state[1];
let sum = a.checked_add(b)?;
self.state[0] = self.state[1];
self.state[1] = sum;
Some(a)
}
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Define Fib, with a constructor Fib::new(), and implement Iterator<Item = u64> for it. It yields the Fibonacci numbers 0, 1, 1, 2, 3, 5, and so on. It yields every Fibonacci number that fits in a u64, then None from then on. Tests run with overflow checks on.
pub struct Fib {
a: u64,
b: u64,
}
impl Fib {
pub fn new() -> Self {
Fib { a: 0, b: 1 }
}
}
impl Iterator for Fib {
type Item = u64;
fn next(&mut self) -> Option<Self::Item> {
if self.a > u64::MAX {
return None;
}
let next = self.a;
let (self.a, self.b) = (self.b, self.a.saturating_add(self.b));
Some(next)
}
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Define Fib, with a constructor Fib::new(), and implement Iterator<Item = u64> for it. It yields the Fibonacci numbers 0, 1, 1, 2, 3, 5, and so on. It yields every Fibonacci number that fits in a u64, then None from then on. Tests run with overflow checks on.
pub struct Fib {
current: u64,
next: u64,
done: bool,
}
impl Fib {
pub fn new() -> Self {
Self {
current: 0,
next: 1,
done: false,
}
}
}
impl Iterator for Fib {
type Item = u64;
fn next(&mut self) -> Option<Self::Item> {
if self.done {
return None;
}
let result = self.current;
// Check for overflow before adding
if self.next.checked_add(self.current).is_none() {
self.done = true;
return None;
}
let (new_current, new_next) = (self.next, self.next + self.current);
self.current = new_current;
self.next = new_next;
Some(result)
}
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Define enum TempError deriving Debug, with the variants Empty, BadUnit(char), and BadNumber(std::num::ParseFloatError), and write parse_temp(s: &str) -> Result<f64, TempError>. The input is a number followed by one unit character, C or F, and the result is in Celsius, so "212F" returns 100.0. An empty string gives Empty. If the last character is neither C nor F, it gives BadUnit with that character, which may be non-ASCII. A number that does not parse gives BadNumber. Implement Display and std::error::Error for TempError, with source() returning the parse error for BadNumber, and implement From<std::num::ParseFloatError> for it.
use std::fmt;
use std::num::ParseFloatError;
#[derive(Debug)]
pub enum TempError {
Empty,
BadUnit(char),
BadNumber(ParseFloatError),
}
impl fmt::Display for TempError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TempError::Empty => write!(f, "Input string is empty"),
TempError::BadUnit(unit) => write!(f, "Invalid unit character: {}", unit),
TempError::BadNumber(e) => write!(f, "Failed to parse number: {}", e),
}
}
}
impl std::error::Error for TempError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
TempError::BadNumber(ref e) => Some(e),
_ => None,
}
}
}
impl From<ParseFloatError> for TempError {
fn from(err: ParseFloatError) -> Self {
TempError::BadNumber(err)
}
}
pub fn parse_temp(s: &str) -> Result<f64, TempError> {
if s.is_empty() {
return Err(TempError::Empty);
}
let unit_char = s.chars().last().unwrap();
if unit_char != 'C' && unit_char != 'F' {
return Err(TempError::BadUnit(unit_char));
}
let number_part = &s[..s.len() - 1];
let celsius = number_part.parse::<f64>().map_err(TempError::from)?;
if unit_char == 'F' {
Ok(celsius * 5.0 / 9.0 + 32.0 - 32.0)
} else {
Ok(celsius)
}
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Define enum TempError deriving Debug, with the variants Empty, BadUnit(char), and BadNumber(std::num::ParseFloatError), and write parse_temp(s: &str) -> Result<f64, TempError>. The input is a number followed by one unit character, C or F, and the result is in Celsius, so "212F" returns 100.0. An empty string gives Empty. If the last character is neither C nor F, it gives BadUnit with that character, which may be non-ASCII. A number that does not parse gives BadNumber. Implement Display and std::error::Error for TempError, with source() returning the parse error for BadNumber, and implement From<std::num::ParseFloatError> for it.
use std::error::Error;
use std::fmt;
use std::num::ParseFloatError;
#[derive(Debug)]
pub enum TempError {
Empty,
BadUnit(char),
BadNumber(ParseFloatError),
}
impl fmt::Display for TempError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TempError::Empty => write!(f, "Temperature string is empty"),
TempError::BadUnit(unit) => write!(f, "Invalid unit character: {}", unit),
TempError::BadNumber(err) => write!(f, "Failed to parse number: {}", err),
}
}
}
impl Error for TempError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
TempError::BadNumber(err) => Some(err),
_ => None,
}
}
}
impl From<ParseFloatError> for TempError {
fn from(err: ParseFloatError) -> Self {
TempError::BadNumber(err)
}
}
pub fn parse_temp(s: &str) -> Result<f64, TempError> {
if s.is_empty() {
return Err(TempError::Empty);
}
let unit = s.chars().last().unwrap();
if unit != 'C' && unit != 'F' {
return Err(TempError::BadUnit(unit));
}
let prefix = &s[..s.len() - 1];
let celsius: f64 = prefix.parse::<f64>().map_err(TempError::from)?;
if unit == 'F' {
let celsius = (celsius - 32.0) * 5.0 / 9.0;
Ok(celsius)
} else {
Ok(celsius)
}
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Define enum TempError deriving Debug, with the variants Empty, BadUnit(char), and BadNumber(std::num::ParseFloatError), and write parse_temp(s: &str) -> Result<f64, TempError>. The input is a number followed by one unit character, C or F, and the result is in Celsius, so "212F" returns 100.0. An empty string gives Empty. If the last character is neither C nor F, it gives BadUnit with that character, which may be non-ASCII. A number that does not parse gives BadNumber. Implement Display and std::error::Error for TempError, with source() returning the parse error for BadNumber, and implement From<std::num::ParseFloatError> for it.
use std::fmt;
use std::num::ParseFloatError;
use std::error::Error;
#[derive(Debug)]
pub enum TempError {
Empty,
BadUnit(char),
BadNumber(ParseFloatError),
}
impl fmt::Display for TempError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TempError::Empty => write!(f, "Empty input"),
TempError::BadUnit(unit) => write!(f, "Invalid unit: {}", unit),
TempError::BadNumber(_) => write!(f, "Failed to parse number"),
}
}
}
impl Error for TempError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
TempError::BadNumber(ref err) => Some(err),
_ => None,
}
}
}
impl From<ParseFloatError> for TempError {
fn from(err: ParseFloatError) -> Self {
TempError::BadNumber(err)
}
}
pub fn parse_temp(s: &str) -> Result<f64, TempError> {
if s.is_empty() {
return Err(TempError::Empty);
}
let last_char = s.chars().last().unwrap();
if last_char != 'C' && last_char != 'F' {
return Err(TempError::BadUnit(last_char));
}
let num_str = &s[..s.len() - 1];
let celsius = num_str.parse::<f64>()?;
// Convert to Celsius if input was Fahrenheit
if last_char == 'F' {
let fahrenheit = celsius;
let celsius = (fahrenheit - 32.0) * 5.0 / 9.0;
return Ok(celsius);
}
Ok(celsius)
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Write parallel_sum(data: &[u64], workers: usize) -> u64, which sums data by splitting it across workers threads from std::thread. data is a borrowed slice, and workers may be larger than data.len(). It returns 0 for an empty slice and panics when workers is 0, including when the slice is empty.
use std::thread;
use std::sync::{Arc, Mutex};
pub fn parallel_sum(data: &[u64], workers: usize) -> u64 {
if workers == 0 {
panic!("workers must be greater than 0");
}
let len = data.len();
if len == 0 {
return 0;
}
let chunks_per_worker = (len + workers - 1) / workers;
let mut parts = Vec::with_capacity(workers);
for i in 0..workers {
let start = i * chunks_per_worker;
let end = if i == workers - 1 {
len
} else {
(i + 1) * chunks_per_worker
};
if start >= len {
break;
}
let slice = &data[start..end];
let sum = Arc::new(Mutex::new(0u64));
let inner_sum = Arc::new(Mutex::new(slice.iter().sum::<u64>()));
let sum_ref = Arc::clone(&sum);
thread::spawn(move || {
*sum_ref.lock().unwrap() = inner_sum.lock().unwrap().clone();
});
parts.push(sum);
}
let total = Arc::new(Mutex::new(0u64));
for part in parts {
let chunk_sum = part.lock().unwrap().clone();
let total_ref = Arc::clone(&total);
thread::spawn(move || {
*total_ref.lock().unwrap() += chunk_sum;
});
}
*total.lock().unwrap()
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Write parallel_sum(data: &[u64], workers: usize) -> u64, which sums data by splitting it across workers threads from std::thread. data is a borrowed slice, and workers may be larger than data.len(). It returns 0 for an empty slice and panics when workers is 0, including when the slice is empty.
use std::thread;
use std::sync::mpsc;
pub fn parallel_sum(data: &[u64], workers: usize) -> u64 {
if workers == 0 {
panic!("workers cannot be zero");
}
if data.is_empty() {
return 0;
}
let (tx, rx) = mpsc::channel();
let len = data.len() as u64;
let chunk_size = (len + (workers as u64) - 1) / workers as u64;
let mut indices = vec![0u64; workers];
let mut current = 0u64;
for i in 0..workers {
if current >= len {
break;
}
let end = (current + chunk_size).min(len);
indices[i] = current;
current = end;
}
// Ensure all workers get an assignment if possible, or some get empty ranges
while current < len {
let worker_idx = indices.iter().position(|&x| x == len).unwrap_or(workers - 1);
// This logic is slightly flawed for exact distribution; let's redo cleanly.
}
// Cleaner chunk calculation
let mut chunks = Vec::with_capacity(workers);
let mut start = 0;
for _ in 0..workers {
if start >= len {
break;
}
let end = (start + chunk_size).min(len);
if start < end {
chunks.push((start, end));
} else {
// Distribute remaining elements to first available chunk
if let Some((s, e)) = chunks.last_mut() {
if *e < len {
*e = len;
}
}
}
start = end;
}
// Actually, simpler: just iterate and push ranges
chunks.clear();
start = 0;
for _ in 0..workers {
if start >= len {
break;
}
let end = (start + chunk_size).min(len);
chunks.push((start, end));
start = end;
}
// If last chunk didn't reach end, extend the previous one? No, loop handles it.
// Wait, the loop above stops when start >= len. If there are leftover items,
// the last iteration set end = len. So it's fine.
let handles: Vec<thread::JoinHandle<u64>> = chunks
.into_iter()
.map(|(start, end)| {
let tx = tx.clone();
thread::spawn(move || {
let sum: u64 = data[start..end].iter().sum();
tx.send(sum).unwrap();
sum
})
})
.collect();
let mut total = 0u64;
for handle in handles {
total += handle.join().unwrap();
}
drop(tx); // Drop original sender so rx knows when to stop
total
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Write parallel_sum(data: &[u64], workers: usize) -> u64, which sums data by splitting it across workers threads from std::thread. data is a borrowed slice, and workers may be larger than data.len(). It returns 0 for an empty slice and panics when workers is 0, including when the slice is empty.
use std::thread;
use std::sync::{Arc, Mutex};
pub fn parallel_sum(data: &[u64], workers: usize) -> u64 {
if workers == 0 {
panic!("workers cannot be zero");
}
if data.is_empty() {
return 0;
}
let len = data.len();
let chunk_size = (len + workers - 1) / workers;
let chunks: Vec<_> = data
.chunks(chunk_size)
.collect();
let handles: Vec<thread::JoinHandle<u64>> = chunks
.into_iter()
.map(|chunk| {
let handle = thread::spawn(move || chunk.iter().sum::<u64>());
handle
})
.collect();
let mut total: u64 = 0;
for handle in handles {
total += handle.join().unwrap();
}
total
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Define an extension trait PairsExt that adds a method .pairs() to every iterator whose items implement Clone. It returns a lazy iterator of consecutive overlapping pairs, so (1..4).pairs() yields (1, 2) then (2, 3). A source with fewer than two items yields nothing, and an infinite source must work.
pub trait PairsExt: Sized {
fn pairs(self) -> impl Iterator<Item = (Self::Item, Self::Item)>
where
Self: Clone,
Self::Item: Clone,
{
self.clone().try_fold(
(self.clone().next(), self.clone().next()),
|(first, second), item| {
let mut iterator = self.clone();
let _ = iterator.next(); // consume one to align
if let Some(next) = iterator.next() {
Ok((second, next))
} else {
Err((first, second))
}
},
)
}
}
impl<T> PairsExt for T
where
T: Iterator,
T::Item: Clone,
{
type Item = (T::Item, T::Item);
fn pairs(self) -> impl Iterator<Item = Self::Item>
where
Self: Clone,
{
let mut first = self.clone().next();
let mut second = self.clone().next();
Box::new(std::iter::from_fn(move || {
if let (Some(f), Some(s)) = (&first, &second) {
first = None;
second = None;
let mut iter = self.clone();
if let Some(new_first) = iter.next() {
first = Some(new_first);
if let Some(new_second) = iter.next() {
second = Some(new_second);
return Some((*f.clone(), *s.clone()));
} else {
first = None;
second = None;
}
} else {
first = None;
second = None;
}
}
None
}))
}
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Define an extension trait PairsExt that adds a method .pairs() to every iterator whose items implement Clone. It returns a lazy iterator of consecutive overlapping pairs, so (1..4).pairs() yields (1, 2) then (2, 3). A source with fewer than two items yields nothing, and an infinite source must work.
/// An extension trait for iterators that adds a method to yield consecutive overlapping pairs.
pub trait PairsExt: Iterator + Sized {
/// Returns an iterator over consecutive overlapping pairs of items.
///
/// # Returns
///
/// An iterator yielding `Option<(T, T)>` for each consecutive pair.
/// If the iterator yields fewer than two items, it yields nothing.
///
/// # Example
///
/// ```rust
/// let items = vec![1, 2, 3, 4];
/// let pairs: Vec<_> = items.iter().cloned().pairs().collect();
/// // pairs contains: Some((1, 2)), Some((2, 3)), Some((3, 4))
/// ```
fn pairs(&self) -> impl Iterator<Item = Option<(Self::Item, Self::Item)>>;
}
impl<I, T> PairsExt for I
where
I: Iterator,
T: Clone,
I::Item: Clone,
{
fn pairs(&self) -> impl Iterator<Item = Option<(Self::Item, Self::Item)>> {
self.clone()
.scan(None, |state, item| {
let prev = state.take();
state.replace(item);
prev.map(|prev| (prev, item))
})
}
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Define an extension trait PairsExt that adds a method .pairs() to every iterator whose items implement Clone. It returns a lazy iterator of consecutive overlapping pairs, so (1..4).pairs() yields (1, 2) then (2, 3). A source with fewer than two items yields nothing, and an infinite source must work.
pub trait PairsExt {
fn pairs<T>(self) -> Pairs<T>
where
Self: Sized,
T: Clone,
{
struct Pairs<I, T> {
iter: I,
prev: Option<T>,
}
impl<I, T> Iterator for Pairs<I, T>
where
I: Iterator<Item = T>,
T: Clone,
{
type Item = (T, T);
fn next(&mut self) -> Option<Self::Item> {
match self.prev.take() {
Some(prev) => {
let curr = self.iter.next()?;
Some((prev, curr))
}
None => {
self.prev = self.iter.next();
self.next()
}
}
}
}
Pairs {
iter: self,
prev: None,
}
}
}
impl<T, I> PairsExt for I
where
I: Iterator<Item = T>,
T: Clone,
{
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Define TreeNode with exactly these fields: value: i32, parent: RefCell<Weak<TreeNode>>, and children: RefCell<Vec<Rc<TreeNode>>>, importing those types from the standard library. Write TreeNode::new(value: i32) -> Rc<TreeNode>. Write TreeNode::add_child(parent: &Rc<TreeNode>, child: Rc<TreeNode>), which also sets the child's parent. Write sum(&self) -> i32, the total of this node and all its descendants, and depth(&self) -> usize, the number of ancestors, which is 0 for a root.
use std::rc::Rc;
use std::cell::RefCell;
use std::weak::Weak;
pub struct TreeNode {
pub value: i32,
pub parent: RefCell<Weak<TreeNode>>,
pub children: RefCell<Vec<Rc<TreeNode>>>,
}
impl TreeNode {
pub fn new(value: i32) -> Rc<TreeNode> {
Rc::new(TreeNode {
value,
parent: RefCell::new(Weak::new()),
children: RefCell::new(Vec::new()),
})
}
pub fn add_child(parent: &Rc<TreeNode>, child: Rc<TreeNode>) {
child.parent.borrow_mut().upgrade().unwrap();
parent.children.borrow_mut().push(child.clone());
}
pub fn sum(&self) -> i32 {
let mut total = self.value;
for child in self.children.borrow().iter() {
total += child.sum();
}
total
}
pub fn depth(&self) -> usize {
if self.parent.borrow().strong_count() == 0 {
0
} else {
1 + self.parent.borrow().upgrade().unwrap().depth()
}
}
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Define TreeNode with exactly these fields: value: i32, parent: RefCell<Weak<TreeNode>>, and children: RefCell<Vec<Rc<TreeNode>>>, importing those types from the standard library. Write TreeNode::new(value: i32) -> Rc<TreeNode>. Write TreeNode::add_child(parent: &Rc<TreeNode>, child: Rc<TreeNode>), which also sets the child's parent. Write sum(&self) -> i32, the total of this node and all its descendants, and depth(&self) -> usize, the number of ancestors, which is 0 for a root.
use std::cell::RefCell;
use std::rc::{Rc, Weak};
pub struct TreeNode {
pub value: i32,
pub parent: RefCell<Weak<TreeNode>>,
pub children: RefCell<Vec<Rc<TreeNode>>>,
}
impl TreeNode {
pub fn new(value: i32) -> Rc<TreeNode> {
Rc::new(TreeNode {
value,
parent: RefCell::new(Weak::new()),
children: RefCell::new(Vec::new()),
})
}
pub fn add_child(parent: &Rc<TreeNode>, child: Rc<TreeNode>) {
child.parent.borrow_mut().replace(Rc::downgrade(parent));
parent.children.borrow_mut().push(child);
}
pub fn sum(&self) -> i32 {
let mut total = self.value;
for child in self.children.borrow().iter() {
total += child.sum();
}
total
}
pub fn depth(&self) -> usize {
if self.parent.borrow().is_none() {
return 0;
}
let parent_weak = self.parent.borrow();
let parent_rc = match parent_weak.upgrade() {
Some(rc) => rc,
None => return 0,
};
1 + parent_rc.depth()
}
}
Write Rust for the 2024 edition on stable, using only the standard library. Answer with one ```rust code block that defines what the question describes. Do not include fn main, tests, examples, explanations, or print statements.
Define TreeNode with exactly these fields: value: i32, parent: RefCell<Weak<TreeNode>>, and children: RefCell<Vec<Rc<TreeNode>>>, importing those types from the standard library. Write TreeNode::new(value: i32) -> Rc<TreeNode>. Write TreeNode::add_child(parent: &Rc<TreeNode>, child: Rc<TreeNode>), which also sets the child's parent. Write sum(&self) -> i32, the total of this node and all its descendants, and depth(&self) -> usize, the number of ancestors, which is 0 for a root.
use std::cell::RefCell;
use std::rc::{Rc, Weak};
pub struct TreeNode {
pub value: i32,
pub parent: RefCell<Weak<TreeNode>>,
pub children: RefCell<Vec<Rc<TreeNode>>>,
}
impl TreeNode {
pub fn new(value: i32) -> Rc<TreeNode> {
Rc::new(TreeNode {
value,
parent: RefCell::new(Weak::new()),
children: RefCell::new(Vec::new()),
})
}
pub fn add_child(parent: &Rc<TreeNode>, child: Rc<TreeNode>) {
let mut children = parent.children.borrow_mut();
children.push(child.clone());
child.parent.borrow_mut().upgrade = Some(parent.clone());
}
pub fn sum(&self) -> i32 {
self.value + self.children.borrow().iter().map(|c| c.sum()).sum()
}
pub fn depth(&self) -> usize {
if self.parent.borrow().upgrade.is_none() {
0
} else {
1 + self.parent.borrow().upgrade.as_ref().unwrap().depth()
}
}
}