The challenge
Instructions
Write a function that takes a single string (word
) as argument. The function must return an ordered list containing the indexes of all capital letters in the string.
Example
Test.assertSimilar( capitals('CodEStAr'), [0,3,4,6] );
The solution in C
Option 1:
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
size_t *find_capitals(const char *word, size_t *nb_uppercase)
{
size_t n = strlen(word);
size_t *arr = (size_t *) calloc(n, sizeof(size_t));
size_t j = 0;
for(size_t i=0; i<n; i++) {
if(word[i] >='A' && word[i] <='Z') {
arr[j++] = i;
}
}
*nb_uppercase = j;
return realloc(arr, j * sizeof(size_t));
}
Option 2:
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
size_t *find_capitals (const char *word, size_t *nb_uppercase)
{
if (!word || !*word) {
*nb_uppercase = 0;
return 0;
}
*nb_uppercase = 0;
for (char const *itr = word; *itr; itr++)
if (*itr >= 'A' && *itr <= 'Z')
(*nb_uppercase)++;
size_t * const buffer = malloc(*nb_uppercase * sizeof(size_t));
for (size_t i = 0, j = 0; word[i]; i++)
if (word[i] >= 'A' && word[i] <= 'Z')
buffer[j++] = i;
return buffer;
}
Option 3:
#include <stddef.h>
size_t *find_capitals (const char *word, size_t *nb_uppercase)
{
size_t* arr = malloc(50 * sizeof(int));
int i = 0;
int a = 0;
while(word[i] != '\0'){
if(word[i] >= 'A' && word[i] <= 'Z'){
arr[a] = i;
a++;
}
i++;
}
*nb_uppercase = a;
return arr;
return NULL;
}
Test cases to validate our solution
#include <time.h>
#include <stdlib.h>
#include <criterion/criterion.h>
extern void do_test (const char *word, size_t exp_len, const size_t expected[exp_len]);
#define ARR_LEN(array) (sizeof(array) / sizeof *(array))
#define sample_test(word, expected) do_test(word, ARR_LEN(expected), expected)
Test(tests_suite, sample_tests)
{
do_test("", 0, NULL);
do_test("4ysdf4", 0, NULL);
sample_test("CodEStAr", ((const size_t[]){0, 3, 4, 6}));
sample_test("aAbB", ((const size_t[]){1, 3}));
sample_test("ABCDEF", ((const size_t[]){0, 1, 2, 3, 4, 5}));
}
enum { MAX_LEN = 40 };
#define take_char(str) ((str)[rand() % (sizeof(str) - 1)])
// generates a random word, fill the indexes[] array, return the number of uppercase letters
static size_t random_word (char *word, size_t uppercase_indexes[])
{
size_t length = 1 + (rand() % MAX_LEN);
size_t idx_caps = 0;
for (size_t i = 0; i < length; i++) {
switch (rand() % 3) {
case 0:
word[i] = take_char("abcdefghijklmnopqrstuvwxyz");
break;
case 1:
word[i] = take_char("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
uppercase_indexes[idx_caps++] = i;
break;
default:
word[i] = take_char("@&~#0123456789-*/=,;:!.");
break;
}
}
word[length] = '\0';
return idx_caps;
}
Test(tests_suite, random_tests)
{
srand(time(NULL));
size_t expected[MAX_LEN];
char word[MAX_LEN + 1];
for (int i = 0; i < 100; i++) {
size_t exp_len = random_word(word, expected);
do_test(word, exp_len, expected);
}
}