2AKIFT POS Test (Group B)

2023-06-14

Max. 100 points

Name:

Task Max. Achieved
1 25
2 25
3 25
4 25
Sum 100
Grading: > 87.5: 1, >75: 2, >62.5 : 3, >50: 4, <=50: 5
    1. Answer the following statements indicating whether they are True or False.
      0-3 correct: 0 points, 4 correct: 5 points, 5 correct: 10 points, 6 correct: 15 points.
      Statement True False
      cmake can generate Makefiles.
      One can only use cmake if the chosen IDE supports it.
      cmake is platform independent.
      With dynamic memory it is possible to grow and shrink dynamic data structures.
      The size of the stack can be determined with ulimit -s.
      Using memory from the heap is faster than from the stack.
    2. Answer the following statements indicating whether they are True or False.
      0-2 correct: 0 points, 3 correct: 5 points, 4 correct: 10 points.
      Statement True False
      Text files have the advantage of being human readable.
      There are multiple standards for storing data in text files.
      Binary files can easily be read with any text editor.
      Storing data in binary files generally requires more memory than structured text files.
  1. The following C17 snippets are executed as a part of int main(.) (unless main is part of the snippet). Assume that all neccessary standard library #includes are present.
    What do these code snippets write to stdout? Write their exact output below each snippet.
    If a snippet cannot be compiled, would crash or its output is undefined, it is enough to write “ERROR”. If there is no visible output, write "-".
    5 points for each correct answer.
    1. typedef struct { double x; double y; } Point;
      Point test = {.25, .75};
      printf("[%.2lf %.2lf]\n", test.x, test.y);
      [0.25 0.75]
    2. int a = 10;
      int* p = &a;
      int** pp = &p;
      **pp /= **pp;
      printf("%d\n", a);
      1
    3. char s[] = "Hello";
      char* p = s;
      while (*p) {
        *p = toupper(*p);
        ++p;
      }
      puts(s);
      HELLO
    4. unsigned int radicand = 36;
      for (unsigned int i = 0; i <= radicand; --i) {
        if (i * i == radicand) { printf("%u", i); }
      }
      -
    5. size_t size = 8192 * 1024;  // 8 MB
      int* array = (int*) malloc(size);
      for (size_t i = 0; i < size / sizeof(int); ++i) {
        array[i] = i * i;  // initialize the array ...
      }
      printf("Survived?\n");
      free(array);  // avoid memory leak
      Survived?
  2. Queen Attack
    const int CAN_NOT_ATTACK = 0;
    const int CAN_ATTACK = 1;
    const int INVALID_POSITION = 2;
    typedef struct {
      uint8_t row;
      uint8_t column;
    } Position;
    Given the position of two queens on a chess board (8 times 8 squares) as 0 indexed row and column of type Position, determine whether the two queens have invalid positions, can attack each other or cannot attach each other. To do so, implement a function int can_attack(Position queen_1, Position queen_2) that returns the appropriate constant as defined above.
    The setting is valid, if the two queens do not share the same field and if both of them are based within the 8x8 board. Assume that two queens can attack each other if the setting is valid and they share the same row, column or diagonal on the board.
    5 points for catching any possible off-board condition as invalid
    5 points for returning invalid if the queens share a position
    5 points for returning CAN_ATTACK in case rows or columns are shared and the setting is valid
    5 points for returning CAN_ATTACK in case the diagonal is shared and the setting is valid
    5 points for returning CAN_NOT_ATTACK in case the setting is valid but an attack is impossible
    bool is_valid(Position pos) {
      if (pos.row >= 8 || pos.column >= 8) return false;
      return true;
    }
    
    int can_attack(Position queen_1, Position queen_2) {
      if (!(is_valid(queen_1) && is_valid(queen_2))) return INVALID_POSITION;
      if (queen_1.row == queen_2.row && queen_1.column == queen_2.column)
        return INVALID_POSITION;
      if (queen_1.row == queen_2.row || queen_1.column == queen_2.column)
        return CAN_ATTACK;
      int8_t d_row = queen_1.row - queen_2.row;
      int8_t d_column = queen_1.column - queen_2.column;
      if (abs(d_row) == abs(d_column)) return CAN_ATTACK;
      return CAN_NOT_ATTACK;
    }
  3. Binary Numbers
    Implement a function int binary_str_to_int(const char* str) that takes a C string representing a binary number (eg. "100101") and returns the base 10 numeric representation of that string. In case of "100101", the result would be 125+024+023+122+021+120=32+4+1=37. Do not use any library functions. You may assume the input to be valid.
    5 points if the function name and signature are correct and no library functions are used
    5 points for calculating the number of digits
    5 points for skipping 0 digits
    5 points for calculating the value of each digit
    5 points for returning the correct value
    int binary_str_to_int(const char* str) {
        int digits = 0;
        int result = 0;
        while (str[digits]) { digits++; }
        for (int i = digits - 1; i >= 0; --i) {
            if (str[digits - i - 1] == '1') {
                result += 1 << i;
            }
        }
        return result;
    }