Given two arrays containing integers, figure out whether or not three consecutive integers are present in both arrays.
For example: A = [1, 4, 5, 7, 2] and B = [3, 1, 4, 5, 9] will result in "true" / 1 because [1, 4, 5] is present in both arrays.
My solution to this task is present below, but I feel like there must be a more optimized solution than this.
int consecutiveInts(int *a, int sizeA, int *b, int sizeB){
int i, j;
// Iterate over every integer in array b for every integer in array a.
for (i = 0 ; i < sizeA - 2 ; i++){
for (j = 0 ; j < sizeB - 2 ; j++){
if (a[i] == b[j] && a[i + 1] == b[j + 1] && a[i + 2] == b[j + 2])
return 1;
}
}
return 0;
}
For small arrays, OP approach is OK. For array lengths m,n it has O(m*n) run time.
An alternate makes 2 value arrays, sorts them and then looks for a common element. It has O(m*log2(m) + n*log2(n)) run time. Certainly faster with large arrays than OP's code.
typedef struct {
int i[3];
} int3;
void Init3(int3 *i3, const int *i, size_t n) {
while (n--) {
i3[n].i[0] = i[n];
i3[n].i[1] = i[n + 1];
i3[n].i[2] = i[n + 2];
}
}
int fcmp(const void *a, const void *b) {
return memcmp(a, b, sizeof (int3));
}
bool Pattern3(const int *a, size_t size_a, const int *b, size_t size_b) {
if (size_a < 3 || size_b < 3) return false;
int3 a3[size_a - 2];
Init3(a3, a, size_a - 2);
qsort(a3, size_a - 2, sizeof *a3, fcmp);
int3 b3[size_b - 2];
Init3(b3, b, size_b - 2);
qsort(b3, size_b - 2, sizeof *b3, fcmp);
while (size_a && size_b) {
int cmp = fcmp(&a[size_a - 1], &b[size_b - 1]);
if (cmp == 0) return true;
if (cmp > 0) size_a--;
else size_b--;
}
return false;
}
int main() {
int A[] = { 1, 4, 5, 7, 2 };
int B[] = { 3, 1, 4, 5, 9 };
printf("%d\n", Pattern3(A, sizeof A / sizeof *A, B, sizeof B / sizeof *B));
}
An alternative would use a bsearch() rather than form the 2nd int3 b3[]/qsort().
I think I cannot be wrong by sayin that declaring i and j outside of the loop is useless and not optimized.
Something like :
for (unsigned i = 0; i < sizeA - 2; i++) // i will only exist inside the loop
Would be a little better.
I use unsigned type because it is a habit I have taken when using an iterating variable. I think this is a matter which, if you are interested and not already informed, you could learn from by reading this topic.
Not sure it optimizes running speed, but I notice that in case there are repeated numbers you don't need to check them over and over again.
For example three sequential elements in the first array are all 1. After checking a[i] and seeing it's a mismatch you can skip directly to a[i + 3] without comparing a[i + 1] or a[i + 2] (they are also a mismatch).
The management of this condition, particularly if it's a short sequence of repeats, may not improve running time. You have to measure.
With code changes that do not affect the order of complexity, any candidate improvements need profiling (tests that measure the performance) to verify.
The following is still a O(n*m), yet with reduced coefficient as it can step through b[] faster if a[] has repeated values that also exist in b[]. This speeds the inner b[] loop where the majority of time is consumed.
Look at the a[] pattern for distinct values to so j may be advanced faster.
Example:
#define x 0
bool Pattern3(const int *a, size_t size_a, const int *b, size_t size_b) {
static const unsigned char deltas[2][2][2][2] = { //
// What type of pattern is a[0], a[1], a[2]?
{ { { 1, 1 }, // X Y Z
{ 1, 1 } }, // X Y Y
{ { 1, 2 }, // X Y X
{ x, x } } }, // not possible
{ { { 2, 1 }, // X X Y
{ x, x } }, // not possible
{ { x, x }, // not possible
{ 2, 3 } } } }; // X X X
for (unsigned i = 0; i + 2 < size_a; i++) {
const unsigned char *delta23 = deltas[a[0] == a[1]][a[0] == a[2]][a[1] == a[2]];
for (unsigned j = 0; j + 2 < size_b;) {
if (a[0] != b[j]) {
j++;
} else if (a[0 + 1] != b[j + 1]) {
j += delta23[0];
} else if (a[0 + 2] != b[j + 2]) {
j += delta23[1];
} else {
return true;
}
}
a++;
}
return false;
}
Other minor changes which may help.
In the above, swap a,b when size_a > size_b.
Use const as lesser compilers can optimized on that.
// int consecutiveInts(int *a, int sizeA, int *b, int sizeB){
int consecutiveInts(const int *a, int sizeA, const int *b, int sizeB){
Iterate from 2. Adjust indexing accordingly.
for (i = 2 ; i < sizeA ; i++){
...
try using the following loop
for(int i=0;i<A.length;i++)
{
for(int j=0;j<A.length;j++)
{
if(A[i]==B[j])
{
count=count+1; //It checks how many times equal elements have been found
//ensure to declare and initialize int count=0;
}
}
}
if(count>=3)
System.out.println("true");
Related
I have tried to solve this problem with pointers, but I couldn’t.
The requirement was writing a function in which you see if the array is
sorted increase (return 1)
sorted decrease (return -1)
not sorted at all (return 0)
Here is what I wrote:
int *test(int l,int *T)
{
int i,A[l],sign;
int *t=&A[0];
for (i=0; i<l; i++)
{
if(A[i]>A[i+1]){
t++;
sign =-1;
}
if (A[i]<A[i+1]){
t++;
sign =1;
}
if (A[i]!=A[i+1]){
t++;
sign =0;
}
}
return sign;
}
The compiler is giving
returning ‘int’ from a function with return type ‘int *’ makes pointer from integer without a cast [-Wint-conversion]
61 | return sign;
error: ld returned 1 exit status
A few things to notice,
The 'T' parameter wasn't used, so removed.
The 't' variable wasn't used, so removed.
The function return type shouldn't be a pointer to integer, it should be just an integer, from your requirements.
Your code is testing against an array declared in the function scope, and since it is an automatic variable, it is not initialized and may contain garbage values.
Your code is testing against an out of bounds index when using 'i < len' as the loop condition (ex.: considering that the array length is 3, when i == 2, comparing a[i] with a[i + 1] would access a[3], which is not within array boundaries that goes from index 0 to index 2.
With that in mind, a possible implementation with some tests is provided below, from what I can see from the requirements list, but bear in mind that I made some assumptions, since there was no restriction about them.
#include <assert.h>
#define SORTED_ASC 1
#define SORTED_DES -1
#define UNSORTED 0
int is_sorted(int *arr, int len)
{
int sorted = 0;
// I am assuming that this approach is reasonable, check your requirements.
if (len <= 1)
return UNSORTED;
for (int i = 0; i < len - 1; i++)
{
// Previous iteration detected order as 'descending', but current
// is 'ascending'.
if (sorted == SORTED_DES && arr[i] < arr[i + 1])
return UNSORTED;
// Previous iteration detected order as 'ascending', but current
// is 'descending'.
if (sorted == SORTED_ASC && arr[i] > arr[i + 1])
return UNSORTED;
// I am assuming that arrays with repeated values should remain classified
// as 'unsorted' until a different value appears, check your requirements.
if (arr[i] > arr[i + 1])
sorted = SORTED_DES;
else if (arr[i] < arr[i + 1])
sorted = SORTED_ASC;
}
return sorted;
}
void test_unsorted()
{
int arr[4][3] = {
{ 1, 3, 2 },
{ 2, 1, 3 },
{ 2, 3, 1 },
{ 3, 1, 2 }
};
for (int row = 0 ; row < 4 ; row++)
{
int res = is_sorted(arr[row], 3);
assert(res == UNSORTED);
}
}
void test_sorted_ascending()
{
int arr[] = { 1, 2, 3 };
int res = is_sorted(arr, 3);
assert(res == SORTED_ASC);
}
void test_sorted_descending()
{
int arr[] = { 3, 2, 1 };
int res = is_sorted(arr, 3);
assert(res == SORTED_DES);
}
void test_with_repeated_values()
{
int sorted_asc[] = { 1, 1, 2 };
int sorted_asc_res = is_sorted(sorted_asc, 3);
assert(sorted_asc_res == SORTED_ASC);
int sorted_des[] = { 3, 3, 2 };
int sorted_des_res = is_sorted(sorted_des, 3);
assert(sorted_des_res == SORTED_DES);
int unsorted[] = { 1, 1, 1 };
int unsorted_res = is_sorted(unsorted, 3);
assert(unsorted_res == UNSORTED);
}
int main(void)
{
test_unsorted();
test_sorted_ascending();
test_sorted_descending();
test_with_repeated_values();
}
I was asked to make a function that swaps two sections in array.
Something like this,
array[] = {1 , 2, 5, 7, 8, a , b, c}
| |
sections: First Second
The signature is void reverse_reg(int *arr, int s, int k, int j) where arr is the array, s is the first index of the first section, k is the last index of the first section and j denotes the end of the second section, the start is k ( since indexing in C start from 0 )
So far I have something something like this,
void reverse_reg(int *arr, int s, int k, int j)
{
for (int i = s; i < j; i++)
{
if (i > k / 2) /* swap the rest */
{
swap(&arr[i], &arr[j - i + 1]); /* this is wrong */
}
else
{
swap(&arr[i], &arr[k + i + 1]);
}
}
}
I have tested the else block and so far it swaps successfully the second section, producing,
result:
a b c 7 8 1 2 5
Though, I haven't been able to find a way to swap the second part, since the if block, produces something completely wrong (and it makes sense), which makes me think that the initial logic is wrong. Any hints?
If it helps, the way I call the function is, reverse_reg(arr, 0, 4, 8);
The resulting array should be:
result:
a b c 1 2 5 7 8
As pointed out by #EugeneSh., a simple way is to reverse each section and then reverse the whole array. It could be as simple as:
void swap(int* i, int* j) {
int k = *i;
*i = *j;
*j = k;
}
void reverse(int arr[], int len) {
for (int i = 0; i < len / 2; i++) {
swap(arr + i, arr + len - i - 1);
}
}
void reverse_reg(int* arr, int s, int k, int j) {
// you use last index of initial section while I need index of second one
++k;
reverse(arr + s, k - s);
reverse(arr + k, j - k);
reverse(arr + s, j - s);
}
"12578abc"
"abc12578"
Assuming array is declared as unsigned char array[8];, this can be a rotate operation on 64-bit integer. Using a rotate function, we can shift "abc" to the left, and "12578" to the right, then combine their result:
uint64_t rot_left_64(uint64_t num, int n)
{
return (num << n) | (num >> (64 - n));
}
uint64_t num = 0x01020507080a0b0c;
num = rot_left_64(num , 8 * 5);
printf("%016llX\n", n); //output 0x0A0B0C0102050708
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
array a1 = [1, 2, 3, 4, 5, 8];
array a2 = [1, 4, 5];
array a3 = a1 - a2; /* [2, 3, 8] */
array a4 = a2 - a1; /* print -None */
Here array would be the type my program uses to represent a struct which is used as a container. The rest of it is pseudo code, of course I'm not creating the arrays like that nor subtracting.
The simplest solution I can think of involves nested loops. any idea to solve an efficient way to solve this problem?
You want set difference. If both arrays are sorted, and contain no duplicates, you can iterate through both simultaneously:in linear time.
Whenever you encounter an element b in list B greater than the current element a of A, you can be sure that B does not contain a (or it would not be sorted). Then a is in A and not B, so it is in your output. Proceed to the next element of A, and compare it to the first element of B greater than the previous a, which is your current b. If b < a, it is also less than any remaining element of a, so you can advance to the next element of b. If you do encounter a == b, it is not in the set difference, so compare the next elements of both lists. If you reach the end of B first, add all remaining elements of A. When you reach the end of A, stop.
You can sort a list and remove duplicates in O(n log n) time, or faster if you can radix sort.
Sample Code
#include <assert.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
void print_set( const size_t asize, const int a[asize] )
{
const ptrdiff_t n = (ptrdiff_t)asize;
assert(n >= 0);
putchar('{');
if (n > 0) {
printf( "%d", a[0] );
for ( ptrdiff_t i = 1; i < n; ++i )
printf( ", %d", a[i] );
}
putchar('}');
fflush(stdout);
return;
}
size_t setdiff( const size_t asize, const int a[asize],
const size_t bsize, const int b[bsize],
const size_t csize, int c[csize] )
/* Calculates c = a - b, where a, b and c are sets. Returns the number of
* elements in c. The destination array c must be large enough to hold the
* result (asize elements are always enough). All sets must be sorted and
* contain no duplicates (checked at runtime).
*/
{
ptrdiff_t i = 0, j = 0, k = 0;
const ptrdiff_t m = (ptrdiff_t)asize;
const ptrdiff_t n = (ptrdiff_t)bsize;
const ptrdiff_t p = (ptrdiff_t)csize;
assert(m >= 0);
assert(n >= 0);
assert(p >= 0);
while ( i < m ) {
if ( j == n || a[i] < b[j] ) {
assert( k < p );
c[k++] = a[i++];
assert( i == m || a[i] > a[i-1]);
} else if ( a[i] > b[j] ) {
++j;
assert( j == n || b[j] > b[j-1]);
} else {
assert( a[i] == b[j] );
++i;
assert( i == m || a[i] > a[i-1]);
++j;
assert( j == n || b[j] > b[j-1]);
}
}
return (size_t)k;
}
int main(void)
{
static const int a[] = {1, 2, 3, 4, 5, 6};
static const size_t m = sizeof(a)/sizeof(a[0]);
static const int b[] = {1, 4, 5};
static const size_t n = sizeof(b)/sizeof(b[0]);
int c[6] = {0};
static const size_t p = sizeof(c)/sizeof(c[0]);
print_set( m, a );
printf(" - ");
print_set( n, b );
printf(" = ");
const size_t q = setdiff( m, a, n, b, p, c );
print_set( q, c );
printf(".\n");
print_set( n, b );
printf(" - ");
print_set( m, a );
printf(" = ");
const size_t r = setdiff( n, b, m, a, p, c );
print_set( r, c );
printf(".\n");
return EXIT_SUCCESS;
}
Assuming the two arrays are sorted, as in your examples, you should be able to locate common elements optimally using bsearch. I've provided an example, but in the future please make an effort to write your own C code in the future, then I/we might be able to help you better!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compare(void const *x, void const *y) {
return memcmp(x, y, sizeof (int)); // XXX: This might not be what you expect for negative values!
}
size_t difference(void *dest, size_t dest_size, void const *x, size_t x_size, void const *y, size_t y_size, size_t size, int (*compare)(void const *, void const *)) {
typedef unsigned char item[size];
item const *a = x, *b = y;
item *d = dest;
size_t cursor = 0, d_size = 0;
for (size_t x = 0; x < x_size; x++) {
item *ptr = bsearch(a + x, b + cursor, y_size - cursor, size, compare);
if (ptr) {
cursor = ptr - b;
}
else {
memcpy(d[d_size++], a[x], sizeof (item));
}
}
return d_size;
}
void print(char *name, int array[], size_t array_size) {
printf("%s: %s", name, array_size ? "" : "NONE\n");
for (size_t x = 0; x < array_size; x++, putchar(x < array_size ? ',' : '\n')) {
printf("%d", array[x]);
}
}
int main(void) {
int a[] = { 1, 2, 3, 4, 5, 8 },
b[] = { 1, 4, 5 },
c[sizeof a / sizeof *a],
d[sizeof a / sizeof *a];
size_t c_size = difference(c, sizeof c / sizeof *c,
a, sizeof a / sizeof *a,
b, sizeof b / sizeof *b,
sizeof (int), compare);
size_t d_size = difference(d, sizeof d / sizeof *d,
b, sizeof b / sizeof *b,
a, sizeof a / sizeof *a,
sizeof (int), compare);
print("c", c, c_size);
print("d", d, d_size);
}
First, you will obviously need a find function:
int find(int val, const int* a, int na)
{
int i;
for (i = 0; i < na; ++i)
{
if (val == a[i])
return i;
}
return -1;
}
The diff function become quite trivial, assuming you have an allocated array for the result. r should be able to hold at least na elements.
int diff(int* r, const int* a, int na, const int* b, int nb)
{
// returns the number of elenment in resulting set.
// on output r contains the elements from a that are not found in b
// expects r to provide enough room for na elements
int i, nr;
nr = 0;
for (i = 0; i < na; ++i)
{
if (find(a[i], b, nb) < 0)
{
r[nr++] = a[i];
}
}
return nr;
}
I know that in a sense, this is still a nested loop. But it is much more readable. Plus, you've gained a generic find() function that you can use elsewhere in your code.
I thought the difference of two sets was not as you describe, but defined as A with intersection of A and B removed. i.e. If a value is found several times in A, but only once in B, only one element of A is removed from the result set. For this case, you'd need a remove function.
int remove(int at, int* a, int na)
{
// removes first occurence of val in a.
// returns the number of elements in a after remove op.
if (0 <= at && at < na)
{
memmove(&a[at], &a[at + 1], sizeof(int) * (na - (at + 1)));
return na - 1;
}
return na;
}
The diff when elements are not unique is not much more complex, we'll loop on b.
int difference(int* r, const int* a, int na, const int* b, int nb)
{
// returns elements from a, minus set b.
// handles non-unique cases, so this is the true difference or a-b
// returns the number of elements in resulting set
int nr, found;
memcpy(r, a, na * sizeof(int));
nr = na;
for (i = 0; i < nb; ++i)
{
found = find(b[i], r, nr);
if (found >= 0)
{
nr = remove(found, r, nr);
}
}
return nr;
}
I did not try to compile these, so there might be some typos, but it should be fairly close..
Edit: These algorithms have a complexity of O(N^2), so by sorting a (or b) and using a binary search, you could get them down to 1) O(2NlogN) 2) O(3NlogN), which is not bad, since you'd only need to change the find() function to implement optimization.
How can one iterate through order of execution?
I am developing a piece of software that have several steps to compute over some data, and i was thinking in may changing the order of those steps pragmatically so i can check what would be the best order for some data.
Let me exemplify: I have let's say 3 steps (it's actually more):
stepA(data);
stepB(data);
stepC(data);
And I want a contraption that allow me to walk thought every permutation of those steps and then check results. Something like that:
data = originalData; i=0;
while (someMagic(&data,[stepA,stepB,stepC],i++)){
checkResults(data);
data = originalData;
}
then someMagic execute A,B then C on i==0. A, C then B on i==1. B, A then C on i==2 and so on.
You can use function pointers, maybe something like the following:
typedef void (*func)(void *data);
int someMagic(void *data, func *func_list, int i) {
switch (i) {
case 0:
func_list[0](data);
func_list[1](data);
func_list[2](data);
break;
case 1:
func_list[0](data);
func_list[2](data);
func_list[1](data);
break;
case 2:
func_list[1](data);
func_list[0](data);
func_list[2](data);
break;
default: return 0;
}
return 1;
}
func steps[3] = {
stepA,
stepB,
stepC
}
while (someMagic(&data, steps, i++)) {
....
}
The key is to find a way to iterate over the set of permutations of the [0, n[ integer interval.
A permutation (in the mathematical meaning) can be seen as a bijection of [0, n[ into itself and can be represented by the image of this permutation, applied to [0, n[.
for example, consider the permutation of [0, 3[:
0 -> 1
1 -> 2
2 -> 0
it can be seen as the tuple (1, 2, 0), which in C, translate naturally to the array of integers permutation = (int []){1, 2, 0};.
Suppose you have an array of function pointers steps, then for each permutation, you'll then want to call steps[permutation[i]], for each value of i in [0, n[.
The following code implements this algorithm:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
static void stepA(int data) { printf("%d: %s\n", data, __func__); }
static void stepB(int data) { printf("%d: %s\n", data, __func__); }
static void stepC(int data) { printf("%d: %s\n", data, __func__); }
static void (* const steps[])(int) = {stepA, stepB, stepC,};
static int fact(int n) { return n == 0 ? 1 : fact(n - 1) * n; }
static int compare_int(const void *pa, const void *pb)
{
return *(const int *)pa - *(const int *)pb;
}
static void get_next_permutation(int tab[], size_t n)
{
int tmp;
unsigned i;
unsigned j;
unsigned k;
/* to find the next permutation in the lexicographic order
* source: question 4 (in french, sorry ^^) of
* https://liris.cnrs.fr/~aparreau/Teaching/INF233/TP2-permutation.pdf
. */
/* 1. find the biggest index i for which tab[i] < tab[i+1] */
for (k = 0; k < n - 1; k++)
if (tab[k] < tab[k + 1])
i = k;
/* 2. Find the index j of the smallest element, bigger than tab[i],
* located after i */
j = i + 1;
for (k = i + 1; k < n; k++)
if (tab[k] > tab[i] && tab[k] < tab[j])
j = k;
/* 3. Swap the elements of index i and j */
tmp = tab[i];
tab[i] = tab[j];
tab[j] = tmp;
/* 4. Sort the array in ascending order, after index i */
qsort(tab + i + 1, n - (i + 1), sizeof(*tab), compare_int);
}
int main(void)
{
int n = sizeof(steps) / sizeof(*steps);
int j;
int i;
int permutation[n];
int f = fact(n);
/* first permutation is identity */
for (i = 0; i < n; i++)
permutation[i] = i;
for (j = 0; j < f; j++) {
for (i = 0; i < n; i++)
steps[permutation[i]](i);
if (j != f - 1)
get_next_permutation(permutation, n);
}
return EXIT_SUCCESS;
}
The outer loop in main, indexed by j, iterates over all the n! permutations, while the inner one, indexed by i, iterates overs the n steps.
The get_next_permutation modifies the permutation array in place, to obtain the next permutation in the lexicographical order.
Note that it doesn't work when the permutation in input is the last one (n - 1, ..., 1, 0), hence the if (j != f - 1) test.
One could enhance it to detect this case (i isn't set) and to put the first permutation (0, 1, ..., n - 1) into the permutation array.
The code can be compiled with:
gcc main.c -o main -Wall -Wextra -Werror -O0 -g3
And I strongly suggest using valgrind as a way to detect off-by-one errors.
EDIT: I just realized I didn't answer the OP's question precisely. The someMagic() function would allow a direct access to the i-th permutation, while my algorithm only allows to compute the successor in the lexicographic order. But if the aim is to iterate on all the permutations, it will work fine. Otherwise, maybe an answer like this one should match the requirement.
I've come to a solution that is simple enough:
void stepA(STRUCT_NAME *data);
void stepB(STRUCT_NAME *data);
void stepC(STRUCT_NAME *data);
typedef void (*check)(STRUCT_NAME *data);
void swap(check *x, check *y) {
check temp;
temp = *x;
*x = *y;
*y = temp;
}
void permute(check *a, int l, int r,STRUCT_NAME *data) {
int i, j = 0, score;
HAND_T *copy, *copy2, *best_order = NULL;
if (l == r) {
j = 0;
while (j <= r) a[j++](data);
} else {
for (i = l; i <= r; i++) {
swap((a + l), (a + i));
permute(a, l + 1, r, data);
swap((a + l), (a + i));
}
}
}
check checks[3] = {
stepA,
stepB,
stepC,
};
int main(void){
...
permute(checks,0,2,data)
}
I have some difficulties in writing a code which determines whether two unsorted arrays are permutation of each other , by using recursion.
I know how to determine it by non-recursive code, using sorts - but I dont know how to do it by using recursion.
So far, I cant get any real idea...
int CheckPermutation(int arr1[], int arr2[], int size) {
if (size == 0)
return 1;
if (size == 1)
return (arr1[0] > arr2[0]);
}
that's what I have tried, I find it difficult to continue from that point
Here is an implementation for comparing 2 unsorted arrays without modifying them that uses recursion:
#include <stdio.h>
// count occurrences of value in an array using recursion
int rcount(int value, const int *a, int size) {
return size == 0 ? 0 : (value == *a) + rcount(value, a + 1, size - 1);
}
// check if all entries in a have the same number of occurrences in a and b
int check_perm(const int *a, const int *b, int size) {
for (int i = 0; i < size; i++) {
if (rcount(a[i], a, size) != rcount(a[i], b, size))
return 0;
}
return 1;
}
int main(void) {
int a[] = { 1, 2, 3, 3, 4, 4, 4, 5, 6, };
int b[] = { 1, 3, 2, 4, 5, 4, 4, 6, 3, };
int c[] = { 1, 3, 2, 4, 5, 4, 4, 6, 6, };
if (check_perm(a, b, sizeof(a) / sizeof(*a)))
printf("arrays a and b match\n");
if (!check_perm(a, c, sizeof(a) / sizeof(*a)))
printf("arrays a and c do not match\n");
if (!check_perm(b, c, sizeof(b) / sizeof(*b)))
printf("arrays b and c do not match\n");
return 0;
}
EDIT:
Here is a solution with a single recursive function. Both arrays are potentially modified. If indeed check_perm() returns non zero, both arrays will have been sorted:
int check_perm(const int *a, const int *b, int size) {
if (size > 1) {
for (int i = 1; i < size; i++) {
if (a[0] > a[i]) {
int temp = a[0];
a[0] = a[i];
a[i] = temp;
}
if (b[0] > b[i]) {
int temp = b[0];
b[0] = b[i];
b[i] = temp;
}
}
return (a[0] == b[0]) && check_perm(a + 1, b + 1, size - 1);
}
return 1;
}