# MID 參考解答 ## mid01 :::spoiler mid01.c ```clike= #include <stdio.h> #include <stdint.h> #define SECONDS_IN_A_MINUTE 60 #define MINUTES_IN_AN_HOUR 60 #define HOURS_IN_A_DAY 24 #define DAYS_IN_A_COMMON_YEAR 365 #define DAYS_IN_A_LEAP_YEAR 366 int isLeapYear(int year) { if (year % 400 == 0) return 1; if (year % 100 == 0) return 0; if (year % 4 == 0) return 1; return 0; } uint64_t convertToSeconds(int year, int month, int day, int hour, int minute, int second) { uint64_t totalSeconds = 0; int monthDays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if (isLeapYear(year)) { monthDays[1] = 29; // February has 29 days in a leap year } for (int y = 1970; y < year; y++) { totalSeconds += (isLeapYear(y) ? DAYS_IN_A_LEAP_YEAR : DAYS_IN_A_COMMON_YEAR) * HOURS_IN_A_DAY * MINUTES_IN_AN_HOUR * SECONDS_IN_A_MINUTE; } for (int m = 0; m < month - 1; m++) { totalSeconds += monthDays[m] * HOURS_IN_A_DAY * MINUTES_IN_AN_HOUR * SECONDS_IN_A_MINUTE; } totalSeconds += (day - 1) * HOURS_IN_A_DAY * MINUTES_IN_AN_HOUR * SECONDS_IN_A_MINUTE; totalSeconds += hour * MINUTES_IN_AN_HOUR * SECONDS_IN_A_MINUTE; totalSeconds += minute * SECONDS_IN_A_MINUTE; totalSeconds += second; return totalSeconds; } int main() { int startY, startM, startD, startH, startMi, startS; int endY, endM, endD, endH, endMi, endS; printf("Start Time: "); scanf("%d-%d-%d %d:%d:%d", &startY, &startM, &startD, &startH, &startMi, &startS); printf("End Time: "); scanf("%d-%d-%d %d:%d:%d", &endY, &endM, &endD, &endH, &endMi, &endS); uint64_t startSeconds = convertToSeconds(startY, startM, startD, startH, startMi, startS); uint64_t endSeconds = convertToSeconds(endY, endM, endD, endH, endMi, endS); uint64_t duration = endSeconds - startSeconds; printf("Duration: %lu sec\n", duration); return 0; } ``` ::: ## mid02 :::spoiler mid02.c ```c= #include <stdio.h> #include <stdint.h> #include <stdbool.h> int64_t n = 0, len = 0; void print_space(int32_t blockCount){ for(int32_t i = 0; i < blockCount*(len*2+1); i++){ printf(" "); } } void print_line(int32_t blockCount){ for(int32_t i = 0; i < blockCount*(len*2+1); i++){ if(i % (len*2+1) == 0){ printf("+"); }else{ printf("-"); } } printf("+"); } void print_color(int32_t totalBlock){ int32_t blockCnt = 0; for(int32_t i = 0; i < totalBlock*(len*2+1); i++){ if(i % (len*2+1) == 0){ printf("\033[0m"); printf("|"); int32_t color = 0; if(blockCnt <= totalBlock/2){ color = blockCnt % 3; }else{ color = (totalBlock-1 - blockCnt) % 3; } blockCnt ++; if(color == 0){ printf("\033[41m"); }else if(color == 1){ printf("\033[42m"); }else{ printf("\033[44m"); } }else{ printf(" "); } } printf("\033[0m"); printf("|"); } int main(){ printf("Please enter n: "); scanf("%ld", &n); printf("Please enter the edge length: "); scanf("%ld", &len); if(n <= 0 || len <= 0){ printf("Error: Invalid input\n"); return 0; } int64_t max_i = (1 + len) * (2*n-1); for(int32_t i = 0; i <= max_i ; i ++){ bool isLowerTriangle = (i >= (1 + len) * n); int32_t spaceBlock = (n-1)-((i-isLowerTriangle)/(len+1)); if(spaceBlock < 0) spaceBlock = -spaceBlock; int32_t colorBlock = (2*n-1) - spaceBlock*2; print_space(spaceBlock); if(i % (len+1) == 0){ print_line(colorBlock); }else{ print_color(colorBlock); } printf("\n"); } } ``` ::: ## mid03 ![](https://hackmd.io/_uploads/ry6crlAfa.png) test testcase by `./mid03 < 1.in > your1.out` :::spoiler mid03.c ```c= #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <stdbool.h> int8_t digit; int64_t state(int8_t event) { return (1<<(event - 1)); } bool r1_success = false; int64_t r1_state = 0b00000; //s5, s4, s3, s2, s1, void rule1() { int64_t r1_new_state = 0b000000; if (digit == 1) { r1_new_state |= state(2); } if (digit == 3) { r1_new_state |= state(1); } if (r1_state & state(1)) { if (digit == 1 || digit == 2) { r1_new_state |= state(2); } else if (digit == 3) { r1_new_state |= state(1); } } if (r1_state & state(2)) { if (digit == 6) { r1_new_state |= state(3); } else { r1_new_state |= state(2); } } if (r1_state & state(3)) { if (digit == 5) { r1_new_state |= state(4); } else if (digit == 6) { r1_new_state |= state(3); } else { r1_new_state |= state(2); } } if (r1_state & state(4)) { if (digit == 9) { r1_success = true; } else if (digit == 7) { r1_new_state |= state(5); } else { r1_new_state |= state(4); } } if (r1_state & state(5)) { if (digit == 8 || digit == 9) { r1_success = true; } else if (digit == 7) { } else { r1_new_state |= state(4); } } r1_state = r1_new_state; } bool r2_success = false; int64_t r2_state = 0b000; //s3, s2, s1 void rule2() { int64_t r2_new_state = 0b0000; if (digit == 7) { r2_new_state |= state(1); } if (r2_state & state(1)) { if (digit == 7) { r2_new_state |= state(2); } else if (digit == 5) { r2_new_state |= state(3); } else if (digit == 3) { r2_success = true; } else { r2_new_state |= state(1); } } if (r2_state & state(2)) { if (digit == 5) { r2_new_state |= state(3); } else if (digit == 3) { r2_success = true; } else if (digit != 7) { r2_new_state |= state(2); } } if (r2_state & state(3)) { if (digit == 3) { r2_success = true; } else if (digit != 5) { r2_new_state |= state(3); } } r2_state = r2_new_state; } bool r3_success = false; int64_t r3_state = 0b0000; //s4, s3, s2, s1 void rule3() { int64_t r3_new_state = 0b0000; if (digit == 4) { r3_new_state |= state(1); } if (r3_state & state(1)) { if (digit == 6) { r3_new_state |= state(2); } else { r3_new_state |= state(1); } } if (r3_state & state(2)) { if (digit == 6) { r3_new_state |= state(3); } else { r3_new_state |= state(1); } } if (r3_state & state(3)) { if (digit == 6) { r3_new_state |= state(4); } else { r3_new_state |= state(1); } } if (r3_state & state(4)) { if (digit == 8) { r3_success = true; } else { r3_new_state |= state(4); } } r3_state = r3_new_state; } int main() { while(1) { printf("Please input the digit: "); scanf("%hhd", &digit); if(digit == -1) break; rule1(); rule2(); rule3(); } if (r1_success && r2_success && r3_success) { printf("SUCCESS!\n"); } else { if (!r1_success) { printf("Rule 1 "); } if (!r2_success) { printf("Rule 2 "); } if (!r3_success) { printf("Rule 3 "); } printf("not follow!\n"); } return 0; } ``` ::: ## mid04 :::spoiler parity.h ```c #pragma once #include <stdint.h> uint64_t parity_2d( int32_t , int32_t , int32_t , int32_t , int32_t ); ``` ::: :::spoiler parity.c ```c #include <stdint.h> #include <stdbool.h> #include <stdio.h> uint64_t parity_2d(int32_t n1, int32_t n2, int32_t n3, int32_t n4, int32_t n5) { // generate parity table by 5 input numbers bool parity_table[6][33] = {0}; int32_t num_list[6] = {n1, n2, n3, n4, n5}; for (int i = 0; i < 6; i++) { for (int bit = 31; bit >= 0; bit--) { parity_table[i][31-bit] = (num_list[i] & (1 << bit)) ? 1 : 0; } } // count 1's by row for (int i = 0; i < 5; i++) { int count = 0; for (int j = 0; j < 32; j++) { count = parity_table[i][j] ? count + 1 : count; } parity_table[i][32] = (count % 2) ? 0 : 1; } // count 1's by colume for (int i = 0; i < 33; i++) { int count = 0; for (int j = 0; j < 5; j++) { count = parity_table[j][i] ? count + 1 : count; } parity_table[5][i] = (count % 2) ? 0 : 1; } // print parity_table // // for (size_t i = 0; i < 6; i++) // { // for (size_t j = 0; j < 33; j++) // { // printf("%u ", parity_table[i][j]); // } // printf("\n"); // } // caculate parity number uint64_t parity_num = 0; for (int i = 0; i < 33; i++) { parity_num |= ((uint64_t)(parity_table[5][i]) << (32 - i)); } return parity_num; } ``` ::: ## mid05 :::spoiler `weight.c` ```c= #include "weight.h" static int64_t girl_weight = -1; static int64_t boy_weight = -1; void setup_girl_weight(uint32_t kg) { girl_weight = kg; return; } void setup_boy_weight(uint32_t kg) { boy_weight = kg; return; } double _calculate_weight(int32_t x, int32_t y); int64_t afford_weight(int32_t x, int32_t y) { // not initialized, error if (girl_weight == -1 || boy_weight == -1) { return -1; } // negative index, error if (x < 0 || y < 0) { return -1; } // out of range, error if (y > x) { return -1; } int64_t self_weight = x % 2 ? boy_weight : girl_weight; return _calculate_weight(x, y) - self_weight; } // helper function to calculate the weight of the member at (x,y) // including the weight of the member itself and the weight he/she bears double _calculate_weight(int32_t x, int32_t y) { int64_t self_weight = x % 2 ? boy_weight : girl_weight; // the toppest one if (x == 0 && y == 0) { return self_weight; } // the first one in the row if (y == 0) { return self_weight + _calculate_weight(x - 1, 0) / 2.0; } // the last one in the row if (y == x) { return self_weight + _calculate_weight(x - 1, x - 1) / 2.0; } // those in the middle return self_weight + _calculate_weight(x - 1, y - 1) / 2.0 + _calculate_weight(x - 1, y) / 2.0; } ``` :::