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