C Array Exercises

Here are 13 problems, from beginner to advanced, that use arrays. They cover the basics of 1D arrays, 2D arrays (matrices), sorting and binary search. Write your code in the browser and press "Check": it is run with real gcc on several inputs to see whether the output is correct.

How to use these problems
  1. Read the problem and the sample run, then write your code in the box
  2. Press "▶ Run" to try it with your own input
  3. Press "✔ Check" to test the output against several prepared inputs
  4. Stuck? Open "Hint". Solved it? Compare with "Solution & explanation"
Checking rules
  • Print output exactly as in the sample run. Do not print input prompts such as "Enter a number"
  • Trailing spaces at line ends and trailing blank lines are ignored
  • Your code is saved automatically in this browser

Note: Run and Check send your code to Wandbox, a free external compiler service, and run it with gcc.

13 problems (Beginner 4 · Intermediate 5 · Advanced 4)

Arrays (13 problems)

A01 Beginner

Problem 1. Print in reverse order

Read an integer N (1 ≤ N ≤ 100) on the first line and N integers on the second line, and print them on one line, separated by spaces, in the reverse of the input order.
Sample run (input is underlined)
5 3 1 4 1 5 5 1 4 1 3
Your code
"Run" executes your code with the input above. "Check" tests it against 4 prepared inputs.
First read everything by repeating scanf("%d", &a[i]); with for (i = 0; i < n; i++). To print, start at i = n - 1 and go back to 0 with i--.
#include <stdio.h>

int main(void) {
    int n;
    int a[100];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    for (int i = n - 1; i >= 0; i--) {
        printf("%d ", a[i]);
    }
    printf("\n");
    return 0;
}
Explanation: The indexes of an array with N elements are 0 to N−1. If you start at i = n, you read a[n], which is outside the array (out-of-bounds access is undefined behavior; it may not cause an error and just print a garbage value). The end condition must also be i >= 0, or a[0] is not printed.
A02 Beginner

Problem 2. Sum and average

Read an integer N (1 ≤ N ≤ 100) on the first line and N integers (each between −1000 and 1000) on the second line, and print their sum and average. Print the average to 2 decimal places.
Sample run (input is underlined)
5 1 2 3 4 5 Sum: 15 Average: 3.00
Your code
"Run" executes your code with the input above. "Check" tests it against 5 prepared inputs.
Initialize a variable sum for the total to 0 and repeat sum += a[i]; N times. For the average, divide with one side converted to double: (double)sum / n.
#include <stdio.h>

int main(void) {
    int n;
    int a[100];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    int sum = 0;
    for (int i = 0; i < n; i++) {
        sum += a[i];
    }
    printf("Sum: %d\n", sum);
    printf("Average: %.2f\n", (double)sum / n);
    return 0;
}
Explanation: Plain sum / n is division of two ints, and the fractional part is discarded (5 / 3 is 1). If you write (double)sum / n, sum is converted to double before the division, so you get 1.666…. (double)(sum / n) converts after dividing, so it doesn't help.
A03 Beginner

Problem 3. Positions of the maximum and minimum

Read an integer N (1 ≤ N ≤ 100) on the first line and N integers on the second line, and print the maximum and the minimum together with their positions (the first element is position 1). If the same value appears more than once, print the position of the earliest one.
Sample run (input is underlined)
5 3 9 2 9 1 Max: 9 (position 2) Min: 1 (position 5)
Your code
"Run" executes your code with the input above. "Check" tests it against 4 prepared inputs.
If you remember the index instead of the value itself, you know both the value and the position. Start with imax = 0 and update imax = i when a[i] > a[imax]. When printing, the position is imax + 1.
#include <stdio.h>

