Exercise 7

Added Exercise 7 to Repository
This commit is contained in:
JirR02 2025-04-07 08:56:57 +02:00
parent bfc1a7a2b0
commit c71d2e026f
6 changed files with 471 additions and 7 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.norg
*.md

View File

@ -0,0 +1,71 @@
#+title: Task 1: Recursive function analysis
#+author: JirR02
/This task is a text based task. You do not need to write any program or C++ file: the answer should be written in main.md (and might include code fragments if questions ask for them)./
* Task
:PROPERTIES:
:CUSTOM_ID: task
:END:
For each of the following recursive functions:
1.
#+begin_src cpp
bool f(const int n) {
if (n == 0) return false;
return !f(n - 1);
}
#+end_src
2. [@2]
#+begin_src cpp
void g(const int n) {
if (n == 0) {
std::cout << "*";
return;
}
g(n - 1);
g(n - 1);
}
#+end_src
1) Formulate pre- and post conditions.
2) Show that the function terminates. *Hint*: No proof expected, proceed
similar as with the lecture example of the factorial function.
3) Determine the number of functions calls as mathematical function of
parameter n. *Note*: include the first non-recursive function call.
* Solution
:PROPERTIES:
:CUSTOM_ID: solution
:END:
#+begin_src markdown
1. i) Pre- and post conditions
```c++
// PRE: n is a positive integer
// POST: returns true if n is even and false if n is odd.
```
ii) The function =plain|f= terminates because it has a termination
condition. It will terminate once n reaches 0. If the number is
negative, it will be in an infinite loop.
iii) $\text{Calls}_{f}(n) = n$
2. i) Pre- and post conditions
```cpp
// PRE: n is a positive integer
// POST: print 2^n *
```
ii) The function =plain|g= terminates because it has a termination condition. It will terminate once n reaches 0. If the number is negative, it will be in an infinite loop.
iii) $\text{Calls}_{g}(n) = 2^n$
#+end_src

View File

@ -0,0 +1,88 @@
#+title: Task 2: Bitstrings up to n
#+author: JirR02
* Task
:PROPERTIES:
:CUSTOM_ID: task
:END:
Your task is implementing the function =all_bitstrings_up_to_n= in
=solution.cpp= which generates all bitstrings up to length \(n\) in
ascending order. The generated bitstrings are returned in a
=std::vector<std::string>=.
*Note*: It is *mandatory* to use *recursive implementation* for this
task.
* Input & Output
:PROPERTIES:
:CUSTOM_ID: input-output
:END:
The program first prompts you to enter the bitstring length \(n\). It
then calls the function =all_bitstrings_up_to_n= and prints the returned
bitstrings to the console.
** Example
:PROPERTIES:
:CUSTOM_ID: example
:END:
#+begin_src sh
Bitstring length: 2
Bitstrings up to length 2
0
1
00
01
10
11
#+end_src
*Note*: The empty line after Bitstrings up to length 2 is actually the
bitstring of length \(0\).
*Note*: The autograder will only accept output that exactly matches the
expected result. Therefore, do not output anything with =std::cout= in
the =all_bitstrings_up_to_n= function. 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.
* Solution
:PROPERTIES:
:CUSTOM_ID: solution
:END:
#+begin_src cpp
#include "solution.h"
using vec = std::vector<std::string>;
using str = std::string;
void bitstring(vec &res, str ram, int l) {
if (l == 0) {
res.push_back(ram);
return;
}
bitstring(res, ram + "0", l - 1);
bitstring(res, ram + "1", l - 1);
}
void recursion(int count, int n, vec &res) {
if (count > n)
return;
bitstring(res, "", count);
recursion(count + 1, n, res);
}
vec all_bitstrings_up_to_n(int n) {
vec res;
recursion(0, n, res);
return res;
}
#+end_src

View File

@ -0,0 +1,197 @@
#+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

View File

