Avatar of vlzware

vlzware's solution

to Bob in the C Track

Published at Jul 13 2018 · 1 comment
Instructions
Test suite
Solution

Note:

This solution was written on an old version of Exercism. The tests below might not correspond to the solution code, and the exercise may have changed since this code was written.

Bob is a lackadaisical teenager. In conversation, his responses are very limited.

Bob answers 'Sure.' if you ask him a question.

He answers 'Whoa, chill out!' if you yell at him.

He answers 'Calm down, I know what I'm doing!' if you yell a question at him.

He says 'Fine. Be that way!' if you address him without actually saying anything.

He answers 'Whatever.' to anything else.

Getting Started

Make sure you have read the C page on the Exercism site. This covers the basic information on setting up the development environment expected by the exercises.

Passing the Tests

Get the first test compiling, linking and passing by following the three rules of test-driven development.

The included makefile can be used to create and run the tests using the test task.

make test

Create just the functions you need to satisfy any compiler errors and get the test to fail. Then write just enough code to get the test to pass. Once you've done that, move onto the next test.

As you progress through the tests, take the time to refactor your implementation for readability and expressiveness and then go on to the next test.

Try to use standard C99 facilities in preference to writing your own low-level algorithms or facilities by hand.

Source

Inspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. http://pine.fm/LearnToProgram/?Chapter=06

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

test_bob.c

#include "vendor/unity.h"
#include "../src/bob.h"

void setUp(void)
{
}

void tearDown(void)
{
}

void test_stating_something(void)
{
   TEST_ASSERT_EQUAL_STRING("Whatever.", hey_bob("Tom-ay-to, tom-aaaah-to.")
       );
}

void test_shouting(void)
{
   TEST_IGNORE();               // delete this line to run test
   TEST_ASSERT_EQUAL_STRING("Whoa, chill out!", hey_bob("WATCH OUT!")
       );
}

void test_shouting_gibberish(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Whoa, chill out!", hey_bob("FCECDFCAAB")
       );
}

void test_asking_a_question(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Sure.",
                            hey_bob
                            ("Does this cryogenic chamber make me look fat?")
       );
}

void test_asking_a_numeric_question(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Sure.", hey_bob("You are, what, like 15?")
       );
}

void test_asking_gibberish(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Sure.", hey_bob("fffbbcbeab?")
       );
}

void test_talking_forcefully(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Whatever.",
                            hey_bob("Let's go make out behind the gym!")
       );
}

void test_using_acronyms_in_regular_speech(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Whatever.",
                            hey_bob
                            ("It's OK if you don't want to go to the DMV.")
       );
}

void test_forceful_question(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Calm down, I know what I'm doing!",
                            hey_bob("WHAT THE HELL WERE YOU THINKING?")
       );
}

void test_shouting_numbers(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Whoa, chill out!", hey_bob("1, 2, 3 GO!")
       );
}

void test_only_numbers(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Whatever.", hey_bob("1, 2, 3")
       );
}

void test_question_with_only_numbers(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Sure.", hey_bob("4?")
       );
}

void test_shouting_with_special_characters(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Whoa, chill out!",
                            hey_bob
                            ("ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!")
       );
}

void test_shouting_with_no_exclamation_mark(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Whoa, chill out!", hey_bob("I HATE YOU")
       );
}

void test_statement_containing_question_mark(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Whatever.",
                            hey_bob("Ending with a ? means a question.")
       );
}

void test_non_letters_with_question(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Sure.", hey_bob(":) ?")
       );
}

void test_prattling_on(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Sure.",
                            hey_bob("Wait! Hang on.  Are you going to be OK?")
       );
}

void test_silence(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Fine. Be that way!", hey_bob("")
       );
}

void test_prolonged_silence(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Fine. Be that way!", hey_bob("   ")
       );
}

void test_alternate_silence(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Fine. Be that way!",
                            hey_bob("\t\t\t\t\t\t\t\t\t\t")
       );
}

void test_multiple_line_question(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Whatever.",
                            hey_bob
                            ("\nDoes this cryogenic chamber make me look fat?\nno")
       );
}

void test_starting_with_whitespace(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Whatever.", hey_bob("         hmmmmmmm...")
       );
}

void test_ending_with_whitespace(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Sure.",
                            hey_bob
                            ("Okay if like my  spacebar  quite a bit?   ")
       );
}

void test_other_whitespace(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Fine. Be that way!", hey_bob("\n\r \t")
       );
}

void test_non_question_ending_with_whitespace(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL_STRING("Whatever.",
                            hey_bob
                            ("This is a statement ending with whitespace      ")
       );
}

int main(void)
{
   UnityBegin("test/test_bob.c");

   RUN_TEST(test_stating_something);
   RUN_TEST(test_shouting);
   RUN_TEST(test_shouting_gibberish);
   RUN_TEST(test_asking_a_question);
   RUN_TEST(test_asking_a_numeric_question);
   RUN_TEST(test_asking_gibberish);
   RUN_TEST(test_talking_forcefully);
   RUN_TEST(test_using_acronyms_in_regular_speech);
   RUN_TEST(test_forceful_question);
   RUN_TEST(test_shouting_numbers);
   RUN_TEST(test_only_numbers);
   RUN_TEST(test_question_with_only_numbers);
   RUN_TEST(test_shouting_with_special_characters);
   RUN_TEST(test_shouting_with_no_exclamation_mark);
   RUN_TEST(test_statement_containing_question_mark);
   RUN_TEST(test_non_letters_with_question);
   RUN_TEST(test_prattling_on);
   RUN_TEST(test_silence);
   RUN_TEST(test_prolonged_silence);
   RUN_TEST(test_alternate_silence);
   RUN_TEST(test_multiple_line_question);
   RUN_TEST(test_starting_with_whitespace);
   RUN_TEST(test_ending_with_whitespace);
   RUN_TEST(test_other_whitespace);
   RUN_TEST(test_non_question_ending_with_whitespace);

   UnityEnd();
   return 0;
}

src/bob.c

#include "bob.h"
#include <ctype.h>
#include <stddef.h>

#define SURE 	"Sure."
#define WHOA 	"Whoa, chill out!"
#define FINE 	"Fine. Be that way!"
#define WTEVER 	"Whatever."

/**
 * hey_bob: parsing sentence only once, searching for
 * question | yelling | silence | something
 */
char *hey_bob(const char *sentence)
{
	if (sentence == NULL)
		return (char*) FINE;

	char *tmp = (char*) sentence;
	int alphas = 0;
	int uppers = 0;
	char lastch = ' ';

	while (*tmp) {
		if (!isspace(*tmp)) {
			lastch = *tmp;
			if (isalpha(*tmp)) {
				alphas++;
				if (isupper(*tmp))
					uppers++;
			}
		}
		tmp++;
	}

	if (alphas && alphas == uppers)
		return (char*) WHOA;
	if (lastch == '?')
		return (char*) SURE;
	if (lastch == ' ')
		return (char*) FINE;

	return (char*) WTEVER;
}

src/bob.h

#ifndef BOB_H
#define BOB_H

char *hey_bob(const char *sentence);

#endif

Community comments

Find this solution interesting? Ask the author a question to learn more.
Avatar of vlzware

Liked the idea from @tealdeer of counting alpha's and upper's so much, so here is my (less bloated) version based on that.

What can you learn from this solution?

A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.

Here are some questions to help you reflect on this solution and learn the most from it.

  • What compromises have been made?
  • Are there new concepts here that you could read more about to improve your understanding?