EX_03/rip/README.md
2025-09-22 17:26:39 +01:00

179 lines
4.9 KiB
Markdown

# The Parentheses Balancing Problem (RIP Exercise)
## What is this exercise about?
Imagine you have a string of parentheses like this: `"(()"`.
Think of parentheses like **doors** in a building:
- `(` is like **opening a door**
- `)` is like **closing a door**
For everything to work properly, every door you open must have a matching door that closes it!
## The Problem
Sometimes we get strings where the doors don't match properly. For example:
- `"((("` - We opened 3 doors but never closed any!
- `"())"` - We opened 1 door, closed 1 door, but then tried to close another door that was never opened!
Our job is to **fix** these strings by removing the minimum number of parentheses (but replacing them with spaces instead of deleting them completely).
## Real-World Example
Let's say you have: `"(()"`
This means:
1. Open door 1: `(`
2. Open door 2: `(`
3. Close door 2: `)`
4. But door 1 is still open! 😱
To fix this, we need to either:
- Remove one of the opening doors: ` ()` (remove first `(`)
- Or remove one of the opening doors: `( )` (remove second `(`)
Both solutions work!
## How Our Program Works
### Step 1: Count the Problems
```c
// This function counts how many parentheses we need to remove
void calculate_removals(char *str, int *left_rem, int *right_rem)
{
int left = 0; // Count of unmatched opening parentheses
int right = 0; // Count of unmatched closing parentheses
// Go through each character
while (str[i])
{
if (str[i] == '(')
left++; // Found an opening door
else if (str[i] == ')')
{
if (left > 0)
left--; // Found a closing door for an open one
else
right++; // Found a closing door with no matching open door
}
}
}
```
**Example with `"(()"`:**
- Start: `left = 0`, `right = 0`
- See `(`: `left = 1` (one unmatched opening)
- See `(`: `left = 2` (two unmatched openings)
- See `)`: `left = 1` (one opening got matched)
- End: `left = 1`, `right = 0`
So we need to remove **1 opening parenthesis**.
### Step 2: Try All Possible Solutions
Think of it like trying different combinations:
```c
// This function tries removing different parentheses to find all valid solutions
void solve(char *s, int pos, int left_rem, int right_rem, int open, char *path)
{
// If we've looked at all characters
if (pos == len)
{
// Check if we removed exactly what we needed and everything balances
if (left_rem == 0 && right_rem == 0 && open == 0)
add_result(results, path); // This is a valid solution!
return;
}
// Try removing this parenthesis (replace with space)
if (s[pos] == '(' && left_rem > 0)
{
path[pos] = ' '; // Replace with space
solve(s, pos + 1, left_rem - 1, right_rem, open, path);
}
// Try keeping this parenthesis
path[pos] = s[pos];
if (s[pos] == '(')
solve(s, pos + 1, left_rem, right_rem, open + 1, path);
// ... and so on
}
```
### Step 3: Avoid Duplicates
We use a list to store all unique solutions:
```c
// This makes sure we don't print the same solution twice
void add_result(t_result **results, char *str)
{
// Check if we already have this solution
current = *results;
while (current)
{
if (ft_strcmp(current->str, str) == 0)
return; // Already have it, don't add again
current = current->next;
}
// It's new, so add it to our list
new->str = ft_strdup(str);
new->next = *results;
*results = new;
}
```
## Example Walkthrough
Let's trace through `"(()"` step by step:
### Initial Analysis:
- Need to remove 1 opening parenthesis (`left_rem = 1`)
- Need to remove 0 closing parentheses (`right_rem = 0`)
### Trying Different Positions:
**Position 0 (first `(`):**
- Try removing it: `" ()"`
- Check: removed 1 opening ✓, no unmatched doors ✓
- **Valid solution!** ✅
**Position 1 (second `(`):**
- Try removing it: `"( )"`
- Check: removed 1 opening ✓, no unmatched doors ✓
- **Valid solution!** ✅
**Position 2 (the `)`):**
- Can't remove it (we need to remove openings, not closings)
### Final Output:
```
()
( )
```
## More Complex Example: `"()())()"`
This string has:
- 3 opening doors: `(`, `(`, `(`
- 4 closing doors: `)`, `)`, `)`, `)`
So we have 1 extra closing door that needs to be removed.
**All possible solutions:**
- Remove closing at position 2: `"()( )()"`
- Remove closing at position 3: `"()() ()"`
- Remove closing at position 4: `"( ())()"`
## Why This Exercise is Useful
This problem teaches us:
1. **Problem-solving**: Break down complex problems into smaller steps
2. **Recursion**: Try all possibilities systematically
3. **Data structures**: Use lists to store and manage results
4. **Optimization**: Find the minimum changes needed
It's like being a **door inspector** - you need to make sure every building (string) has properly matched doors (parentheses) with the minimum number of changes!