diff --git a/src/SUMMARY.md b/src/SUMMARY.md
index f624be3..fffe6c7 100644
--- a/src/SUMMARY.md
+++ b/src/SUMMARY.md
@@ -70,4 +70,7 @@
- [Challenge 66](./challenges/challenge-66.md)
- [Challenge 67](./challenges/challenge-67.md)
- [Challenge 68](./challenges/challenge-68.md)
+ - [Challenge 69](./challenges/challenge-69.md)
+ - [Challenge 70](./challenges/challenge-70.md)
+ - [Challenge 71](./challenges/challenge-71.md)
- [Resources](./resources.md)
diff --git a/src/challenges/challenge-69.md b/src/challenges/challenge-69.md
new file mode 100644
index 0000000..d1757cc
--- /dev/null
+++ b/src/challenges/challenge-69.md
@@ -0,0 +1,93 @@
+# Challenge 69
+
+### String Compression
+
+Your task is to implement a `compress_string` function that compresses a string by replacing consecutive repeated characters with the character followed by the number of repetitions.
+
+```rust,editable
+// Rust Bytes Challenge Issue #87 String Compression
+
+assert_eq!(compress_string(""), "");
+assert_eq!(compress_string("a"), "a1");
+assert_eq!(compress_string("zzzzzz"), "z6");
+assert_eq!(compress_string("aabbaa"), "a2b2a2");
+```
+
+#### Write your solution below
+
+```rust,editable
+// Rust Bytes Challenge Issue #87 String Compression
+
+pub fn compress_string(input: &str) -> String {
+ // TODO: Implement your logic here
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_basic() {
+ assert_eq!(compress_string("aaabbc"), "a3b2c1");
+ assert_eq!(compress_string("abcd"), "a1b1c1d1");
+ }
+
+ #[test]
+ fn test_edge_cases() {
+ assert_eq!(compress_string(""), "");
+ assert_eq!(compress_string("a"), "a1");
+ assert_eq!(compress_string("zzzzzz"), "z6");
+ assert_eq!(compress_string("aabbaa"), "a2b2a2");
+ }
+}
+```
+
+### Solution
+
+
+Click to Show/Hide Solution
+
+```rust
+// Rust Bytes Challenge Issue #87 String Compression
+
+pub fn compress_string(input: &str) -> String {
+ // TODO: Implement your logic here
+ let mut compressed = String::new();
+ let mut chars = input.chars().peekable();
+
+ while let Some(current) = chars.next() {
+ let mut count = 1;
+
+ while chars.peek() == Some(¤t) {
+ count += 1;
+ chars.next();
+ }
+
+ compressed.push(current);
+ compressed.push_str(&count.to_string());
+ }
+
+ compressed
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_basic() {
+ assert_eq!(compress_string("aaabbc"), "a3b2c1");
+ assert_eq!(compress_string("abcd"), "a1b1c1d1");
+ }
+
+ #[test]
+ fn test_edge_cases() {
+ assert_eq!(compress_string(""), "");
+ assert_eq!(compress_string("a"), "a1");
+ assert_eq!(compress_string("zzzzzz"), "z6");
+ assert_eq!(compress_string("aabbaa"), "a2b2a2");
+ }
+}
+```
+
+
diff --git a/src/challenges/challenge-70.md b/src/challenges/challenge-70.md
new file mode 100644
index 0000000..28adf81
--- /dev/null
+++ b/src/challenges/challenge-70.md
@@ -0,0 +1,126 @@
+# Challenge 70
+
+### Mirror Index
+
+Given a vector of integers, return the index i such that the sum of all elements to the left of i equals the sum of all elements to the right of i.
+
+If multiple such indices exist, return the middlemost one (closest to the center).
+
+If none exist, return -1.
+
+```rust,editable
+assert_eq!(mirror_index(&[2, 3, -1, 8, 4]), 3);
+assert_eq!(mirror_index(&[1, 2, 3, 4, 6]), 3);
+assert_eq!(mirror_index(&[1, 1, 1, 1, 1, 1]), 2);
+assert_eq!(mirror_index(&[10, -10, 10, -10]), -1);
+assert_eq!(mirror_index(&[0]), 0);
+```
+
+#### Write your solution below
+
+```rust,editable
+// Rust Bytes Challenge Issue #88 Mirror Index
+
+pub fn mirror_index(arr: &[i32]) -> i32 {
+ // TODO: Implement your logic here
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_basic_cases() {
+ assert_eq!(mirror_index(&[2, 3, -1, 8, 4]), 3);
+ assert_eq!(mirror_index(&[1, 2, 3, 4, 6]), 3);
+ assert_eq!(mirror_index(&[1, 1, 1, 1, 1, 1]), 2);
+ assert_eq!(mirror_index(&[10, -10, 10, -10]), -1);
+ assert_eq!(mirror_index(&[0]), 0);
+ }
+
+ #[test]
+ fn test_edge_cases() {
+ assert_eq!(mirror_index(&[]), -1);
+ assert_eq!(mirror_index(&[5, 5, 5, 15, 5, 5, 5]), 3);
+ assert_eq!(mirror_index(&[1, 2, 3, 3, 2, 1]), 2);
+ assert_eq!(mirror_index(&[-1, -1, -1, 0, 1, 1, 1]), 3);
+ }
+}
+```
+
+### Solution
+
+
+ Click to Show/Hide Solution
+
+```rust
+// Rust Bytes Challenge Issue #88 Mirror Index
+
+pub fn mirror_index(arr: &[i32]) -> i32 {
+ // TODO: Implement your logic here
+ if arr.is_empty() {
+ return -1;
+ }
+
+ let n = arr.len();
+ let total: i32 = arr.iter().sum();
+ let mut left = 0;
+ let mut candidates = Vec::new();
+
+ for i in 0..n {
+ if 2 * left == total - arr[i] {
+ candidates.push(i);
+ }
+
+ left += arr[i];
+
+ if i < n - 1 && 2 * left == total && left != 0 {
+ candidates.push(i);
+ }
+ }
+
+ if candidates.is_empty() && total == 0 {
+ for (i, &v) in arr.iter().enumerate() {
+ if v == 0 {
+ candidates.push(i);
+ }
+ }
+ }
+
+ if candidates.is_empty() {
+ return -1;
+ }
+
+ let center = (n - 1) as isize;
+ let best = candidates
+ .into_iter()
+ .min_by_key(|&i| ((2 * i as isize) - center).abs())
+ .unwrap();
+
+ best as i32
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_basic_cases() {
+ assert_eq!(mirror_index(&[2, 3, -1, 8, 4]), 3);
+ assert_eq!(mirror_index(&[1, 2, 3, 4, 6]), 3);
+ assert_eq!(mirror_index(&[1, 1, 1, 1, 1, 1]), 2);
+ assert_eq!(mirror_index(&[10, -10, 10, -10]), -1);
+ assert_eq!(mirror_index(&[0]), 0);
+ }
+
+ #[test]
+ fn test_edge_cases() {
+ assert_eq!(mirror_index(&[]), -1);
+ assert_eq!(mirror_index(&[5, 5, 5, 15, 5, 5, 5]), 3);
+ assert_eq!(mirror_index(&[1, 2, 3, 3, 2, 1]), 2);
+ assert_eq!(mirror_index(&[-1, -1, -1, 0, 1, 1, 1]), 3);
+ }
+}
+```
+
+
diff --git a/src/challenges/challenge-71.md b/src/challenges/challenge-71.md
new file mode 100644
index 0000000..411ac41
--- /dev/null
+++ b/src/challenges/challenge-71.md
@@ -0,0 +1,92 @@
+# Challenge 71
+
+### Run-Length Decode
+
+Given a compressed string like **“a3b2c1”** return its expanded version *“aaabbc”*.
+
+If this feels familiar, that’s because we tackled the `reverse` (String Compression) in issue 87.
+
+```rust,editable
+// Rust Bytes Challenge Issue #89 Run-Length Decode
+
+assert_eq!(decompress("a3b2c1"), "aaabbc");
+assert_eq!(decompress("a10"),"aaaaaaaaaa");
+assert_eq!(decompress("a0b3"), "bbb");
+assert_eq!(decompress("r1u1s1t1"), "rust");
+
+```
+
+#### Write your solution below
+
+```rust,editable
+// Rust Bytes Challenge Issue #89 Run-Length Decode
+
+pub fn decompress(s: &str) -> String {
+ // TODO: Implement your logic here
+ let mut out = String::new();
+ let mut iter = s.chars().peekable();
+
+ while let Some(c) = iter.next() {
+ if c.is_alphabetic() {
+ let mut count = 0;
+
+ while let Some(&digit) = iter.peek() {
+ if digit.is_ascii_digit() {
+ iter.next();
+ count = count * 10 + digit.to_digit(10).unwrap() as usize;
+ } else {
+ break;
+ }
+ }
+ out.extend(std::iter::repeat(c).take(count.max(0)));
+ }
+ }
+
+ out
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_decompress_basic() {
+ assert_eq!(decompress("a3b2c1"), "aaabbc");
+ assert_eq!(decompress("x5"), "xxxxx");
+ assert_eq!(decompress("z1y2"), "zyy");
+ }
+
+ #[test]
+ fn test_decompress_with_single_counts() {
+ assert_eq!(decompress("a1b1c1"), "abc");
+ assert_eq!(decompress("r1u1s1t1"), "rust");
+ }
+
+ #[test]
+ fn test_decompress_with_multi_digit_counts() {
+ assert_eq!(decompress("a10"), "aaaaaaaaaa");
+ assert_eq!(decompress("b12c3"), "bbbbbbbbbbbbccc");
+ }
+
+ #[test]
+ fn test_decompress_mixed_patterns() {
+ assert_eq!(decompress("a2b10c1"), "aabbbbbbbbbbc"); // example with large middle
+ assert_eq!(decompress("A3b1C2"), "AAAbCC"); // test case sensitivity
+ }
+
+ #[test]
+ fn test_decompress_edge_cases() {
+ assert_eq!(decompress(""), ""); // empty string
+ assert_eq!(decompress("a0b3"), "bbb"); // handle zero count properly
+ assert_eq!(decompress("q1"), "q"); // single pattern
+ }
+
+ #[test]
+ fn test_decompress_invalid_inputs() {
+ // depending on implementation, could ignore or panic
+ assert_eq!(decompress("a"), ""); // missing count
+ assert_eq!(decompress("3a"), ""); // invalid order
+ assert_eq!(decompress("a-1"), ""); // invalid number
+ }
+}
+```