From a5b363793384136d966ceb8e5375778d20df3d47 Mon Sep 17 00:00:00 2001 From: "exercism-solutions-syncer[bot]" <211797793+exercism-solutions-syncer[bot]@users.noreply.github.com> Date: Tue, 27 Jan 2026 09:48:40 +0000 Subject: [PATCH] [Sync Iteration] rust/list-ops/2 --- solutions/rust/list-ops/2/Cargo.toml | 9 ++ solutions/rust/list-ops/2/src/lib.rs | 188 +++++++++++++++++++++++++++ 2 files changed, 197 insertions(+) create mode 100644 solutions/rust/list-ops/2/Cargo.toml create mode 100644 solutions/rust/list-ops/2/src/lib.rs diff --git a/solutions/rust/list-ops/2/Cargo.toml b/solutions/rust/list-ops/2/Cargo.toml new file mode 100644 index 00000000..2637d4f1 --- /dev/null +++ b/solutions/rust/list-ops/2/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "list_ops" +version = "0.1.0" +edition = "2024" + +# Not all libraries from crates.io are available in Exercism's test runner. +# The full list of available libraries is here: +# https://github.com/exercism/rust-test-runner/blob/main/local-registry/Cargo.toml +[dependencies] diff --git a/solutions/rust/list-ops/2/src/lib.rs b/solutions/rust/list-ops/2/src/lib.rs new file mode 100644 index 00000000..c19eb815 --- /dev/null +++ b/solutions/rust/list-ops/2/src/lib.rs @@ -0,0 +1,188 @@ +/// Gibt jedes Element von a und dann jedes Element von b zurück (ohne chain) +pub fn append(a: I, b: J) -> Append +where + I: Iterator, + J: Iterator, +{ + Append { a, b } +} + +pub struct Append { + a: I, + b: J, +} + +impl Iterator for Append +where + I: Iterator, + J: Iterator, +{ + type Item = I::Item; + fn next(&mut self) -> Option { + self.a.next().or_else(|| self.b.next()) + } +} + +/// Kombiniert alle Elemente aus allen verschachtelten Iteratoren zu einem flachen Iterator (ohne flatten) +pub fn concat(nested_iter: I) -> Concat +where + I: Iterator, + I::Item: Iterator, +{ + Concat { + outer: nested_iter, + inner: None, + } +} + +pub struct Concat +where + I: Iterator, + I::Item: Iterator, +{ + outer: I, + inner: Option, +} + +impl Iterator for Concat +where + I: Iterator, + I::Item: Iterator, +{ + type Item = ::Item; + fn next(&mut self) -> Option { + loop { + if let Some(inner) = &mut self.inner { + if let Some(item) = inner.next() { + return Some(item); + } + } + match self.outer.next() { + Some(next_inner) => self.inner = Some(next_inner), + None => return None, + } + } + } +} + +/// Gibt einen Iterator über alle Elemente zurück, für die das Prädikat true ergibt (ohne filter) +pub fn filter(iter: I, predicate: F) -> Filter +where + I: Iterator, + F: Fn(&I::Item) -> bool, +{ + Filter { iter, predicate } +} + +pub struct Filter { + iter: I, + predicate: F, +} + +impl Iterator for Filter +where + I: Iterator, + F: Fn(&I::Item) -> bool, +{ + type Item = I::Item; + fn next(&mut self) -> Option { + while let Some(item) = self.iter.next() { + if (self.predicate)(&item) { + return Some(item); + } + } + None + } +} + +pub fn length(mut iter: I) -> usize { + let mut n = 0; + while let Some(_) = iter.next() { + n += 1; + } + n +} + +/// Gibt einen Iterator mit den Ergebnissen der Funktion auf alle Elemente zurück (ohne map) +pub fn map(iter: I, function: F) -> Map +where + I: Iterator, + F: Fn(I::Item) -> U, +{ + Map { iter, function } +} + +pub struct Map { + iter: I, + function: F, +} + +impl Iterator for Map +where + I: Iterator, + F: Fn(I::Item) -> U, +{ + type Item = U; + fn next(&mut self) -> Option { + self.iter.next().map(&self.function) + } +} + +pub fn foldl(mut iter: I, mut acc: U, function: F) -> U +where + I: Iterator, + F: Fn(U, I::Item) -> U, +{ + while let Some(item) = iter.next() { + acc = function(acc, item); + } + acc +} + +pub fn foldr(mut iter: I, acc: U, function: F) -> U +where + I: DoubleEndedIterator, + F: Fn(U, I::Item) -> U, +{ + // Sammle alle Elemente in einen Vektor, dann von rechts falten + let mut items = Vec::new(); + while let Some(item) = iter.next() { + items.push(item); + } + let mut acc = acc; + while let Some(item) = items.pop() { + acc = function(acc, item); + } + acc +} + +/// Gibt einen Iterator mit allen ursprünglichen Elementen in umgekehrter Reihenfolge zurück (ohne rev) +pub fn reverse(iter: I) -> Reverse +where + I: DoubleEndedIterator, +{ + Reverse { iter, finished: false } +} + +pub struct Reverse { + iter: I, + finished: bool, +} + +impl Iterator for Reverse +where + I: DoubleEndedIterator, +{ + type Item = I::Item; + fn next(&mut self) -> Option { + if self.finished { + None + } else { + let next = self.iter.next_back(); + if next.is_none() { + self.finished = true; + } + next + } + } +}