Try   HackMD

FINAL 評分標準

1. Fraction Arithmetic

正解及測試資料檔案:
https://drive.google.com/file/d/1GslLrVxKkt4KUWCsx6fP15JVgGoCNLgj/view?usp=sharing

總共有 20 個測試資料,加減乘除照順序測試,每個函式各有 5 個。

若在執行該測試時遇到 error,則不會繼續進行測試,也不會得到後續的分數。

fin01.c
#include <stdio.h> #include "frac.h" #define NUM_TESTS 20 void print_score(int32_t score, int failed_tests[]){ printf("%d, WA: ", score); 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 x, y; int failed_tests[NUM_TESTS] = {}; // Array to track failed tests for(int i = 0; i < NUM_TESTS; i++){ failed_tests[i] = -1; } int add_testx1[5] = {1, 0, 3, 87, 2147483647-87}; int add_testy1[5] = {2, 1, 4, 1073741819, 100}; int add_testx2[5] = {1, 1, -5, 2147482164, -100}; int add_testy2[5] = {3, 3, 6, 2147483638, 2147483647-56}; int add_ansx[5] = {5, 1, -1, 1073741169, 0}; int add_ansy[5] = {6, 3, 12, 1073741819, 0}; int add_ansisvalid[5] = {0, 0, 0, 0, -1}; for(int i = 0; i < 5; i++){ int isvalid = frac_add(&x, &y, add_testx1[i], add_testy1[i], add_testx2[i], add_testy2[i]); if(isvalid != add_ansisvalid[i]){ failed_tests[i] = 1; continue; } if(isvalid == -1 || (x == add_ansx[i] && y == add_ansy[i])){ score++; failed_tests[i] = 0; } else{ failed_tests[i] = 1; } } int del_testx1[5] = {3, 0, -1, 321, 1}; int del_testy1[5] = {4, 1, 2, 73, 0}; int del_testx2[5] = {1, 1, -1, 36482, 1}; int del_testy2[5] = {2, 3, 4, 675835, 2}; int del_ansx[5] = {1, -1, -1, 12604697, 0}; int del_ansy[5] = {4, 3, 4, 2902115, 0}; int del_ansisvalid[5] = {0, 0, 0, 0, -1}; for(int i = 0; i < 5; i++){ int isvalid = frac_del(&x, &y, del_testx1[i], del_testy1[i], del_testx2[i], del_testy2[i]); if(isvalid != del_ansisvalid[i]){ failed_tests[i+5] = 1; continue; } if(isvalid == -1 || (x == del_ansx[i] && y == del_ansy[i])){ score++; failed_tests[i+5] = 0; } else{ failed_tests[i+5] = 1; } } int mul_testx1[5] = {1, 0, 2147483647-1483, 1073741824, 1}; int mul_testy1[5] = {2, 1, (2147483647-9)/2, 1, 0}; int mul_testx2[5] = {2, 1, 2147483647-9, 4, 1}; int mul_testy2[5] = {3, 3, 2147483647-1483, 1, 2}; int mul_ansx[5] = {1, 0, 2, -1, -1}; int mul_ansy[5] = {3, 1, 1, 0, -1}; int mul_ansisvalid[5] = {0, 0, 0, -1, -1}; for(int i = 0; i < 5; i++){ int isvalid = frac_mul(&x, &y, mul_testx1[i], mul_testy1[i], mul_testx2[i], mul_testy2[i]); if(isvalid != mul_ansisvalid[i]){ failed_tests[i+10] = 1; continue; } if(isvalid == -1 || (x == mul_ansx[i] && y == mul_ansy[i])){ score++; failed_tests[i+10] = 0; } else{ failed_tests[i+10] = 1; } } int div_testx1[5] = {1, 0, -1, 1, 2147483647}; int div_testy1[5] = {2, 1, 2, 2, 1}; int div_testx2[5] = {1, 1, 1, 0, 1}; int div_testy2[5] = {3, 3, 4, 1, 2147483647}; int div_ansx[5] = {3, 0, -2, 0, 0}; int div_ansy[5] = {2, 1, 1, 0, 0}; int div_ansisvalid[5] = {0, 0, 0, -1, -1}; for(int i = 0; i < 5; i++){ int isvalid = frac_div(&x, &y, div_testx1[i], div_testy1[i], div_testx2[i], div_testy2[i]); if(isvalid != div_ansisvalid[i]){ failed_tests[i+15] = 1; continue; } if(isvalid == -1 || (x == div_ansx[i] && y == div_ansy[i])){ score++; failed_tests[i+15] = 0; } else{ failed_tests[i+15] = 1; } } print_score(score, failed_tests); return 0; }

