added permutations

This commit is contained in:
Rui Ribeiro 2025-09-22 16:55:06 +01:00
parent 2dfffb7ab5
commit f755b9a481
5 changed files with 364 additions and 0 deletions

25
permutations/Makefile Normal file
View File

@ -0,0 +1,25 @@
NAME = permutations
CC = gcc
CFLAGS = -Wall -Wextra -Werror
SRCS = permutations.c
OBJS = $(SRCS:.c=.o)
all: $(NAME)
$(NAME): $(OBJS)
$(CC) $(CFLAGS) -o $(NAME) $(OBJS)
%.o: %.c permutations.h
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(OBJS)
fclean: clean
rm -f $(NAME)
re: fclean all
.PHONY: all clean fclean re

200
permutations/README.md Normal file
View File

@ -0,0 +1,200 @@
# Permutations Exercise - Simple Explanation 🔄
## What is a Permutation? 🤔
Imagine you have some letters, like the letters in your name. A **permutation** is just a fancy word for "all the different ways you can arrange those letters."
Think of it like this:
- If you have the letters **A** and **B**, you can arrange them as **AB** or **BA**
- If you have **A**, **B**, and **C**, you can make **ABC**, **ACB**, **BAC**, **BCA**, **CAB**, **CBA**
It's like having alphabet blocks and seeing how many different words you can spell by changing the order!
## The Challenge 🎯
Your mission is to write a program that:
1. Takes a word (like "abc")
2. Shows ALL possible ways to rearrange the letters
3. Shows them in **alphabetical order** (like in a dictionary)
## Real Examples 📝
Let's see what our program does:
### Example 1: Single Letter
```bash
./permutations a
```
**Output:** `a`
*Why?* There's only one letter, so there's only one way to arrange it!
### Example 2: Two Letters
```bash
./permutations ab
```
**Output:**
```
ab
ba
```
*Why?* We can put 'a' first or 'b' first. That's it!
### Example 3: Three Letters
```bash
./permutations abc
```
**Output:**
```
abc
acb
bac
bca
cab
cba
```
*Why?* Think of it step by step:
- Start with 'a': we can make **abc** and **acb**
- Start with 'b': we can make **bac** and **bca**
- Start with 'c': we can make **cab** and **cba**
## How Our Code Works 🛠️
### Step 1: Getting Ready
```c
// We take the word you give us
char *str = argv[1]; // This is your word like "abc"
// We make a copy so we don't mess up the original
copy = malloc(sizeof(char) * (len + 1));
```
### Step 2: Sorting First (The Secret Sauce! ✨)
```c
ft_sort_string(copy); // This puts letters in order: "cba" becomes "abc"
```
**Why do we sort first?**
- If someone gives us "cba", we sort it to "abc" first
- This way, we always start with letters in alphabetical order
- Then when we make all arrangements, they come out in the right order!
### Step 3: The Magic Swapping Function
```c
void ft_swap(char *a, char *b)
{
char temp = *a; // Remember the first letter
*a = *b; // Put the second letter in first position
*b = temp; // Put the first letter in second position
}
```
**What's swapping?** It's like switching two cards in your hand:
- You have cards **A** and **B**
- After swapping, you have **B** and **A**
### Step 4: The Next Permutation Magic 🪄
```c
int next_permutation(char *str, int len)
{
int i = len - 2;
while (i >= 0 && str[i] >= str[i + 1]) // Find rightmost character smaller than next
i--;
if (i < 0)
return (0); // No more permutations
int j = len - 1;
while (str[j] <= str[i]) // Find rightmost character greater than str[i]
j--;
ft_swap(&str[i], &str[j]); // Swap them
ft_reverse(str, i + 1, len - 1); // Reverse the suffix
return (1); // Successfully generated next permutation
}
```
**How does this work?** Think of it like counting in a special way:
1. **Find** the rightmost place where we can "increment" (make it bigger)
2. **Swap** with the next bigger character available
3. **Reverse** everything after that position to get the smallest arrangement
4. **Repeat** until no more permutations exist
It's like a smart odometer that counts through all possible letter arrangements in perfect alphabetical order!
### Step 5: The Main Loop 🔄
```c
ft_sort_string(copy); // Start with alphabetically first arrangement
puts(copy); // Print the first permutation
while (next_permutation(copy, len)) // While there are more permutations
puts(copy); // Print each one
```
**How does this work?**
1. **Start** with the smallest (first) arrangement: "abc"
2. **Print** it
3. **Generate** the next alphabetical arrangement using `next_permutation`
4. **Print** it
5. **Repeat** until `next_permutation` says "no more!"
It's like flipping through a dictionary - each page (permutation) comes in perfect alphabetical order!
## Why This Approach is Cool 😎
### The Step-by-Step Process 📋
When we have "abc", our program works like this:
```
1. Start: abc (sorted, print it!)
2. Next: acb (swap 'b' and 'c', print it!)
3. Next: bac (find next in alphabetical order, print it!)
4. Next: bca (continue the pattern, print it!)
5. Next: cab (keep going, print it!)
6. Next: cba (last one, print it!)
7. Done: No more permutations possible
```
**The Magic:** Each step finds the next arrangement that would come after the current one in a dictionary! It's like having a super-smart assistant who knows exactly what comes next alphabetically.
### Memory Management 🧠
```c
copy = malloc(sizeof(char) * (len + 1)); // Ask for memory
// ... do our work ...
free(copy); // Give memory back when done
```
We're polite programmers - we clean up after ourselves!
### Error Handling 🛡️
```c
if (argc != 2) // Did you give us exactly one word?
return (1); // If not, we quit
if (!copy) // Did we get the memory we asked for?
return (1); // If not, we quit safely
```
We check if things went wrong and handle it gracefully.
## Fun Facts! 🎉
- With 1 letter: **1** permutation
- With 2 letters: **2** permutations
- With 3 letters: **6** permutations
- With 4 letters: **24** permutations
- With 5 letters: **120** permutations
**Pattern?** For n letters, you get n × (n-1) × (n-2) × ... × 1 permutations!
## Try It Yourself! 🚀
1. Compile the program: `gcc -Wall -Wextra -Werror permutations.c -o permutations`
2. Try it with your name: `./permutations john`
3. Try it with short words: `./permutations cat`
4. See how the results are always in alphabetical order!
Remember: The computer is doing exactly what we told it to do, step by step, just like following a recipe! 👨‍🍳
---
*Made with ❤️ for curious minds who want to understand how permutations work!*