int main(void) {
    int n;
    int a[100];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    int imax = 0, imin = 0;
    for (int i = 1; i < n; i++) {
        if (a[i] > a[imax]) imax = i;
        if (a[i] < a[imin]) imin = i;
    }
    printf("Max: %d (position %d)\n", a[imax], imax + 1);
    printf("Min: %d (position %d)\n", a[imin], imin + 1);
    return 0;
}
Explanation: If you start the maximum at 0, you get the wrong answer when all the numbers are negative. Starting from the first element is the safe choice. Also, if you compare with >=, it updates on equal values too, and you end up with the last position.
A04 Beginner

Problem 4. Differences between neighbors

Read an integer N (1 ≤ N ≤ 100) on the first line and N integers a1, a2, …, aN on the second line, and print the differences between neighboring elements, a2−a1, a3−a2, …, aN−aN−1, on one line separated by spaces. When N is 1, print an empty line.
Sample run (input is underlined)
5 3 7 4 4 10 4 -3 0 6
Your code
"Run" executes your code with the input above. "Check" tests it against 4 prepared inputs.
There are N−1 differences. Run i from 0 to n - 2 and print a[i + 1] - a[i]. The loop condition is i < n - 1.
#include <stdio.h>

int main(void) {
    int n;
    int a[100];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    for (int i = 0; i < n - 1; i++) {
        printf("%d ", a[i + 1] - a[i]);
    }
    printf("\n");
    return 0;
}
Explanation: Whenever you use a[i + 1], think about whether i + 1 is inside the array. If the condition is i < n, the last step reads a[n] (out of bounds). When N=1, the loop doesn't run even once, and only an empty line is printed.
A05 Intermediate

Problem 5. Searching for a value

Read an integer N (1 ≤ N ≤ 100) on the first line, N integers on the second line, and the value X to search for on the third line. If X is in the array, print the position where it first appears (the first element is position 1) and how many times X appears. If it isn't there at all, print "Not found".
Sample run (input is underlined)
6 4 2 7 2 9 2 2 First position: 2 Count: 3
Your code
"Run" executes your code with the input above. "Check" tests it against 5 prepared inputs.
Initialize the position variable to −1, meaning "not found yet". When a[i] == x, record i if the position is still −1, and increase the count by 1 every time.
#include <stdio.h>

int main(void) {
    int n, x;
    int a[100];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
    scanf("%d", &x);

    int pos = -1, count = 0;
    for (int i = 0; i < n; i++) {
        if (a[i] == x) {
            if (pos == -1) pos = i;
            count++;
        }
    }

    if (count == 0) {
        printf("Not found\n");
    } else {
        printf("First position: %d\n", pos + 1);
        printf("Count: %d\n", count);
    }
    return 0;
}
Explanation: If you only need the first match, you can break as soon as you find it, but this problem also counts them, so you check to the end. Instead, record the position only the first time (if you do pos = i every time, you get the last position). Representing "not found" with −1, a value that can never be an index, is a standard technique.
A06 Intermediate

Problem 6. Values at or above the average

Read an integer N (1 ≤ N ≤ 100) on the first line and N integers (each between −1000 and 1000) on the second line. On the first output line, print the average to 2 decimal places; on the second, print the values that are at or above the average, in input order, separated by spaces.
Sample run (input is underlined)
6 50 60 70 80 90 100 Average: 75.00 80 90 100
Your code
"Run" executes your code with the input above. "Check" tests it against 5 prepared inputs.
You can't know the average until you have read everything. So store the values in an array first, compute the average, then go through the array again from the start and print those with a[i] >= avg.
#include <stdio.h>

int main(void) {
    int n;
    int a[100];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    int sum = 0;
    for (int i = 0; i < n; i++) {
        sum += a[i];
    }
    double avg = (double)sum / n;
    printf("Average: %.2f\n", avg);

    for (int i = 0; i < n; i++) {
        if (a[i] >= avg) {
            printf("%d ", a[i]);
        }
    }
    printf("\n");
    return 0;
}
Explanation: Processing that "can't be decided until you've seen everything" is exactly when you need an array. If you compute the average with int avg = sum / n;, the input 1 2 2 gives an average of 1, and 1 gets printed too. In the comparison a[i] >= avg, the int is converted to double before comparing.
A07 Intermediate

