Try   HackMD

(2022年) CS50 week2

其實之前就已經修完 CS50 了,不過因應 2022 年將課堂作業的系統
c9.io 換到 github codespace + vscode 整合
打算來重溫一下裡面的作業,並暖身一下 C 語言的手感

由於已經有許多前輩分享課程與作業的心得
加上官網教材的投影片、重點筆記、教學影片都非常完整
故不再做詳細的紀錄,專注在作業 (Lab, Problem sets) 上面

https://cs50.harvard.edu/x/2022/weeks/2/


Lab2: Scrabble

(點擊展開) 符合 style50 風格的程式碼
#include <ctype.h>
#include <cs50.h>
#include <stdio.h>
#include <string.h>

// Points assigned to each letter of the alphabet
int POINTS[] = {1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10};
/*              A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P,  Q, R, S, T, U, V, W, X, Y,  Z */

int compute_score(string word);

int main(void)
{
    // Get input words from both players
    string word1 = get_string("Player 1: ");
    string word2 = get_string("Player 2: ");

    // Score both words
    int score1 = compute_score(word1);
    int score2 = compute_score(word2);

    if (score1 > score2)
    {
        printf("Player 1 wins!\n");
    }
    else if (score1 < score2)
    {
        printf("Player 2 wins!\n");
    }
    else
    {
        printf("Tie!\n");
    }
}

int compute_score(string word)
{
    int sum = 0;
    for (int i = 0, n = strlen(word); i < n; i++)
    {
        // in ASCII, A ~ Z is 65 ~ 90, so only collect char code 65 ~ 90
        char c = toupper(word[i]);
        // -65 for get index (condition is 0 ~ 25)
        int c_index = (int) c - 65;
        // accumulate score in valid char
        if (c_index >= 0 && c_index < 26)
        {
            sum += POINTS[c_index];
        }
    }

    return sum;
}

(點擊展開) 個人覺得比較好讀的程式碼風格
#include <ctype.h>
#include <cs50.h>
#include <stdio.h>
#include <string.h>

// Points assigned to each letter of the alphabet
int POINTS[] = {1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10};
/*              A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P,  Q, R, S, T, U, V, W, X, Y,  Z */

int compute_score(string word);

int main(void)
{
    // Get input words from both players
    string word1 = get_string("Player 1: ");
    string word2 = get_string("Player 2: ");

    // Score both words
    int score1 = compute_score(word1);
    int score2 = compute_score(word2);

    if (score1 > score2)
        printf("Player 1 wins!\n");

    if (score1 < score2)
        printf("Player 2 wins!\n");

    if (score1 == score2)
        printf("Tie!\n");
}

int compute_score(string word)
{
    int sum = 0;
    for (int i = 0, n = strlen(word); i < n; i++) {
        // in ASCII, A ~ Z is 65 ~ 90, so only collect char code 65 ~ 90
        char c = toupper(word[i]);
        // -65 for get index (condition is 0 ~ 25)
        int c_index = (int) c - 65;
        // accumulate score in valid char
        if (c_index >= 0 && c_index < 26)
            sum += POINTS[c_index];
    }

    return sum;
}

執行

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

驗證

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →


作業: Readability

(點擊展開) 符合 style50 風格的程式碼
#include <ctype.h>
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

int main(void)
{
    string text = get_string("Text: ");
    int letter_count = 0;
    int word_count = strlen(text) > 0 ? 1 : 0;
    int sentence_count = 0;

    for (int i = 0, n = strlen(text); i < n; i++)
    {
        char c = toupper(text[i]);

        // count letters (in ASCII, A ~ Z is 65 ~ 90)
        if (c >= 65 && c <= 90)
        {
            letter_count += 1;
        }

        // count sentences (in '!', '.', '?)
        if (c == '!' || c == '.' || c == '?')
        {
            sentence_count += 1;
        }

        // count words (in ' ')
        if (c == ' ')
        {
            word_count += 1;
        }
    }

    // formula: Coleman-Liau index
    // index = 0.0588 * L - 0.296 * S - 15.8
    // L is the average number of letters per 100 words in the text
    // S is the average number of sentences per 100 words in the text
    float L = letter_count / (float) word_count * 100;
    float S = sentence_count / (float) word_count * 100 ;
    float CL_index = 0.0588 * L - 0.296 * S - 15.8;

    if (CL_index < 1)
    {
        printf("Before Grade 1\n");
    }
    else if (CL_index >= 16)
    {
        printf("Grade 16+\n");
    }
    else
    {
        printf("Grade %i\n", (int) round(CL_index));
    }
}

