HW05 評分標準

5.1 Statistics

hw0501.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,則不會繼續進行測試,也不會得到後續的分數。

hw0502.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

這是評分程式,可以直接複製貼上編譯執行後會直接跑結果

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

hw0505.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 倍的大小