Problem 7. Score histogram

Read the number of people N (1 ≤ N ≤ 100) on the first line and N scores (integers from 0 to 100) on the second line, and print a frequency distribution in steps of 10 points, using the number of * characters. There are 10 ranges: 0-9, 10-19, …, 80-89, 90-100 (100 belongs to 90-100). Print ranges with nobody in them too, like "20-29:".
Sample run (input is underlined)
10 0 9 10 55 59 60 89 90 99 100 0-9: ** 10-19: * 20-29: 30-39: 40-49: 50-59: ** 60-69: * 70-79: 80-89: * 90-100: ***
Your code
"Run" executes your code with the input above. "Check" tests it against 4 prepared inputs.
Prepare an array int cnt[10] = {0}; to count the people in each range. The range number for a score s is s / 10, but 100 gives 10, so change it to 9 only in that case.
#include <stdio.h>

int main(void) {
    int n;
    int a[100];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    int cnt[10] = {0};
    for (int i = 0; i < n; i++) {
        int k = a[i] / 10;
        if (k == 10) k = 9;
        cnt[k]++;
    }

    for (int k = 0; k < 10; k++) {
        if (k == 9) {
            printf("90-100: ");
        } else {
            printf("%d-%d: ", k * 10, k * 10 + 9);
        }
        for (int j = 0; j < cnt[k]; j++) {
            printf("*");
        }
        printf("\n");
    }
    return 0;
}
Explanation: "Compute an index from the value and add 1 to that element" is the basic form of a frequency distribution (histogram). If you forget to handle 100, you write to cnt[10], which is out of bounds. Initialize the counting array with = {0} so that every element starts at 0 (an array inside a function has indeterminate contents unless you initialize it).
A08 Intermediate

Problem 8. The second largest value

Read an integer N (1 ≤ N ≤ 100) on the first line and N integers on the second line, and print the second largest value among the distinct values. For example, for 3 9 7 9 1 the largest is 9 and the second largest is 7. If there is no such value (all values are the same, or N is 1), print "No second largest value".
Sample run (input is underlined)
5 3 9 7 9 1 Second largest: 7
Your code
"Run" executes your code with the input above. "Check" tests it against 5 prepared inputs.
It is easier in two passes. The first pass finds the maximum max, and the second pass finds "the largest value that is smaller than max". In the second pass, use a variable (a flag) that means "nothing found yet".
#include <stdio.h>

int main(void) {
    int n;
    int a[100];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    int max = a[0];
    for (int i = 1; i < n; i++) {
        if (a[i] > max) max = a[i];
    }

    int found = 0, second = 0;
    for (int i = 0; i < n; i++) {
        if (a[i] < max && (!found || a[i] > second)) {
            second = a[i];
            found = 1;
        }
    }

    if (found) {
        printf("Second largest: %d\n", second);
    } else {
        printf("No second largest value\n");
    }
    return 0;
}
Explanation: If you sort and take the second element from the end, 3 9 7 9 1 gives 9 as the answer (the case where the maximum appears more than once). If you start second at a fixed value such as 0, it fails when all the numbers are negative. That is why found is used to say "accept the first value found as is".
A09 Intermediate

Problem 9. Row and column sums (2D array)

Read the number of rows R and columns C (1 ≤ R, C ≤ 10) on the first line, followed by R lines of C integers each. Print the sum of each row on one line and the sum of each column on the next line, separated by spaces.
Sample run (input is underlined)
2 3 1 2 3 4 5 6 Row sums: 6 15 Column sums: 5 7 9
Your code
"Run" executes your code with the input above. "Check" tests it against 4 prepared inputs.
a[i][j] is "row i, column j". For row sums, put i in the outer loop and loop over j; for column sums, put j in the outer loop and loop over i. Reset the sum variable to 0 every time you enter the outer loop.
#include <stdio.h>