(點擊展開) 個人覺得比較好讀的程式碼風格
#include <ctype.h>
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

int main(void)
{
    string text = get_string("Text: ");
    int letter_count = 0;
    int word_count = strlen(text) > 0 ? 1 : 0;
    int sentence_count = 0;

    for (int i = 0, n = strlen(text); i < n; i++) {
        char c = toupper(text[i]);

        // count letters (in ASCII, A ~ Z is 65 ~ 90)
        if (c >= 65 && c <= 90)
            letter_count += 1;

        // count sentences (in '!', '.', '?)
        if (c == '!' || c == '.' || c == '?')
            sentence_count += 1;

        // count words (in ' ')
        if (c == ' ')
            word_count += 1;
    }

    // formula: Coleman-Liau index
    // index = 0.0588 * L - 0.296 * S - 15.8
    // L is the average number of letters per 100 words in the text
    // S is the average number of sentences per 100 words in the text
    float L = letter_count / (float) word_count * 100;
    float S = sentence_count / (float) word_count * 100 ;
    float CL_index = 0.0588 * L - 0.296 * S - 15.8;

    if (CL_index < 1)
        printf("Before Grade 1\n");

    else if (CL_index >= 16)
        printf("Grade 16+\n");

    else
        printf("Grade %i\n", (int) round(CL_index));
}

執行

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

驗證

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →


作業: Caesar

(點擊展開) 符合 style50 風格的程式碼
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, string argv[])
{
    // argc[1] must be present
    if (argc != 2)
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }

    // argc[1] all value must be digit (decimal number)
    string input_key = argv[1];
    for (int i = 0, n = strlen(input_key); i < n; i++)
    {
        if (isdigit(input_key[i]) == 0)
        {
            printf("Usage: ./caesar key\n");
            return 1;
        }
    }

    // just need get alphabet number (0 ~ 25)
    int key = atoi(argv[1]) % 26;
    string plaintext = get_string("plaintext:  ");
    string ciphertext = plaintext;

    // for lopp to convert char
    for (int i = 0, n = strlen(ciphertext); i < n; i++)
    {
        // covert alphabet only
        char c = ciphertext[i];
        if (isalpha(c))
        {
            // if isupper = 65, islower = 97
            int alpha_params = isupper(c) ? 65 : 97;
            c = (c + key - alpha_params) % 26 + alpha_params;

            // do convert alphabet
            ciphertext[i] = c;
        }
    }

    printf("Ciphertext: %s\n", ciphertext);
}

(點擊展開) 個人覺得比較好讀的程式碼風格
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, string argv[])
{
    // argc[1] must be present
    if (argc != 2) {
        printf("Usage: ./caesar key\n");
        return 1;
    }

    // argc[1] all value must be digit (decimal number)
    string input_key = argv[1];
    for (int i = 0, n = strlen(input_key); i < n; i++) {
        if (isdigit(input_key[i]) == 0) {
            printf("Usage: ./caesar key\n");
            return 1;
        }
    }

    // just need get alphabet number (0 ~ 25)
    int key = atoi(argv[1]) % 26;
    string plaintext = get_string("plaintext:  ");
    string ciphertext = plaintext;

    // for lopp to convert char
    for (int i = 0, n = strlen(ciphertext); i < n; i++) {
        // covert alphabet only
        char c = ciphertext[i];
        if (isalpha(c)) {
            // if isupper = 65, islower = 97
            int alpha_params = isupper(c) ? 65 : 97;
            c = (c + key - alpha_params) % 26 + alpha_params;

            // do convert alphabet
            ciphertext[i] = c;
        }
    }

    printf("Ciphertext: %s\n", ciphertext);
}