2. Minesweeper

Case1~Case6 1 分
Case7~Case8 3 分
Case9~Case11 1 分

fin02.c
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "mine.h"

int main() {

    int32_t board[16][30] = {0};
    for (int i = 0; i < 16; i++) {
        for (int j = 0; j < 30; j++) {
            scanf("%d", &board[i][j]);
        }
    }

    int row, col;
    while(scanf("%d %d", &row, &col) != EOF) {
        int state = hit(board, row, col);
        printf("%d\n", state);
        for (int i = 0; i < 16; i++) {
            for (int j = 0; j < 30; j++) {
                printf("%d ", board[i][j]);
            }
            printf("\n");
        }
    }

    return 0;
}

testcase

3. Firewall

  • Case 1 (5pt)
    • 可以設置 set_rule, unset_rule function,並且 call filter function 之後有根據 function pointer 去 call rule function
  • Case 2 (5pt)
    • 加上一條規則:
      • If source ID is 1, set destination ID to 5
  • Case 3 (5pt)
    • 加上兩條規則:
        1. If source ID is 1, set destination ID to 62.
        1. If source ID is 2, set source ID to 256.
  • Case 4 (5pt)
    • 加上下列規則:
        1. If source ID is 1, set destination ID to 5.
        1. If source ID is 2, set source ID to 7.
        1. If size is 2, duplicate data.
        1. If source ID is 7 and destination ID is 3, Drop the packet.

測試之 Code 如下(以Case 4為例),input packet 內容每個 Case 皆相同,想手動測其他 Case 的話改 rule function 跟 set_rule function 就好

fin03.c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#include "firewall.h"

typedef int32_t (*RuleFunctionPointer)(const uint8_t *p_input_packet, const int32_t input_size, uint8_t **pp_output_packet, int32_t *p_output_size);

// Rule 1: If source ID is 1, set destination ID to 5.
int32_t rule1(const uint8_t *p_input_packet, const int32_t input_size, uint8_t **pp_output_packet, int32_t *p_output_size)
{
    if (p_input_packet == NULL || input_size <= 0)
    {
        return -1;
    }

    *pp_output_packet = (uint8_t *)malloc(input_size * sizeof(uint8_t));
    memcpy(*pp_output_packet, p_input_packet, input_size * sizeof(uint8_t));
    
    uint32_t source_id = ((uint32_t *)p_input_packet)[0];
    printf("rule1: id: %d\n", source_id);
    if (source_id == 1)
    {
        ((uint32_t *)(*pp_output_packet))[1] = 5; // change destination ID to 5.   
    }

    *p_output_size = input_size;
    return 0;
}

// Rule 2: If source ID is 2, set source ID to 7.
int32_t rule2(const uint8_t *p_input_packet, const int32_t input_size, uint8_t **pp_output_packet, int32_t *p_output_size) 
{
    if (p_input_packet == NULL || input_size <= 0)
    {
        return -1;
    }

    *pp_output_packet = (uint8_t *)malloc(input_size * sizeof(uint8_t));
    memcpy(*pp_output_packet, p_input_packet, input_size * sizeof(uint8_t));
    
    uint32_t source_id = ((uint32_t *)p_input_packet)[0];
    printf("rule2: id: %d\n", source_id);
    if (source_id == 2)
    {
        ((uint32_t *)(*pp_output_packet))[0] = 7; // change destination ID to 7.   
    }

    *p_output_size = input_size;
    return 0;
}

// // Rule 3: If size is 2, duplicate data.
int32_t rule3(const uint8_t *p_input_packet, const int32_t input_size, uint8_t **pp_output_packet, int32_t *p_output_size) 
{
    if (p_input_packet == NULL || input_size <= 0)
    {
        return -1;
    }

    uint16_t packet_size = ((uint16_t *)p_input_packet)[4];
    printf("rule3: size: %d\n", packet_size);
    if (packet_size == 2) 
    {
        *pp_output_packet = (uint8_t*)malloc((input_size + packet_size) * sizeof(uint8_t));
        memcpy(*pp_output_packet, p_input_packet, input_size * sizeof(uint8_t));
        memcpy(*pp_output_packet + input_size, p_input_packet + input_size - packet_size, packet_size * sizeof(uint8_t)); // duplicate data
        *p_output_size = input_size + packet_size;
    }
    else
    {
        *pp_output_packet = (uint8_t *)malloc(input_size * sizeof(uint8_t));
        memcpy(*pp_output_packet, p_input_packet, input_size * sizeof(uint8_t));
        *p_output_size = input_size;
    }

    return 0;
}

