--- tags: CS50 --- # (2022年) CS50 week2 其實之前就已經修完 CS50 了,不過因應 2022 年將課堂作業的系統 從 c9.io 換到 github codespace + vscode 整合 打算來重溫一下裡面的作業,並暖身一下 C 語言的手感 由於已經有許多前輩分享課程與作業的心得 加上官網教材的投影片、重點筆記、教學影片都非常完整 故不再做詳細的紀錄,專注在作業 (Lab, Problem sets) 上面 https://cs50.harvard.edu/x/2022/weeks/2/ --- ### Lab2: [Scrabble](https://cs50.harvard.edu/x/2022/labs/2/) :::spoiler (點擊展開) 符合 `style50` 風格的程式碼 ```c #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; } ``` ::: -- :::spoiler (點擊展開) 個人覺得比較好讀的程式碼風格 ```c #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; } ``` ::: -- 執行 ![](https://hackmd.io/_uploads/rk63q9jQs.png) 驗證 ![](https://hackmd.io/_uploads/BJ3nucjmi.png) --- ### 作業: [Readability](https://cs50.harvard.edu/x/2022/psets/2/readability/) :::spoiler (點擊展開) 符合 `style50` 風格的程式碼 ```c #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)); } } ``` ::: -- :::spoiler (點擊展開) 個人覺得比較好讀的程式碼風格 ```c #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)); } ``` ::: -- 執行 ![](https://hackmd.io/_uploads/BkZyA9sXi.png) 驗證 ![](https://hackmd.io/_uploads/S1Uipcs7o.png) --- ### 作業: [Caesar](https://cs50.harvard.edu/x/2022/psets/2/caesar/) :::spoiler (點擊展開) 符合 `style50` 風格的程式碼 ```c #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); } ``` ::: -- :::spoiler (點擊展開) 個人覺得比較好讀的程式碼風格 ```c #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); } ``` ::: -- 執行 ![](https://hackmd.io/_uploads/HkLERjsmj.png) 驗證 ![](https://hackmd.io/_uploads/BkMyCssmj.png) --- ### 作業: [Substitution](https://cs50.harvard.edu/x/2022/psets/2/substitution/) :::spoiler (點擊展開) 符合 `style50` 風格的程式碼 ```c #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); } ``` ::: -- :::spoiler (點擊展開) 個人覺得比較好讀的程式碼風格 ```c #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); } ``` ::: -- 執行 ![](https://hackmd.io/_uploads/BJWmH2sXi.png) 驗證 ![](https://hackmd.io/_uploads/ryXeHnjmo.png)