Optional
ex05: ft_print_comb
Now this is where it gets trickier, and we need to think before we code.
The task is to print a combination of 3 digits at a time, seperated by a comma, and each of these 3 digits:
- cannot repeat
- cannot occur in the same group again in the next combination
This is the expected output:

I pseudo-coded using Python for loops as it's more readable for me:
cout = ''
for a in range(8):
for b in range(a, 9):
for c in range(b, 10):
if not (a == c or a == b or b == c):
if not (a == 0 and b == 1 and c == 2):
cout += ", "
cout += f'{a}{b}{c}'
print(cout)
Basically how it works is there are 3 loops for each digit, the a loop contains the b loop which contains the c loop
Each loop starts from it's parent's current int or 0 for a to stop numbers like 021 to appear since we're raising the floor for it.
This way, c loop will run for the c digit which runs most of the times. when c loop runs out of digits, the b loop iterates and so the c loop is reset, just like how numbers overflow, aaand finally it cascades to a which is the slowest gear.
Then we just instruct c to print abc if a, b and c are not equal to each other
The reason I chose 8, 9 and 10 is because Python's range() function ends as soon as it sees the number it was given, if I did 7, 8 and 9 it would stop one number too early.
But we are not working with Python, and we are not allowed to use for loops as per Norme, so I created:
ft_print_digits: a function which turns 3 int digits into their corresponding char ASCII representation and then prints them in order and calls ft_print_comma if neccesary.
ft_print_comb: the function that houses our 3 nested while loops and a, b and c variables
ft_print_comma: a function that just prints a comma for seperation.
You can see the code in the C file for it if you're completely helpless but this should be enough info so you can write it yourself, maybe look up syntax for the and/or operators, while loops and if statements in C.
ex06: ft_print_comb2
This one was a bit more difficult than I anticipated. It would be a port of the one in ex05 if it weren't for the 25 line limit for functions...
But the way I ended up doing it is by using some simple math
Basically I have only one int named a that grows from 1 all the way to 9899 (because that's the largest number where the first half is lower than the second half), and then to print it, I made a new ft_print_digits that derives ca, cb, cc and cd which are the char passed to write by doing:
char ca
char cb
char cc
char cd
ca = '0' + (a / 1000) % 10
cb = '0' + (a / 100) % 10
cc = '0' + (a / 10) % 10
cd = '0' + (a) % 10
And then I was able to output them without issue, I just needed to use write constantly and add a space in between cb and cc and a comma after cd if a < 9899 since that's the final number.
Then all my loop does is it gets the left half of a by dividing it by 100 and the right half using a modulo 100, checks if left is smaller than right before printing it because left cannot be larger than right, and that's it.
ex07: ft_putnbr
I solved this one through recursion.
Basically when the function is first run, it checks if the number entered is -2147483648 because this is the overflow point for int, so it would cause unintended behavior if we try to calculate it. For this special case number we manually do the write.
If it is not, then we go on to check if the number is negative, and if it is we need to put a dash so it shows up as negative, then we set nb = -nb which basically makes it positive so we can work with it, otherwise the algorithm will fail.
Then if the number only has 1 digit (more or equal to 0 and less than 10) we can easily reuse ft_putchar again to output that. Otherwise, we will call ft_putnbr again, this time dividing nb by 10 so we remove the rightmost digit and do the same procedure on top of it again, and this keeps repeating until we only have one digit we can output using ft_putchar. Then after all these recursive operations, it does the same but this time using the % operator, which does the opposite of division by 10: it removes the leftmost digit. And this way, both halves are eventually reduced to single characters that can be outputted using ft_putchar, leading to our number!
ex08: ft_print_combn
The code is probably the most complicated, it consists of a recursive function to print digits (ft_print_digits), a validation function (ft_isasc), a helper to calculate the maximum boundary (ft_max), and the main ft_print_combn.
ft_print_combn first uses ft_max to dynamically build the exact maximum valid combination for n. For example, if n=3, it calculates 10-3 to start at 7 and loops up to 9, building the integer 789.
Then we calculate the exact starting number a based on n by looping from 0 to n-1 (for n=3, it builds the integer 12, representing 012). The first valid number is printed immediately using ft_print_digits so we don't have to worry about a leading comma on the first iteration.
After printing the first number, we enter a while loop that increments a by 1 (a++) until it reaches our calculated maximum number.
Instead of trying to mathematically calculate jumps to skip invalid numbers, we pass a and n to ft_isasc. This function extracts the digits from right to left using the % operator and checks if every digit is strictly smaller than the one to its right. If the number is not strictly ascending (like 10) or repeats digits (like 11), ft_isasc returns 0 and the loop skips it.
If ft_isasc returns 1, we print a comma directly using write and then the valid digits using ft_print_digits. This cycle repeats until a hits our exact maximum bound.