int main(void) {
    int r, c;
    int a[10][10];
    scanf("%d %d", &r, &c);
    for (int i = 0; i < r; i++) {
        for (int j = 0; j < c; j++) {
            scanf("%d", &a[i][j]);
        }
    }

    printf("Row sums:");
    for (int i = 0; i < r; i++) {
        int sum = 0;
        for (int j = 0; j < c; j++) {
            sum += a[i][j];
        }
        printf(" %d", sum);
    }
    printf("\n");

    printf("Column sums:");
    for (int j = 0; j < c; j++) {
        int sum = 0;
        for (int i = 0; i < r; i++) {
            sum += a[i][j];
        }
        printf(" %d", sum);
    }
    printf("\n");
    return 0;
}
Explanation: If you write sum = 0 outside the nested loop, the previous row's sum carries over and you get a running total. Swapping the indexes, as in a[j][i], for the column sums is another common mistake; when R and C differ, it reads out of bounds.
A10 Advanced

Problem 10. Bubble sort and the number of swaps

Read an integer N (1 ≤ N ≤ 100) on the first line and N integers on the second line, sort them in increasing order with bubble sort, and print them separated by spaces. On the next line, print how many times two neighbors were swapped. Swap only "when the left one is larger" (don't swap when they are equal).
Sample run (input is underlined)
5 5 3 1 4 2 1 2 3 4 5 Swaps: 7
Your code
"Run" executes your code with the input above. "Check" tests it against 5 prepared inputs.
Run the outer loop N−1 times; in the inner loop move j from 0 to n - 2 - i and swap when a[j] > a[j + 1]. Use a temporary variable tmp for the swap.
#include <stdio.h>

int main(void) {
    int n;
    int a[100];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    int swaps = 0;
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - 1 - i; j++) {
            if (a[j] > a[j + 1]) {
                int tmp = a[j];
                a[j] = a[j + 1];
                a[j + 1] = tmp;
                swaps++;
            }
        }
    }

    for (int i = 0; i < n; i++) {
        printf("%d ", a[i]);
    }
    printf("\nSwaps: %d\n", swaps);
    return 0;
}
Explanation: If you write the swap as a[j] = a[j + 1]; a[j + 1] = a[j];, the first statement destroys the original a[j], so both end up with the same value. Always save it in tmp first. Each round of the outer loop fixes the maximum at the right end, so you can shrink the inner range to n - 1 - i. Note that the number of swaps equals the number of pairs where a larger value is to the left of a smaller one (the inversion count).
A11 Advanced

Problem 11. Selection sort, step by step

Read an integer N (2 ≤ N ≤ 20) on the first line and N integers on the second line, and sort them in increasing order with selection sort. In pass k (k = 1, 2, …, N−1), find the minimum among the k-th and later elements (if there are several minimums, take the leftmost) and swap it with the k-th element. After each pass, print the array at that point after "Pass k: ", separated by spaces.
Sample run (input is underlined)
5 5 3 1 4 2 Pass 1: 1 3 5 4 2 Pass 2: 1 2 5 4 3 Pass 3: 1 2 3 4 5 Pass 4: 1 2 3 4 5
Your code
"Run" executes your code with the input above. "Check" tests it against 4 prepared inputs.
In terms of indexes, pass k decides the element at position i = k - 1. Start with imin = i, check j = i + 1 to n - 1, and set imin = j when a[j] < a[imin]. Finally, swap a[i] and a[imin] and print the array.
#include <stdio.h>

int main(void) {
    int n;
    int a[100];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    for (int i = 0; i < n - 1; i++) {
        int imin = i;
        for (int j = i + 1; j < n; j++) {
            if (a[j] < a[imin]) imin = j;
        }
        int tmp = a[i];
        a[i] = a[imin];
        a[imin] = tmp;

        printf("Pass %d:", i + 1);
        for (int j = 0; j < n; j++) {
            printf(" %d", a[j]);
        }
        printf("\n");
    }
    return 0;
}
Explanation: Selection sort repeats "find the minimum of the rest and bring it to the front". The key is to remember the minimum by its index (imin), not its value; if you remember only the value, you don't know where to swap with. If you compare with <=, the rightmost minimum is chosen when there are several, and the intermediate results for the input 3 1 3 1 change.
A12 Advanced

