# HW05 評分標準 ## 5.1 Statistics :::spoiler hw0501.c(測資檔) ```c #include <stdio.h> #include <stdint.h> #include <stdbool.h> #include "./mystatistics.h" #define eps 1e-4 /*int32_t ans_statistics(int32_t *pData, int32_t size, double *pMean, double *pVariance, double *pStd) { if (pData == NULL || size <= 0 || pMean == NULL || pVariance == NULL || pStd == NULL) { return -1; // Invalid input } double sum = 0; for (int32_t i = 0; i < size; i++) { sum += pData[i]; } *pMean = sum / size; double varSum = 0; for (int32_t i = 0; i < size; i++) { varSum += (pData[i] - *pMean) * (pData[i] - *pMean); } *pVariance = varSum / size; *pStd = sqrt(*pVariance); return 0; // Success }*/ double ans_abs(double x) { return x < 0 ? -x : x; } bool compare(double a, double b) { if (ans_abs(a - b) < eps) { return true; } else { return false; } } int main() { int testcase, score; scanf("%d", &testcase); if(testcase == 1){ int32_t data[1] = {20231231}; double mean, variance, std; double amean, avariance, astd; statistics(data, 1, &mean, &variance, &std); //ans_statistics(data, 1, &amean, &avariance, &astd); score = 3 * compare(mean, 20231231.000000)+ 2 * compare(variance, 0.000000)+ 2 * compare(std, 0.000000); printf("%d\n", score); }else if(testcase == 2){ int32_t data[6] = {2023,12,31,2024,1,1}; double mean, variance, std; double amean, avariance, astd; statistics(data, 6, &mean, &variance, &std); //ans_statistics(data, 6, &amean, &avariance, &astd); score = 3 * compare(mean, 682.000000)+ 2 * compare(variance, 899911.333333)+ 2 * compare(std, 948.636565); printf("%d\n", score); }else if(testcase == 3){ int32_t data[6] = {2023,12,31,2024,1,1}; double mean, variance, std; int32_t ret_val = statistics(NULL, 6, &mean, &variance, &std); if(ret_val == -1){ printf("2\n"); }else{ printf("0\n"); } }else if(testcase == 4){ int32_t data[6] = {2023,12,31,2024,1,1}; double mean, variance, std; int32_t ret_val = statistics(data, -1, &mean, &variance, &std); if(ret_val == -1){ printf("1\n"); }else{ printf("0\n"); } }else if(testcase == 5){ int32_t data[6] = {2023,12,31,2024,1,1}; double mean, variance, std; int32_t ret_val = statistics(data, 6, NULL, &variance, &std); if(ret_val == -1){ printf("1\n"); }else{ printf("0\n"); } }else if(testcase == 6){ int32_t data[6] = {2023,12,31,2024,1,1}; double mean, variance, std; int32_t ret_val = statistics(data, 6, &mean, NULL, &std); if(ret_val == -1){ printf("1\n"); }else{ printf("0\n"); } }else if(testcase == 7){ int32_t data[6] = {2023,12,31,2024,1,1}; double mean, variance, std; int32_t ret_val = statistics(data, 6, &mean, &variance, NULL); if(ret_val == -1){ printf("1\n"); }else{ printf("0\n"); } } return 0; } ``` ``` ::: 1. 回饋顯示的是各筆測資拿到的分數 2. 各筆測資都是分開執行的(執行完一筆測資會結束程式),所以萬一某筆測資發生 Segmentation Fault,不會導致後面的測資像跨年煙火一樣爆掉。 ### 正常測資 14 pts 共有 2 筆: #### testcase 1 (7 pts): input: `{20231231}` answer: - mean: 20231231.000000 - variance: 0.000000 - std: 0.000000 #### testcase 2 (7 pts): input: `{2023,12,31,2024,1,1}` answer: - mean: 682.000000 - variance: 899911.333333 - std: 948.636565 #### 各測資分數分配 mean: 3 pts variance: 2 pts std: 2 pts ### 錯誤測資 6 pts 共有 5 筆 依照補充說明要求需回傳 -1 #### 各測資分數分配 testcase 3: 2 pts testcase 4~7: 1 pt ## 5.2 Gaussian Elimination 正解及測試資料檔案: https://drive.google.com/file/d/1XYaw5gdOwoX8qodwtzOT9XB8SNQNWUSa/view?usp=sharing 總共有 5 個測試資料,每個測試資料若回傳值 (0, 1, 2) 正確 2 分、px 正確 2 分。 若回傳值為 0, 2 則不檢查 px,若正確直接給 4 分。 測資 1, 2, 3, 4 均為 3x3,測資 5 則為 4x4。 會照順序測試,但若在執行該測試時遇到 error,則不會繼續進行測試,也不會得到後續的分數。 :::spoiler hw0502.c ```c= #include "myge.h" #include <stdio.h> #include <stdlib.h> #define NUM_TESTS 5 void print_score(int32_t score, int failed_tests[]){ printf("%d, WA: ", score); // printf("Failed Test Cases: "); for (int i = 0; i < NUM_TESTS; i++) { if (failed_tests[i] != 0) { printf("%d ", i + 1); } } printf("\n"); fflush(stdout); } int main() { int32_t score = 0; int32_t failed_tests[NUM_TESTS]; for(int i = 0; i < NUM_TESTS; i++){ failed_tests[i] = -1; } // Test 1~4: n = 3 int32_t n = 3; // Flatten the matrix into a single array int32_t A[4][9] = { { 1, 1, 1, 1, 2, 4, 1, 3, 9 }, { 1483,53,-1, 1616,74562,43, 563,-5231,79345}, { 1, 1, 1, 0, 0, 0, 1, 2, 3 }, { 1, 2, 3, 2, 4, 6, 3, 6, 9 } }; int32_t y[4][3] = { {6, 17, 34}, {1586, 150869, 228136}, {6, 0, 14}, {14, 28, 42}}; int32_t x_answer[4][3] = { {1, 2, 3}, {1, 2, 3}, {-1, -1, -1}, {-1, -1, -1} }; int32_t return_answer[4] = {1, 1, 0, 2}; for(int t = 0; t < 4; ++t){ int32_t *x = NULL; int32_t result = gaussian_elimination(n, A[t], y[t], &x); if(result != return_answer[t]){ printf("Test %d: Wrong return value\n", t+1); failed_tests[t] = 1; print_score(score, failed_tests); continue; } if(result == 0 || result == 2){ score += 4; printf("Test %d: All Correct\n", t+1); failed_tests[t] = 0; } else{ for(int i = 0; i < n; ++i){ if(x[i] != x_answer[t][i]){ failed_tests[t] = 2; break; } } if(failed_tests[t] == -1){ score += 4; printf("Test %d: All Correct\n", t+1); failed_tests[t] = 0; } else{ score += 2; printf("Test %d: Wrong answer\n", t+1); printf("Your answer: "); for(int i = 0; i < n; ++i){ printf("%d ", x[i]); } printf("\n"); printf("Correct answer: "); for(int i = 0; i < n; ++i){ printf("%d ", x_answer[t][i]); } printf("\n"); } } print_score(score, failed_tests); } n = 4; int32_t B[16]= { 1, 2, 3, 4, 5, 6, 7, 8, 9, -10, -11, 12, 13, -14, -15, -16 }; int32_t yB[4] = {30, 70, 4, -124}; int32_t xB_answer[4] = {1, 2, 3, 4}; int32_t Breturn_answer = {1}; int32_t *x = NULL; int32_t result = gaussian_elimination(n, B, yB, &x); if(result != Breturn_answer){ printf("Test 5: Wrong return value\n"); failed_tests[4] = 1; print_score(score, failed_tests); return 0; } if(result == 0 || result == 2){ score += 4; printf("Test 5: All Correct\n"); failed_tests[4] = 0; } else{ for(int i = 0; i < n; ++i){ if(x[i] != xB_answer[i]){ failed_tests[4] = 2; break; } } if(failed_tests[4] == -1){ score += 4; printf("Test 5: All Correct\n"); failed_tests[4] = 0; } else{ score += 2; printf("Test 5: Wrong answer\n"); printf("Your answer: "); for(int i = 0; i < n; ++i){ printf("%d ", x[i]); } printf("\n"); printf("Correct answer: "); for(int i = 0; i < n; ++i){ printf("%d ", xB_answer[i]); } printf("\n"); } } print_score(score, failed_tests); return 0; } ``` ::: ## 5.3 Sphere 這是評分程式,可以直接複製貼上編譯執行後會直接跑結果 :::spoiler hw0503.c ``` #include "mysphere.h" #include <stdio.h> #include <signal.h> #include <stdint.h> #include <stdlib.h> #include <math.h> #define CASE 10 double testcase[CASE][5] = { {10, 1, 0, 0, 1}, {10, 0, 1, 0, 2}, {10, 0, 0, 1, 3}, {10, 1, 1, 0, 4}, {10, 0, 1, 1, 5}, {10, 1, 0, 1, 6}, {0, 1, 1, 0, 0}, {1, 0, 0, 0, 0}, {1, 1, 0, 0, 3} }; double ans[CASE] = {311.02, 301.59, 285.88, 289.03, 274.89, 257.61, -1, -1, -1}; int32_t return_state[CASE] = {1, 1, 1, 1, 1, 1, -1, -1, 0}; int wrong[10] = {0}; int total_score = 0; void signal_handler(int signum) { wrong[9] = 1; printf("%d\n", total_score); printf("Wrong cases:"); for (int i = 0; i < CASE; i++) { if (wrong[i]) { printf("%d ", i + 1); } } exit(0); } int main() { for (int i = 0; i < CASE - 1; i++) { double area = 0; int32_t state = get_cap_area(testcase[i][0], testcase[i][1], testcase[i][2], testcase[i][3], testcase[i][4], &area); if (ans[i] == -1) { if (state == return_state[i]) { total_score += 2; } else { wrong[i] = 1; } } else { if (state == return_state[i] && fabs(area - ans[i]) < 0.01) { total_score += 2; } else { wrong[i] = 1; } } } signal(SIGSEGV, signal_handler); int32_t state = get_cap_area(3, 1, 1, 1, 0, NULL); if (state == -1) { total_score += 2; } else { wrong[9] = 1; } printf("%d\n", total_score); printf("Wrong cases:"); for (int i = 0; i < CASE; i++) { if (wrong[i]) { printf("%d ", i + 1); } } return 0; } ``` ::: ## 5.4 TLV 共有 10 筆測試,每筆 2 分,共 20 分。 各別超時時限 30 秒。 * 01-example: 題目的範例 * 02-add: 0x02 操作 * 03-mul: 0x03 操作 * 04-half: 0x04 操作 * 05-shift: 0x05 操作 * 06-concat: 0x06 操作 * 07-concat-right: 0x07 操作 * 08-clear: 0x08 操作 * 09-cancel: 0x0A 操作 * 10-unknown 未知操作(0x0B) 助教的 hw0504.c:https://github.com/JacobLinCool/cpta/blob/main/examples/2023-fall/hw0504/.build/mount/hw0504.c 詳細測試資料可參考:https://github.com/JacobLinCool/cpta/tree/main/examples/2023-fall/hw0504/.cases ## 5.5 TAS Editor - output.fm2 檔案比對完全一致,並且完成 1-1 通關 20 pt - output.fm2 檔案比對不完全一致情況下: - 完成 1-1 通關 15 pt - 有成功出去水管,後面爆掉 12 pt - 有成功進入水管,後面爆掉 10 pt - 成功開始遊戲,但沒進入水管 8 pt - 成功開啟模擬器但沒開始遊戲 5 pt - 僅輸出 output.fm2 空檔案 4 pt - no file,未輸出 output.fm2 檔案,或是其他未符合以上情況 0 pt 我會拿以下 Code 測試你的 function :::spoiler hw0505.c ```c #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include "tas.h" #include "decode.h" int main() { uint8_t *tas_src = NULL; size_t size = 0; button_set_frame(&tas_src, &size, 8, 180, 180); button_set_frame(&tas_src, &size, 130, 360, 1800); button_set_frame(&tas_src, &size, 1, 470, 500); button_set_frame(&tas_src, &size, 1, 515, 515); button_set_frame(&tas_src, &size, 1, 555, 590); button_set_frame(&tas_src, &size, 1, 610, 640); button_set_frame(&tas_src, &size, 1, 670, 710); button_set_frame(&tas_src, &size, 32, 730, 750); button_unset_frame(tas_src, size, 130, 710, 850); button_set_frame(&tas_src, &size, 131, 880, 910); button_set_frame(&tas_src, &size, 1, 950, 950); button_set_frame(&tas_src, &size, 131, 1260, 1320); button_unset_frame(tas_src, size, 1, 1260, 1280); button_set_frame(&tas_src, &size, 131, 1350, 1390); for (int i = 0; i < 30; i++) { button_set_frame(&tas_src, &size, 131, 1400 + i*10, 1400 + i*10 + 5); } extract_fm2_file(tas_src, size); if (size) free(tas_src); return 0; } ``` ::: ## 5.6 Bonus: What is Wrong? 我知道有些人會使用 GPT 解題,但他的回答不一定是正確的,還是要靠你的知識去判斷。 #### Reasonable effort (1 pt) - 有寫且有嘗試說明: 1 pt #### What is wrong with Bob’s code? (2 pts) - 有提到會被覆蓋或 `int16_t` -> `int32_t` 導致: 1 pt - 有清楚解釋會被覆蓋的原因(要包含由後往前被覆蓋): 2 pts #### What will happen if the size is five? (2 pts) - 有提到會超界或說會 abort: 1 pt - 有清楚解釋會超界的原因(不能只說超出記憶體區段,這個看 Segmentation Fault 就知道意思了): 2 pts **錯誤解釋** 並不是因為 `int32_t` 所以需要 2 倍的大小