added permutations
This commit is contained in:
parent
2dfffb7ab5
commit
f755b9a481
25
permutations/Makefile
Normal file
25
permutations/Makefile
Normal 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
200
permutations/README.md
Normal 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!*
|
||||
98
permutations/permutations.c
Normal file
98
permutations/permutations.c
Normal 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);
|
||||
}
|
||||
14
permutations/permutations.h
Normal file
14
permutations/permutations.h
Normal 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
27
permutations/subject.txt
Normal 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$
|
||||
Loading…
Reference in New Issue
Block a user