Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
93 changes: 93 additions & 0 deletions src/challenges/challenge-69.md
Original file line number Diff line number Diff line change
@@ -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

<details>
<summary>Click to Show/Hide Solution</summary>

```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(&current) {
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");
}
}
```

</details>
126 changes: 126 additions & 0 deletions src/challenges/challenge-70.md
Original file line number Diff line number Diff line change
@@ -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

<details>
<summary>Click to Show/Hide Solution</summary>

```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);
}
}
```

</details>
92 changes: 92 additions & 0 deletions src/challenges/challenge-71.md
Original file line number Diff line number Diff line change
@@ -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
}
}
```
Loading