# 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

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;
}
```
:::