Next different permutation in C This is a program which you can get the next &quot;different&quot;, i.e. elements in A[] can be identical, permutation at each call. I've written a C++ program for the same purpose in 2018, but I found it unreadable, readability = NULL, so here is a new one.
Any critical comment and answer will be welcomed :)
next_different_permutation.c:
#include &lt;stdbool.h&gt;

void pswap(int *l, int *r) {
    int temp = *l;
    *l = *r;
    *r = temp;
}

void reverse(int A[], int l, int r) {
    int size = (r-l+1);
    for (int i = 0; i &lt; size/2; ++i)
        pswap(&amp;A[l+i], &amp;A[r-i]);
}

bool next_different_permutation(int A[], int l, int r) {
    if (r-l+1 &lt;= 1)
        return false;                           // return false when [l,r] is(or back to) an increasing interval.
    int j = -1;                           // j will point to the highest peak of the interval [i,r].
    for (struct{int i, j;}                           // this for will find the first increasing [i,j] from r to l.
        z = {r-1, r}; z.j != l; --z.i, j=--z.j)
        if (A[z.i] &lt; A[z.j]) {                           // find the maximal decreasing interval [j,r].
            int k = r;                           // after swap (i, k), interval [j,r] remains decreasing.
            while (!(A[z.i] &lt; A[k]))                           // find the first A[k] where A[k] &gt; A[z.i].
                --k;
            pswap(&amp;A[z.i], &amp;A[k]);
            reverse(A, z.j, r);
            return true;                           // when success we go, the z.i, z.j will be initialized in next call.
        }
    reverse(A, j, r);                           // Recover the A[l]&gt;=A[l+1]&gt;=...&gt;=A[r]-array back to the increasing order.
    return false;
}

Usage:
#define ARRAY_SIZE 3
int A[ARRAY_SIZE]

void next_different_permutation_test_distinct() {
    for (int i = 0; i &lt; ARRAY_SIZE; ++i)
        A[i] = i+1;
    do {
        print_array(A, ARRAY_SIZE, PRINT_WIDTH);
    } while (next_different_permutation(A, 0, ARRAY_SIZE-1));
    // the order will back to A[l]&lt;A[l+1]&lt;...&lt;A[r]
}

void next_different_permutation_test_some_identical() {
    for (int i = 0; i &lt; ARRAY_SIZE; ++i)
        A[i] = rand()%RAND_MOD;
    do {
        print_array(A, ARRAY_SIZE, PRINT_WIDTH);
    } while (next_different_permutation(A, 0, ARRAY_SIZE-1));
}
size and i in reverse look superficial. Consider
void reverse(int A[], int l, int r) {
    while (l &lt; r) {
        pswap(&amp;A[l++], &amp;A[r--]);
    }
}


The outer loop looks very strange. Its body is executed exactly once, when the longest decreasing interval is detected. Consider lifting the body out of the loop.
As a side point, I don't see the point of struct {int i; int j}. It is initialized to {r-1, r}, and at each iteration both members are decremented. z.i is always equal to  z.j - 1. Keeping just one int is enough. Consider
  int j = r; // j will point to the highest peak of the interval [i,r].
  // this loop will find the first increasing [i,j] from r to l.
  while (j &gt; l) {
      if (A[j-1] &lt; A[j]) {
          break;
      }
      --j;
  }

  if (j &gt; l) {
      int k = r;
      // find the first A[k] where A[k] &gt; A[j-1].
      while (!(A[j-1] &lt; A[k])) {
          --k;
      }
      pswap(&amp;A[j-1], &amp;A[k]);
      reverse(A, j, r);
      return true;
  }

  reverse(A, j, r);
  return false;

It already looks cleaner, but let's get going. An obvious next step is to get rid of the duplicate calls to reverse:
  if (j &gt; l) {
      ....
      pswap(....);
  }
  reverse (A, j, r);
  return j &gt; l;


No naked loops please. If you felt compelled to put comments like
      // find the maximal decreasing interval [j,r]
      // find the first A[k] where A[k] &gt; A[z.i].

you admit that you failed to express the intentions in the code. Consider refactoring these loops into functions. Consider
  int j = find_decreasing_interval(A, l, r);
  if (l &lt; j) {
      int k = lower_bound(A, j, r, A[j-1]);
      pswap(&amp;A[j-1], &amp;A[k]);
  }
  reverse((A, j, r);
  return j &gt; l;