C Kata - Are you playing banjo?

By Lochard | As a newbie programmer | 11 Jan 2023


Learning from YayoDrayber, I am sharing my CodeWars

DESCRIPTION:
Create a function which answers the question "Are you playing banjo?".
If your name starts with the letter "R" or lower case "r", you are playing banjo!

The function takes a name as its only argument, and returns one of the following strings:

name + " plays banjo"
name + " does not play banjo"

Names given are always valid strings.

Starting code

#include <stdlib.h>

char *are_you_playing_banjo(const char *name) {
  return calloc(1, 1);
}

My attempt

#include <stdlib.h>
#include <string.h>

char *are_you_playing_banjo(const char *name) {
  char *ret;
  if (name[0] == 'R' || name[0] == 'r') {
    ret = malloc((strlen(name) + 13) * sizeof(char));
    for (int i = 0; i < strlen(name); i++)
      ret[i] = name[i];
    strcat(ret, " plays banjo");
  } else {
    ret = malloc((strlen(name) + 21) * sizeof(char));
    for (int i = 0; i < strlen(name); i++)
      ret[i] = name[i];
    strcat(ret, " does not play banjo");
  }
  
  return ret; // memory will be freed
}

It passed all the tests, but there is actually a bug. maclloc() doesn't initialize the memory. The characters of name will be assigned without an issue, but there could be garbage follows. In that case, the string would be concatenated after the garbage.

Best Practice

char* are_you_playing_banjo(const char* n) {
  char *r = (char*)calloc(strlen(n) + 20, 1);
  strcpy(r, n);
  strcat(r, (n[0] == 'R' || n[0] == 'r') ? " plays banjo" : " does not play banjo");
  return r;
}

Clean. The wasted memory when the string is short ia negligible on morden machines.

Clever

#include <stdio.h>


char* are_you_playing_banjo(const char* name) {
  const char* banjo = (name[0] == 'R' || name[0] == 'r')
    ? " plays banjo"
    : " does not play banjo";
  char* ret = NULL;
  asprintf(&ret, "%s%s", name, banjo);
  return ret;
}

Left memory allocation to asprintf(). There are actually many solutions used the same, but this one has the most votes.

My Pick
= Clever
Learned asprintf() which looks very handy. It also includes just stdio instead of stdlib, it is smaller if I have not mistaken. Although the stdlib on CodeWars seems to contain fewer functions than the one on my system.

My post-Kata snippet

#include <stdio.h>

char *are_you_playing_banjo(const char *name) {
  char *ret;
  asprintf(&ret, "%s %s ", name,
           (name[0] == 'R' || name[0] == 'r')
           ? "plays"
           : "does not play");
  return ret;
}

 

My code snippets on GitHub

How do you rate this article?

2


Lochard
Lochard

20240228 Arrived in the UK for about 2 week. All my fears persist. Some are even getting worse. https://github.com/locharp/asylum_diary/


As a newbie programmer
As a newbie programmer

Sharing entry level codes. My snippets on GitHub https://github.com/locharp/code-snippets

Send a $0.01 microtip in crypto to the author, and earn yourself as you read!

20% to author / 80% to me.
We pay the tips from our rewards pool.