@ -0,0 +1,101 @@
#+title: Task 4: [Exam 2022.08 (ITET/MATH/PHYS/RW)] Mini-Knapsack
#+author: JirR02
* Note
:PROPERTIES:
:CUSTOM_ID: note
:END:
I don't know if we have to solve this task recursively or not. It is in
the topic of week but the task does not state this explicitly.
* Task Description
:PROPERTIES:
:CUSTOM_ID: task-description
:END:
As part of a promotion of the local supermarket, you are allowed to get
exactly two items for free. You want to maximize the value of the items
you take, but you need to take the weight limit of your backpack into
account.
You get two integer vectors, one with the value of every item, and one
with its weight. Return the maximum value that you can get by choosing
exactly 2 different items from the supermarket.
* Function
:PROPERTIES:
:CUSTOM_ID: function
:END:
Implement the function =best_two_elements= in =functions.h= according to
its pre- and postconditions.
*Rules*:
- The functions must satisfy their respective postconditions.
- You are not allowed to change the function signatures.
- You are not allowed to use additional libraries.
*Hint*:
- You do not need to check the pre- and postconditions (no asserts
necessary).
* Solution
:PROPERTIES:
:CUSTOM_ID: solution
:END:
#+begin_src cpp
#pragma once
#include <vector>
using vec = std::vector<int>;
// PRE: The vector "weights" at position i contains the weight of element
// i.
// The vector "values" at position i contains the value of element i.
// The vectors have the same size and always contain at least two
// items. The value and weight of every item is > 0.
//
// POST: Returns the sum of the value of the two items that have the most
// value,
// while the sum of their weight is at most `weight_limit`.
// It is not allowed to pick only one item.
// It is also not allowed to pick an item twice, but two different
// items must be chosen. If there are no two items that can be chosen
// (due to exceeding weight), return 0.
//
// Example:
// * weights: [1, 2, 2], values: [3, 1, 9], weight_limit: 3 ~~> 12;
void recursion1(int &value, int count1, int count2, const vec &values,
const vec &weights, int weight_limit) {
if (count2 == int(values.size()))
return;
if (int((values.at(count1)) + int(values.at(count2))) >= value &&
(int(weights.at(count1)) + int(weights.at(count2))) <= weight_limit)
value = int(values.at(count1)) + int(values.at(count2));
recursion1(value, count1, count2 + 1, values, weights, weight_limit);
}
void recursion2(int &value, int count1, const vec &values, const vec &weights,
int weight_limit) {
if (count1 == (int(values.size()) - 1))
return;
recursion1(value, count1, count1 + 1, values, weights, weight_limit);
recursion2(value, count1 + 1, values, weights, weight_limit);
}
int best_two_elements(const vec &values, const vec &weights, int weight_limit) {
int value = 0;
if (values.size() == weights.size() && values.size() >= 2 &&
weights.size() >= 2) {
recursion2(value, 0, values, weights, weight_limit);
}
return value;
}
#+end_src

View File

@ -1,16 +1,21 @@
#+TITLE: ETH Computer Science Projects
#+AUTHOR: JirR02
#+title: ETH Computer Science Projects
In this respository the computer science project of the ETH of D-ITET 2024 are managed. They can be used for inspiration.
#+author: JirR02
In this respository the computer science project of the ETH of D-ITET
2024 are managed. They can be used for inspiration.
The projects are uploaded on [[https://expert.ethz.ch/enrolled/AS24/itet0/exercises][Code Expert]].
The projects are uploaded on
[[https://expert.ethz.ch/enrolled/AS24/itet0/exercises][Code Expert]].
* DISCLAIMER!!!
I assume no liability for possible errors in the code (it certainly has a few in it, since I write it myself).
:PROPERTIES:
:CUSTOM_ID: disclaimer
:END:
I assume no liability for possible errors in the code (it certainly has
a few in it, since I write it myself).
Bugs can be reported via Discord, WhatsApp, Mail and Moodle.
-----
--------------
Made by JirR02 in Switzerland 🇨🇭