CS50 Problem Set 2 — Readability & Substitution

Yan
3 min readOct 11, 2021

Readability

Here is the problem description — how to know which grade level you need to comprehend some texts?

Photo by Thought Catalog on Unsplash

Breakdown of the problem

Basically, when given text, we need to know how many letters, words and sentences in it and use a formula to get the level. To make it more clear, I use several functions here.

int main(void)
{
string text = get_string("Text: ");
int num_letter = count_letters(text);
int num_word = count_words(text);
int num_sentence = count_sentences(text);
grade_check(num_letter, num_sentence, num_word);
}
  • count_letters
int count_letters(string text)
{
int num = 0;
// it's comma between i and n
for (int i = 0, n = strlen(text); i < n; i++)
// single quote!
{
if ((text[i] >= 'a' && text[i] <= 'z') || (text[i] >= 'A' && text[i] <= 'Z'))
{
num++;
}
}
return num;
}
  • count_words
int count_words(string text)
{
int num = 0;
for (int i = 0, n = strlen(text); i < n; i++)
{
if (text[i] == ' ')
{
num++;
}
}
// printf("%i", num+1);
return num + 1;
}
  • count_sentences
int count_sentences(string text)
{
int num = 0;
for (int i = 0, n = strlen(text); i < n;i++)
{
if (text[i] == '.' || text[i] == '!' || text[i] == '?')
{
num++;
}
}
// printf("%i", num);
return num;
}
  • grade check
void grade_check(int l, int s, int w)
{
float L = l * 100.0 / w;
float S = s * 100.0 / w;
int index = round(0.0588 * L - 0.296 * S-15.8);
if (index < 1)
{
printf("Before Grade 1\n");
}
else if (index >= 16)
{
printf("Grade 16+\n");
}
else
{
printf("Grade %i\n", index);
}
}

Substitution

Here is the problem description — the basic idea is that to write a program that implements a substitution cipher. It is not that easy as it sounds because there are quite a lot of conditions to be met.

In this program, we will practice the command-line argument.

Photo by Alex Motoc on Unsplash

Breakdown of the problem

Simply put, we need to get the key, validate it and then encipher!

int main (int argc, string argv[])
{
if (argc != 2)
{
printf("Key must contain 26 characters!");
return 1;
}
else{
string key = argv[1];
// validate whether a key meets the criteria--26 unique letters if (validate_len(key) && validate_alpha(key) && validate_unique(key))
{
encipher(key);
return 0;
}
else
{
printf("Key must contain 26 characters.\n");
return 1;
}
}
}

I break down the validation process into three steps.

  • validate the length
bool validate_len(string key)
{
if (strlen(key) == 26)
{
return true;
}
else
{
return false;
}
}
  • validate whether it is alphabetic
bool validate_alpha(string key)
{
for (int i =0; i<26; i++)
{
if (isalpha(key[i]) == false)
{
return false;
}
}
return true;
}
  • validate whether it consists of 26 unique letters — this one took me much time as I want to validate it in a simple way…but still two loops.
bool validate_unique(string key)
{
for (int i = 0; i < 26; i++)
{
for (int j = i + 1; j < 26; j++)
{
if (key[i] == key[j] || key[i] == toupper(key[j]) || key[i] == tolower(key[j]))
{
return false;
}
}
}
return true;
}

If they are all TRUE, then we can encipher it!

void encipher(string key)
{
string plain = get_string("plaintext: ");
printf("ciphertext: ");
string ab = "abcdefghijklmnopqrstuvwxyz";
for (int i = 0, n = strlen(plain); i < n; i++)
{
if (isalpha(plain[i])== false)
{
printf("%c",plain[i]);
}
else
{
for (int j = 0; j < 26; j++)
{
if (plain[i] == ab[j])
{
printf("%c",tolower(key[j]));
}
else if (plain[i] == toupper(ab[j]))
{
printf("%c", toupper(key[j]));
}
}
}
}
printf("\n");
}

I will see how this can be improved and update here later!

--

--