執行

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

驗證

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →


作業: Substitution

(點擊展開) 符合 style50 風格的程式碼
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

char indexOfalphabets(char c, string alphabets_string)
{
    int index = -1;
    for (int i = 0, n = strlen(alphabets_string); i < n; i++)
    {
        if (toupper(alphabets_string[i]) == toupper(c))
        {
            index = i;
        }
    }

    return index;
}

int main(int argc, string argv[])
{
    // argc[1] must be present
    if (argc != 2)
    {
        printf("Usage: ./substitution key\n");
        return 1;
    }

    // count length of chars
    string input_string = argv[1];
    int input_char_count = 0;
    for (int i = 0, n = strlen(input_string); i < n; i ++)
    {
        char c = input_string[i];
        int index = indexOfalphabets(c, input_string);

        if (isalpha(c) && index == i)
        {
            input_char_count += 1;
        }
    }

    // argc[1] must be 26 length of chars
    if (input_char_count != 26)
    {
        printf("Key must contain 26 characters.");
        return 1;
    }

    // conver input params to array
    string alphabets_string = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    int input_char_arr[26];
    for (int i = 0; i < 26; i++)
    {
        char c = toupper(input_string[i]);
        int diff = c - alphabets_string[i];
        input_char_arr[i] = diff;
    }

    string plaintext = get_string("plaintext:  ");
    string ciphertext = plaintext;

    // for lopp to convert char
    for (int i = 0, n = strlen(ciphertext); i < n; i++)
    {
        char c = ciphertext[i];
        int index_of_alphabets = indexOfalphabets(c, alphabets_string);
        int chiper_params = input_char_arr[index_of_alphabets];

        // covert alphabet only
        if (isalpha(c))
        {
            char cipher_char = c + chiper_params;

            // do convert alphabet
            ciphertext[i] = cipher_char;
        }
    }

    printf("ciphertext: %s\n", ciphertext);
}

(點擊展開) 個人覺得比較好讀的程式碼風格
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

char indexOfalphabets(char c, string alphabets_string)
{
    int index = -1;
    for (int i = 0, n = strlen(alphabets_string); i < n; i++) {
        if (toupper(alphabets_string[i]) == toupper(c))
            index = i;
    }

    return index;
}

int main(int argc, string argv[])
{
    // argc[1] must be present
    if (argc != 2) {
        printf("Usage: ./substitution key\n");
        return 1;
    }

    // count length of chars
    string input_string = argv[1];
    int input_char_count = 0;
    for (int i = 0, n = strlen(input_string); i < n; i ++) {
        char c = input_string[i];
        int index = indexOfalphabets(c, input_string);

        if (isalpha(c) && index == i)
            input_char_count += 1;
    }

    // argc[1] must be 26 length of chars
    if (input_char_count != 26) {
        printf("Key must contain 26 characters.");
        return 1;
    }

    // conver input params to array
    string alphabets_string = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    int input_char_arr[26];
    for (int i = 0; i < 26; i++) {
        char c = toupper(input_string[i]);
        int diff = c - alphabets_string[i];
        input_char_arr[i] = diff;
    }

    string plaintext = get_string("plaintext:  ");
    string ciphertext = plaintext;

    // for lopp to convert char
    for (int i = 0, n = strlen(ciphertext); i < n; i++)
    {
        char c = ciphertext[i];
        int index_of_alphabets = indexOfalphabets(c, alphabets_string);
        int chiper_params = input_char_arr[index_of_alphabets];

        // covert alphabet only
        if (isalpha(c)) {
            char cipher_char = c + chiper_params;
            // do convert alphabet
            ciphertext[i] = cipher_char;
        }
    }

    printf("ciphertext: %s\n", ciphertext);
}

執行

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

驗證

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →