diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1098516 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.norg +*.md diff --git a/Informatik_I/Exercise_7/Task_1/README.org b/Informatik_I/Exercise_7/Task_1/README.org new file mode 100644 index 0000000..c2ef1ce --- /dev/null +++ b/Informatik_I/Exercise_7/Task_1/README.org @@ -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 diff --git a/Informatik_I/Exercise_7/Task_2/README.org b/Informatik_I/Exercise_7/Task_2/README.org new file mode 100644 index 0000000..7054228 --- /dev/null +++ b/Informatik_I/Exercise_7/Task_2/README.org @@ -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=. + +*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; +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 diff --git a/Informatik_I/Exercise_7/Task_3/README.org b/Informatik_I/Exercise_7/Task_3/README.org new file mode 100644 index 0000000..9e5dd7c --- /dev/null +++ b/Informatik_I/Exercise_7/Task_3/README.org @@ -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 + +#include + +#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 diff --git a/Informatik_I/Exercise_7/Task_4/README.org b/Informatik_I/Exercise_7/Task_4/README.org new file mode 100644 index 0000000..ad850da --- /dev/null +++ b/Informatik_I/Exercise_7/Task_4/README.org @@ -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 + +using vec = std::vector; + +// 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 diff --git a/README.org b/README.org index a39fc3c..ed4413e 100644 --- a/README.org +++ b/README.org @@ -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 🇨🇭