View File

@ -0,0 +1,98 @@
#include "permutations.h"
int ft_strlen(char *str)
{
int len;
len = 0;
while (str[len])
len++;
return (len);
}
void ft_swap(char *a, char *b)
{
char temp;
temp = *a;
*a = *b;
*b = temp;
}
void ft_sort_string(char *str)
{
int i;
int j;
int len;
len = ft_strlen(str);
i = 0;
while (i < len - 1)
{
j = i + 1;
while (j < len)
{
if (str[i] > str[j])
ft_swap(&str[i], &str[j]);
j++;
}
i++;
}
}
void ft_reverse(char *str, int start, int end)
{
while (start < end)
{
ft_swap(&str[start], &str[end]);
start++;
end--;
}
}
int next_permutation(char *str, int len)
{
int i;
int j;
i = len - 2;
while (i >= 0 && str[i] >= str[i + 1])
i--;
if (i < 0)
return (0);
j = len - 1;
while (str[j] <= str[i])
j--;
ft_swap(&str[i], &str[j]);
ft_reverse(str, i + 1, len - 1);
return (1);
}
int main(int argc, char **argv)
{
char *str;
char *copy;
int len;
int i;
if (argc != 2)
return (1);
str = argv[1];
len = ft_strlen(str);
copy = malloc(sizeof(char) * (len + 1));
if (!copy)
return (1);
i = 0;
while (i < len)
{
copy[i] = str[i];
i++;
}
copy[len] = '\0';
ft_sort_string(copy);
puts(copy);
while (next_permutation(copy, len))
puts(copy);
free(copy);
return (0);
}

View File

@ -0,0 +1,14 @@
#ifndef PERMUTATIONS_H
# define PERMUTATIONS_H
# include <stdlib.h>
# include <unistd.h>
# include <stdio.h>
void ft_swap(char *a, char *b);
void ft_sort_string(char *str);
void ft_reverse(char *str, int start, int end);
int next_permutation(char *str, int len);
int ft_strlen(char *str);
#endif

27
permutations/subject.txt Normal file
View File

@ -0,0 +1,27 @@
Assignment name : permutations
Expected files : *.c *.h
Allowed functions: puts, malloc, calloc, realloc, free, write
---------------------------------------------------------------
Write a program that will print all the permutations of a string given as argument.
The solutions must be given in alphabetical order.
We will not try your program with strings containing duplicates (eg: 'abccd').
For example this should work:
$> ./permutations a | cat -e
a$
$> ./permutations ab | cat -e
ab$
ba$
$> ./permutations abc | cat -e
abc$
acb$
bac$
bca$
cab$
cba$