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 bytes = s.as_bytes();
let mut left = 0;
let mut right = bytes.len();
while left < right {
while left < right && !is_ascii_alphanumeric(bytes[left]) {
left += 1;
}
while left < right && !is_ascii_alphanumeric(bytes[right - 1]) {
right -= 1;
}
if left >= right {
break;
}
if to_ascii_lowercase(bytes[left]) != to_ascii_lowercase(bytes[right - 1]) {
return false;
}
left += 1;
right -= 1;
}
true
}
const fn is_ascii_alphanumeric(b: u8) -> bool {
(b >= b'0' && b <= b'9')
|| (b >= b'A' && b <= b'Z')
|| (b >= b'a' && b <= b'z')
}
const fn to_ascii_lowercase(b: u8) -> u8 {
if b >= b'A' && b <= b'Z' {
b + (b'a' - b'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 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 bytes = s.as_bytes();
let mut left = 0;
let mut right = bytes.len();
while left < right {
while left < right {
let b = bytes[left];
if matches!(b, b'0'..=b'9' | b'A'..=b'Z' | b'a'..=b'z') {
break;
}
left += 1;
}
while left < right {
let b = bytes[right - 1];
if matches!(b, b'0'..=b'9' | b'A'..=b'Z' | b'a'..=b'z') {
break;
}
right -= 1;
}
if left >= right {
break;
}
let l = bytes[left];
let r = bytes[right - 1];
let l = if l >= b'A' && l <= b'Z' { l + 32 } else { l };
let r = if r >= b'A' && r <= b'Z' { r + 32 } else { r };
if l != r {
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 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.
fn is_palindrome(s: &str) -> bool {
let bytes = s.as_bytes();
let mut left = 0;
let mut right = bytes.len();
while left < right {
while left < right && !is_ascii_alphanumeric(bytes[left]) {
left += 1;
}
while left < right && !is_ascii_alphanumeric(bytes[right - 1]) {
right -= 1;
}
if left >= right {
break;
}
if bytes[left].to_ascii_lowercase() != bytes[right - 1].to_ascii_lowercase() {
return false;
}
left += 1;
right -= 1;
}
true
}
fn is_ascii_alphanumeric(b: u8) -> bool {
matches!(b, b'0'..=b'9' | b'A'..=b'Z' | b'a'..=b'z')
}
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();
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();
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 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.
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() >= y.len() {
x
} else {
y
}
}
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.
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() >= y.len() {
x
} else {
y
}
}
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.
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() >= y.len() {
x
} else {
y
}
}
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;
fn parse_pair<T: FromStr>(s: &str, sep: char) -> Option<(T, T)> {
let (left, right) = s.split_once(sep)?;
let left = T::from_str(left).ok()?;
let right = T::from_str(right).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 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;
fn parse_pair<T: FromStr>(s: &str, sep: char) -> Option<(T, T)> {
let (left, right) = s.split_once(sep)?;
let left = left.parse::<T>().ok()?;
let right = right.parse::<T>().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 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;
fn parse_pair<T: FromStr>(s: &str, sep: char) -> Option<(T, T)> {
let (left, right) = s.split_once(sep)?;
let left = T::from_str(left).ok()?;
let right = T::from_str(right).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.
fn compose<F, G, A, B, C>(f: F, g: G) -> impl Fn(A) -> C
where
F: Fn(A) -> B,
G: Fn(B) -> C,
{
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.
fn compose<F, G, A, B, C>(f: F, g: G) -> impl Fn(A) -> C
where
F: Fn(A) -> B,
G: Fn(B) -> C,
{
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.
fn compose<F, G, A, B, C>(f: F, g: G) -> impl Fn(A) -> C
where
F: Fn(A) -> B,
G: Fn(B) -> C,
{
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: FibState,
}
enum FibState {
Active(u64, u64),
Last(u64),
Done,
}
impl Fib {
pub fn new() -> Self {
Self {
state: FibState::Active(0, 1),
}
}
}
impl Iterator for Fib {
type Item = u64;
fn next(&mut self) -> Option<Self::Item> {
let state = std::mem::replace(&mut self.state, FibState::Done);
match state {
FibState::Active(a, b) => {
let ret = a;
self.state = match b.checked_add(a) {
Some(sum) => FibState::Active(b, sum),
None => FibState::Last(b),
};
Some(ret)
}
FibState::Last(a) => {
self.state = FibState::Done;
Some(a)
}
FibState::Done => 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 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 {
curr: Option<u64>,
next: Option<u64>,
}
impl Fib {
pub fn new() -> Self {
Self {
curr: Some(0),
next: Some(1),
}
}
}
impl Iterator for Fib {
type Item = u64;
fn next(&mut self) -> Option<Self::Item> {
let current = self.curr.take()?;
let next_val = match self.next.take() {
Some(n) => n,
None => return Some(current),
};
match current.checked_add(next_val) {
Some(sum) => {
self.curr = Some(next_val);
self.next = Some(sum);
Some(current)
}
None => {
self.curr = Some(next_val);
self.next = None;
Some(current)
}
}
}
}
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: State,
}
enum State {
Active { curr: u64, next: u64 },
Last { val: u64 },
Done,
}
impl Fib {
pub fn new() -> Self {
Fib {
state: State::Active { curr: 0, next: 1 },
}
}
}
impl Iterator for Fib {
type Item = u64;
fn next(&mut self) -> Option<Self::Item> {
match std::mem::replace(&mut self.state, State::Done) {
State::Active { curr, next } => {
let result = curr;
match curr.checked_add(next) {
Some(sum) => {
self.state = State::Active { curr: next, next: sum };
Some(result)
}
None => {
self.state = State::Last { val: next };
Some(result)
}
}
}
State::Last { val } => {
self.state = State::Done;
Some(val)
}
State::Done => 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 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;
#[derive(Debug)]
enum TempError {
Empty,
BadUnit(char),
BadNumber(std::num::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(c) => write!(f, "invalid unit: {}", c),
TempError::BadNumber(e) => write!(f, "invalid number: {}", e),
}
}
}
impl std::error::Error for TempError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
TempError::BadNumber(e) => Some(e),
_ => None,
}
}
}
impl From<std::num::ParseFloatError> for TempError {
fn from(e: std::num::ParseFloatError) -> Self {
TempError::BadNumber(e)
}
}
fn parse_temp(s: &str) -> Result<f64, TempError> {
if s.is_empty() {
return Err(TempError::Empty);
}
let unit = s.chars().last().expect("string is not empty");
let unit_len = unit.len_utf8();
let num_str = &s[..s.len() - unit_len];
match unit {
'C' | 'F' => {
let value: f64 = num_str.parse().map_err(TempError::BadNumber)?;
if unit == 'F' {
Ok((value - 32.0) * 5.0 / 9.0)
} else {
Ok(value)
}
}
other => Err(TempError::BadUnit(other)),
}
}
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::{self, Display, Formatter};
use std::num::ParseFloatError;
#[derive(Debug)]
pub enum TempError {
Empty,
BadUnit(char),
BadNumber(ParseFloatError),
}
impl Display for TempError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
TempError::Empty => write!(f, "empty input"),
TempError::BadUnit(c) => write!(f, "bad unit: '{c}'"),
TempError::BadNumber(e) => write!(f, "bad number: {e}"),
}
}
}
impl std::error::Error for TempError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
TempError::BadNumber(e) => Some(e),
_ => None,
}
}
}
impl From<ParseFloatError> for TempError {
fn from(e: ParseFloatError) -> Self {
TempError::BadNumber(e)
}
}
pub fn parse_temp(s: &str) -> Result<f64, TempError> {
if s.is_empty() {
return Err(TempError::Empty);
}
let Some(unit) = s.chars().next_back() else {
return Err(TempError::Empty);
};
if unit != 'C' && unit != 'F' {
return Err(TempError::BadUnit(unit));
}
let num_str = &s[..s.len() - unit.len_utf8()];
let value: f64 = num_str.parse()?;
if unit == 'F' {
Ok((value - 32.0) * 5.0 / 9.0)
} else {
Ok(value)
}
}
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.
#[derive(Debug)]
pub enum TempError {
Empty,
BadUnit(char),
BadNumber(std::num::ParseFloatError),
}
impl std::fmt::Display for TempError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
TempError::Empty => write!(f, "empty temperature input"),
TempError::BadUnit(unit) => write!(f, "invalid unit: {unit}"),
TempError::BadNumber(error) => write!(f, "invalid number: {error}"),
}
}
}
impl std::error::Error for TempError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
TempError::BadNumber(error) => Some(error),
_ => None,
}
}
}
impl From<std::num::ParseFloatError> for TempError {
fn from(error: std::num::ParseFloatError) -> Self {
TempError::BadNumber(error)
}
}
pub fn parse_temp(s: &str) -> Result<f64, TempError> {
if s.is_empty() {
return Err(TempError::Empty);
}
let unit = s.chars().next_back().unwrap();
let number_text = &s[..s.len() - unit.len_utf8()];
match unit {
'C' => number_text.parse::<f64>().map_err(TempError::BadNumber),
'F' => {
let value = number_text.parse::<f64>().map_err(TempError::BadNumber)?;
Ok((value - 32.0) * 5.0 / 9.0)
}
_ => Err(TempError::BadUnit(unit)),
}
}
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;
pub fn parallel_sum(data: &[u64], workers: usize) -> u64 {
assert!(workers > 0, "workers must be non-zero");
if data.is_empty() {
return 0;
}
let len = data.len();
let n = workers.min(len);
let base = len / n;
let rem = len % n;
thread::scope(|s| {
let mut handles = Vec::with_capacity(n);
let mut start = 0;
for i in 0..n {
let extra = if i < rem { 1 } else { 0 };
let end = start + base + extra;
let chunk = &data[start..end];
start = end;
handles.push(s.spawn(move || chunk.iter().sum::<u64>()));
}
let mut total = 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.
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.
pub fn parallel_sum(data: &[u64], workers: usize) -> u64 {
if workers == 0 {
panic!("workers must be non-zero");
}
if data.is_empty() {
return 0;
}
let len = data.len();
let num_workers = workers.min(len);
let base_chunk = len / num_workers;
let remainder = len % num_workers;
std::thread::scope(|scope| {
let mut handles = Vec::with_capacity(num_workers);
let mut start = 0;
for i in 0..num_workers {
let end = start + base_chunk + if i < remainder { 1 } else { 0 };
let chunk = &data[start..end];
start = end;
handles.push(scope.spawn(move || {
chunk.iter().sum()
}));
}
let mut total = 0;
for handle in handles {
total += handle.join();
}
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;
pub fn parallel_sum(data: &[u64], workers: usize) -> u64 {
if workers == 0 {
panic!("parallel_sum: workers must be non-zero");
}
if data.is_empty() {
return 0;
}
let workers = workers.min(data.len());
let chunk_size = (data.len() + workers - 1) / workers;
thread::scope(|s| {
let handles: Vec<_> = data
.chunks(chunk_size)
.map(|chunk| {
s.spawn(move || chunk.iter().copied().sum::<u64>())
})
.collect();
handles
.into_iter()
.map(|handle| handle.join().unwrap())
.sum()
})
}
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: Iterator {
fn pairs(self) -> Pairs<Self>
where
Self: Sized,
Self::Item: Clone;
}
impl<I: Iterator> PairsExt for I {
fn pairs(self) -> Pairs<Self>
where
Self: Sized,
Self::Item: Clone,
{
Pairs {
iter: self,
prev: None,
done: false,
}
}
}
pub struct Pairs<I: Iterator> {
iter: I,
prev: Option<I::Item>,
done: bool,
}
impl<I: Iterator> Iterator for Pairs<I>
where
I::Item: Clone,
{
type Item = (I::Item, I::Item);
fn next(&mut self) -> Option<Self::Item> {
if self.done {
return None;
}
let prev = self.prev.take();
match prev {
None => match self.iter.next() {
Some(item) => {
self.prev = Some(item);
None
}
None => {
self.done = true;
None
}
},
Some(prev_item) => match self.iter.next() {
Some(item) => {
let pair = (prev_item.clone(), item);
self.prev = Some(item);
Some(pair)
}
None => {
self.done = true;
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.
pub trait PairsExt: Iterator {
fn pairs(self) -> Pairs<Self>
where
Self: Sized,
Self::Item: Clone;
}
impl<I> PairsExt for I
where
I: Iterator,
I::Item: Clone,
{
fn pairs(self) -> Pairs<Self> {
Pairs::new(self)
}
}
pub struct Pairs<I: Iterator> {
iter: I,
front: Option<I::Item>,
}
impl<I: Iterator> Pairs<I> {
fn new(iter: I) -> Self {
Self { iter, front: None }
}
}
impl<I> Iterator for Pairs<I>
where
I: Iterator,
I::Item: Clone,
{
type Item = (I::Item, I::Item);
fn next(&mut self) -> Option<Self::Item> {
let first = match self.front.take() {
Some(item) => item,
None => match self.iter.next() {
Some(item) => item,
None => return None,
},
};
let second = match self.iter.next() {
Some(item) => item,
None => return None,
};
self.front = Some(second.clone());
Some((first, second))
}
}
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 struct Pairs<I: Iterator> {
iter: I,
prev: Option<I::Item>,
}
impl<I> Iterator for Pairs<I>
where
I: Iterator,
I::Item: Clone,
{
type Item = (I::Item, I::Item);
fn next(&mut self) -> Option<Self::Item> {
loop {
let curr = match self.iter.next() {
Some(item) => item,
None => return None,
};
match self.prev.take() {
None => self.prev = Some(curr),
Some(prev) => {
self.prev = Some(curr);
return Some((prev, curr.clone()));
}
}
}
}
}
pub trait PairsExt: Iterator {
fn pairs(self) -> Pairs<Self>
where
Self: Sized,
Self::Item: Clone,
{
Pairs { iter: self, prev: None }
}
}
impl<I: Iterator> PairsExt for I {}
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.
#![edition = "2024"]
use std::cell::RefCell;
use std::rc::{Rc, Weak};
pub struct TreeNode {
value: i32,
parent: RefCell<Weak<TreeNode>>,
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() = 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 {
match self.parent.borrow().upgrade() {
Some(p) => 1 + p.depth(),
None => 0,
}
}
}
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};
struct TreeNode {
value: i32,
parent: RefCell<Weak<TreeNode>>,
children: RefCell<Vec<Rc<TreeNode>>>,
}
impl TreeNode {
fn new(value: i32) -> Rc<TreeNode> {
Rc::new(TreeNode {
value,
parent: RefCell::new(Weak::new()),
children: RefCell::new(Vec::new()),
})
}
fn add_child(parent: &Rc<TreeNode>, child: Rc<TreeNode>) {
*child.parent.borrow_mut() = Rc::downgrade(parent);
parent.children.borrow_mut().push(child);
}
fn sum(&self) -> i32 {
let mut total = self.value;
for child in self.children.borrow().iter() {
total += child.sum();
}
total
}
fn depth(&self) -> usize {
match self.parent.borrow().upgrade() {
Some(ancestor) => 1 + ancestor.depth(),
None => 0,
}
}
}
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<Self> {
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() = 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 {
let parent = self.parent.borrow();
match parent.upgrade() {
Some(ancestor) => 1 + ancestor.depth(),
None => 0,
}
}
}