#+title: Task 3: [Hidden tests] Trapezoid printing

#+author: JirR02
* Task
:PROPERTIES:
:CUSTOM_ID: task
:END:
In this exercise, you are going to print trapezoids. A trapezoid is
defined by the width of its base and its height. A trapezoid can also
either be rightsideup or upsidedown.

*Note*: It is *mandatory* to use *recursive implementation* for this
task.

** Examples
:PROPERTIES:
:CUSTOM_ID: examples
:END:
*** Rightsideup trapezoid with height and width \(3\) (aka a triangle)
:PROPERTIES:
:CUSTOM_ID: rightsideup-trapezoid-with-height-and-width-3-aka-a-triangle
:END:
#+begin_src sh
  0
 0 0
0 0 0
#+end_src

Upsidedown trapezoid with height and width \(3\) (aka an upsidedown
triangle)

#+begin_src sh
0 0 0
 0 0
  0
#+end_src

*** Rightsideup trapezoid with base width 5 and height 2
:PROPERTIES:
:CUSTOM_ID: rightsideup-trapezoid-with-base-width-5-and-height-2
:END:
#+begin_src sh
 0 0 0 0
0 0 0 0 0
#+end_src

** Subtask 1: print_trapezoid
:PROPERTIES:
:CUSTOM_ID: subtask-1-print_trapezoid
:END:
Implement the function print_trapezoid. The function takes three
arguments:

- =int base_width=: The width of the trapezoid's base
- =int height=: The height of the trapezoid
- =int offset_left=: The number of spaces between the left edge of the
  trapezoid's base and the left edge of the console.
- =bool upsidedown=: Boolean indicating whether or not the trapezoid is
  upsidedown or rightsideup.

When called, the function should print the specified trapezoid to the
console.

** Subtask 2: print_diamond:
:PROPERTIES:
:CUSTOM_ID: subtask-2-print_diamond
:END:
Implement the function =print_diamond=.

The function prints a diamond with a given center width to the console.
A diamond is a rightsideup trapezoid on top of an upsidedown trapezoid.

For example, a diamond of width \(5\) looks as follows:

#+begin_src sh
    0
   0 0
  0 0 0
 0 0 0 0
0 0 0 0 0
 0 0 0 0
  0 0 0
   0 0
    0
#+end_src

** Subtask 3: print_hourglass:
:PROPERTIES:
:CUSTOM_ID: subtask-3-print_hourglass
:END:
Implement the function =print_hourglass=.

The function prints an hourglass with a given base width to the console.
A hourglass is an upsidedown trapezoid on top of a rightsideup
trapezoid.

For example, an hourglass of width \(5\) looks as follows:

#+begin_src sh
0 0 0 0 0
 0 0 0 0
  0 0 0
   0 0
    0
   0 0
  0 0 0
 0 0 0 0
0 0 0 0 0
#+end_src

*Note*: The autograder will only accept output that exactly matches the
expected result. Therefore, do not output anything with std::cout beyond
what is strictly required (i.e., ” ","=0=", and =std::endl= /"=n=“). For
debugging messages, use =std::cerr= as in:

#+begin_src cpp
std::cerr << "This is a test message." << std::endl;
#+end_src

Those will be ignored by the autograder.

* Hidden test cases
:PROPERTIES:
:CUSTOM_ID: hidden-test-cases
:END:
This exercise has some hidden test cases. You will see whether these
tests passed or failed, but you will not see the test input or the
expected output.

** Persistent input
:PROPERTIES:
:CUSTOM_ID: persistent-input
:END:
To help you in testing your code, you can enter your custom test input
in =input.txt=. When running the program, you can let CodeExpert read
the input from the file.

Write some program input in input.txt. Run the program as usual. Type f
(no spaces) in the terminal window and press Enter. The program will use
the contents of input.txt as input. Using this feature is entirely
optional and does not affect your score.

* Solution
:PROPERTIES:
:CUSTOM_ID: solution
:END:
#+begin_src cpp
#include <assert.h>

#include <iostream>

#include "solution.h"

void print_row(int n_bricks, int offset_left) {
  // print spaces for offset
  for (int i = 0; i < offset_left; ++i) {
    std::cout << " ";
  }

  // print bricks
  for (int i = 0; i < n_bricks; ++i) {
    if (i != 0) {
      std::cout << " ";
    }
    std::cout << "0";
  }
  std::cout << std::endl;
}

void print_trapezoid(int base_width, int height, int offset_left,
                     bool upsidedown) {
  assert(base_width >= height);

  if (upsidedown == true) {
    if (height == 0)
    return;

    print_row(base_width, offset_left);
    print_trapezoid(base_width - 1, height - 1, offset_left + 1, upsidedown);
  } else if (upsidedown == false) {
    if (height == 0)
    return;

    print_row(base_width - height + 1, offset_left + height - 1);
    print_trapezoid(base_width, height - 1, offset_left, upsidedown);
}
}

void print_diamond(int center_width) {
  print_trapezoid(center_width, center_width, 0, false);
  print_trapezoid(center_width - 1, center_width - 1, 0, true);
}

void print_hourglass(int base_width) {
  print_trapezoid(base_width, base_width, 0, true);
  print_trapezoid(base_width, base_width - 1, 0, false);
#+end_src

--------------

Made by JirR02 in Switzerland 🇨🇭