// Rule 4: If source ID is 7 and destination ID is 3, Drop the packet.
int32_t rule4(const uint8_t *p_input_packet, const int32_t input_size, uint8_t **pp_output_packet, int32_t *p_output_size) 
{
    if (p_input_packet == NULL || input_size <= 0)
    {
        return -1;
    }

    uint32_t source_id = ((uint32_t *)p_input_packet)[0];
    uint32_t destination_id = ((uint32_t *)p_input_packet)[1];

    printf("rule4: s_id: %d, d_id: %d\n", source_id, destination_id);
    if (source_id == 7 && destination_id == 3)
    {
        return 1; // drop signal
    }

    *pp_output_packet = (uint8_t *)malloc(input_size * sizeof(uint8_t));
    memcpy(*pp_output_packet, p_input_packet, input_size * sizeof(uint8_t));
    *p_output_size = input_size;
    return 0;
}

int main()
{
    uint8_t array[] = { 0x01, 0x00, 0x00, 0x00, // Packet 1 -> Source ID: 1
                        0x02, 0x00, 0x00, 0x00, // Destination ID: 2
                        0x03, 0x00,             // Size
                        0x01, 0x02, 0x03,       // Data
                        0x01, 0x00, 0x00, 0x00, // Packet 2 -> Source ID: 1
                        0x03, 0x00, 0x00, 0x00, // Destination ID: 3
                        0x02, 0x00,             // Size
                        0xEE, 0xFF,             // Data
                        0x02, 0x00, 0x00, 0x00, // Packet 3 -> Source ID: 2
                        0x03, 0x00, 0x00, 0x00, // Destination ID: 3
                        0x04, 0x00,             // Size
                        0x00, 0x00, 0x01, 0x02  // Data
    };

    size_t array_len = sizeof(array)/sizeof(array[0]);
    
    uint8_t *inputPacket = malloc(array_len * sizeof(uint8_t));
    memcpy(inputPacket, array, array_len);
    int32_t inputSize = array_len; 
    uint8_t *outputPacket = NULL;
    int32_t outputSize = 0;

    printf("rule1: %d\n", set_rule(0, rule1));
    printf("rule2: %d\n", set_rule(10, rule2));
    printf("rule3: %d\n", set_rule(20, rule3));
    printf("rule4: %d\n", set_rule(99, rule4));
    printf("filter: %d\n", filter(inputPacket, inputSize, &outputPacket, &outputSize));
    
    uint8_t ans_array[] = { 0x01, 0x00, 0x00, 0x00, // Packet 1 -> Source ID: 1
                            0x05, 0x00, 0x00, 0x00, // Destination ID: 5
                            0x03, 0x00,             // Size
                            0x01, 0x02, 0x03,       // Data
                            0x01, 0x00, 0x00, 0x00, // Packet 2 -> Source ID: 1
                            0x05, 0x00, 0x00, 0x00, // Destination ID: 5
                            0x04, 0x00,             // Size
                            0xEE, 0xFF, 0xEE, 0xFF  // Data
    };

    printf("input_size: %d, output_size: %d\n", inputSize, outputSize);
    for (int i = 0; i < inputSize; i++)
    {
        printf("%d, ", inputPacket[i]);
    }
    printf("\n");
    for (int i = 0; i < outputSize; i++)
    {
        printf("%d, ", outputPacket[i]);
    }
    printf("\n");
    for (int i = 0; i < sizeof(ans_array)/sizeof(ans_array[0]); i++)
    {
        printf("%d, ", ans_array[i]);
    }

    printf("\n=============end===========\n");
    return 0;
}

4. The Tank War Game

助教我很認真的玩了你們寫的遊戲,我花了半天在改這題

測試大小: 20, 40
如果有 Segmentation Fault 或任何不能動的情況我都會多跑幾次你的程式。不會扣分。

詳細回饋請見 Google 表單發還的回饋。

沒有印牆壁 -1
炮口指示標記不會轉動: -3
只有一個電腦玩家會動: -2

如果炮口不會轉動,但有射擊: 1 pt

只動一步就死了: 後面分數也拿不到