Problem 12. Matrix multiplication

Read integers n, m and p (1 ≤ n, m, p ≤ 10) on the first line. Then read an n×m matrix A on n lines and an m×p matrix B on m lines (elements are integers from −100 to 100). Print the product C = AB (n rows, p columns), one row per line, with elements separated by spaces. The (i, j) element of C is the sum of the products of the corresponding elements of row i of A and column j of B.
Sample run (input is underlined)
2 3 2 1 2 3 4 5 6 7 8 9 10 11 12 58 64 139 154
Your code
"Run" executes your code with the input above. "Check" tests it against 5 prepared inputs.
This needs a triple loop. Loop over i (rows of C) and j (columns of C), and inside them loop k from 0 to m−1, accumulating c[i][j] += a[i][k] * b[k][j];.
#include <stdio.h>

int main(void) {
    int n, m, p;
    int a[10][10], b[10][10], c[10][10];
    scanf("%d %d %d", &n, &m, &p);
    for (int i = 0; i < n; i++) {
        for (int k = 0; k < m; k++) {
            scanf("%d", &a[i][k]);
        }
    }
    for (int k = 0; k < m; k++) {
        for (int j = 0; j < p; j++) {
            scanf("%d", &b[k][j]);
        }
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < p; j++) {
            c[i][j] = 0;
            for (int k = 0; k < m; k++) {
                c[i][j] += a[i][k] * b[k][j];
            }
        }
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < p; j++) {
            printf("%d ", c[i][j]);
        }
        printf("\n");
    }
    return 0;
}
Explanation: If you use += on c[i][j] without initializing it to 0, you start adding to an indeterminate value. The loop limits are n for i, p for j and m for k. If you mix any of them up, the tests with square matrices may pass, but it reads out of bounds when n, m and p differ.
A13 Advanced

Problem 13. Binary search

Read an integer N (1 ≤ N ≤ 1000) on the first line and N integers in increasing order with no duplicates on the second line. On the third line read the number of queries Q (1 ≤ Q ≤ 100), followed by Q lines with one value to search for each. For each value, print on its own line its position in the array (the first element is position 1), or "Not found" if it isn't there. Use binary search.
Sample run (input is underlined)
7 2 3 5 7 11 13 17 4 7 2 17 4 4 1 7 Not found
Your code
"Run" executes your code with the input above. "Check" tests it against 4 prepared inputs.
Represent the search range by indexes lo to hi (initially 0 to N−1). While lo <= hi, compare with the middle element mid and halve the range. If a[mid] is smaller, set lo = mid + 1; if it is larger, set hi = mid - 1.
#include <stdio.h>

int main(void) {
    int n, q;
    int a[1000];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
    scanf("%d", &q);

    for (int t = 0; t < q; t++) {
        int x;
        scanf("%d", &x);

        int lo = 0, hi = n - 1, pos = -1;
        while (lo <= hi) {
            int mid = lo + (hi - lo) / 2;
            if (a[mid] == x) {
                pos = mid;
                break;
            } else if (a[mid] < x) {
                lo = mid + 1;
            } else {
                hi = mid - 1;
            }
        }

        if (pos >= 0) {
            printf("%d\n", pos + 1);
        } else {
            printf("Not found\n");
        }
    }
    return 0;
}
Explanation: Binary search halves the range with every comparison, so even with N=1000 it takes at most about 10 comparisons (checking from the start would take up to 1000). If you forget the ±1, as in lo = mid, the range may never shrink and you get an infinite loop. And if the condition is lo < hi, the loop ends without checking the last remaining element. It assumes the array is sorted; if it isn't, you must sort it first.

Review these lessons

← Back to all practice problems