diff --git a/Informatik_I/Exercise_9/Task_1/README.org b/Informatik_I/Exercise_9/Task_1/README.org new file mode 100644 index 0000000..92fac2f --- /dev/null +++ b/Informatik_I/Exercise_9/Task_1/README.org @@ -0,0 +1,175 @@ +#+title: Task 1: Complex Numbers + +#+author: JirR02 +* Task +:PROPERTIES: +:CUSTOM_ID: task +:END: +Create your own data type for complex numbers that can be used as a +drop-in replacement for double. The definition of the data type and the +forward declarations of operators must be in file =complex.h=, while the +implementation of operators must be in file =complex.cpp=. + +1. Define a struct named =Complex= that represents a complex number in + the cartesian form. As data type use floating point numbers with + =double= precision. + +2. Implement input and output =(>>, <<)= operators for reading and + writing of complex numbers. + +A complex number \((x pm yi)\) is represented in the format =[x,y]=, +where =x= and =y= follows the format of floating point numbers with +=double= precision. + +E.g., =[-2,5]= represents \((-2 + 5i)\) . *Important: No spaces*. + +*Note*: You can assume that your input value is a well-formatted complex +number. + +3. [@3] Implement arithmetic operators for addition, subtraction, + multiplication, and division \((+,-,*,/)\) of complex numbers. For + the division, you may assume that the squared modulus of the divisor + is not zero, even after rounding it to a floating point number. + Finally, you do not need to treat the case of division by zero. + +4. Implement the negation operator \((-)\) of complex numbers. + +5. Implement comparison operators for equality and inequality + \((==,!=)\) of complex numbers. + +*Hint*: recall from Exercise 5 how to correctly compare floating point +numbers. + +* Solution +:PROPERTIES: +:CUSTOM_ID: solution +:END: +** =complex.h= +:PROPERTIES: +:CUSTOM_ID: complex.h +:END: +#+begin_src cpp +#pragma once + +#include +#include + +struct Complex { + double a; + double b; +}; + +// arithmetic operators +Complex operator+(const Complex &cn1, const Complex &cn2); +Complex operator-(const Complex &cn1, const Complex &cn2); +Complex operator*(const Complex &cn1, const Complex &cn2); +Complex operator/(const Complex &cn1, const Complex &cn2); + +// negation operator + +Complex operator-(const Complex &cn1); + +// equality and inequality operators + +bool operator==(const Complex &cn1, const Complex &cn2); +bool operator!=(const Complex &cn1, const Complex &cn2); + +// reads a complex number from input +std::istream &operator>>(std::istream &in, Complex &a); +std::ostream &operator<<(std::ostream &out, const Complex &a); +#+end_src + +** =complex.cpp= +:PROPERTIES: +:CUSTOM_ID: complex.cpp +:END: +#+begin_src cpp +#include "complex.h" +#include + +std::istream &operator>>(std::istream &in, Complex &a) { + char open; + char comma; + char close; + double aa; + double ab; + in >> open; + if (open == '[') { + in >> aa >> comma >> ab >> close; + if (comma == ',' && close == ']') { + a.a = aa; + a.b = ab; + } else { + std::cerr << "Invalid Input!"; + } + } else { + std::cerr << "Invalid Input!"; + } + return in; +} + +std::ostream &operator<<(std::ostream &out, const Complex &a) { + return out << "[" << a.a << "," << a.b << "]"; +} + +Complex operator+(const Complex &cn1, const Complex &cn2) { + Complex res; + double a = cn1.a + cn2.a; + double b = cn1.b + cn2.b; + res.a = a; + res.b = b; + return res; +} + +Complex operator-(const Complex &cn1, const Complex &cn2) { + Complex res; + double a = cn1.a - cn2.a; + double b = cn1.b - cn2.b; + res.a = a; + res.b = b; + return res; +} + +Complex operator*(const Complex &cn1, const Complex &cn2) { + Complex res; + double a = (cn1.a * cn2.a) - (cn1.b * cn2.b); + double b = (cn1.a * cn2.b) + (cn1.b * cn2.a); + res.a = a; + res.b = b; + return res; +} + +Complex operator/(const Complex &cn1, const Complex &cn2) { + Complex res; + double a = (cn1.a * cn2.a + cn1.b * cn2.b) / (cn2.a * cn2.a + cn2.b * cn2.b); + double b = (cn1.b * cn2.a - cn1.a * cn2.b) / (cn2.a * cn2.a + cn2.b * cn2.b); + res.a = a; + res.b = b; + return res; +} + +Complex operator-(const Complex &cn1) { + Complex res; + double a = -cn1.a; + double b = -cn1.b; + res.a = a; + res.b = b; + return res; +} + +bool operator==(const Complex &cn1, const Complex &cn2) { + double epsilon = 0.1; + return (std::abs(cn1.a - cn2.a) < epsilon) && + (std::abs(cn1.b - cn2.b) < epsilon); +} + +bool operator!=(const Complex &cn1, const Complex &cn2) { + double epsilon = 0.1; + return (std::abs(cn1.a - cn2.a) > epsilon) || + (std::abs(cn1.b - cn2.b) > epsilon); +} +#+end_src + +-------------- + +Made by JirR02 in Switzerland 🇨🇭 diff --git a/Informatik_I/Exercise_9/Task_2/README.org b/Informatik_I/Exercise_9/Task_2/README.org new file mode 100644 index 0000000..e9f861b --- /dev/null +++ b/Informatik_I/Exercise_9/Task_2/README.org @@ -0,0 +1,96 @@ +#+title: Task 2: Understanding struct & classes + +#+author: JirR02 +/This task is a text based task. You do not need to write any +program/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: +Consider the following definitions: + +1. + +#+begin_src cpp +struct A { +int a; +double b; +int c; +}; + +A str = {1, 1.5, 2}; +std::vector vec = {1, 1, 3}; +int& a = vec[0]; +#+end_src + +For each of the provided expressions state their /C++ type/ and /value/: + +1. =str.a * str.b= +2. =str.b == vec[1]= +3. =str.a * str.b / str.c= +4. =vec[str.a] / str.c= +5. =a / 2 - str.b= + +2. [@2] + +#+begin_src cpp +class B { +public: +B(): vec(128) { +for (int i = 0; i < 128; ++i) { +vec[i] = 0; +} +} + +// PRE: ... +// POST: ... +void add(const char c) { +++vec[c]; +} + +// PRE: ... +// POST: ... +int get(const char c) const { +return vec[c]; +} + +private: +std::vector vec; +}; +#+end_src + +Determine PRE- and POST-conditions for the methods add and get. As these +methods are members functions of class B, PRE- and POST-conditions +should be derived taking the public interface of the class into account. + +* Solution +:PROPERTIES: +:CUSTOM_ID: solution +:END: +#+begin_src markdown + +1. `plain|` + +1. Type: `cpp|double` / Value: `cpp|1.5` +2. Type: `cpp|bool` / Value: `cpp|true` +3. Type: `cpp|double` / Value: `cpp|0.75` +4. Type: `cpp|int` / Value: `cpp|0` +5. Type: `cpp|double` / Value: `cpp|-1.5` + +2. ```c++ +// PRE: 0 <= c < 128 +// POST: Increments the value of the vector at position c +void add(const char c); + +// PRE: 0 <= c < 128 +// POST: Gets the value of the vector at position c +int get(const char c) const; +#+end_src + +``` + +-------------- + +Made by JirR02 in Switzerland 🇨🇭 diff --git a/Informatik_I/Exercise_9/Task_3/README.org b/Informatik_I/Exercise_9/Task_3/README.org new file mode 100644 index 0000000..dcfd746 --- /dev/null +++ b/Informatik_I/Exercise_9/Task_3/README.org @@ -0,0 +1,62 @@ +#+title: Task 3: Averager + +#+author: JirR02 +* Task +:PROPERTIES: +:CUSTOM_ID: task +:END: +Write a class =Averager= that computes averages of given values of type +=double=. + +Initially, an instance of class =Averager= does not contain any value. +The class =Averager= must provide the following functionality: + +#+begin_src cpp +// POST: Adds a value to the current average calculation. +void add_value(double value); + +// POST: Returns the average of all added values, +// or zero, if no value has been added. +double get_average(); + +// POST: Removes all values from the current average calculation. +void reset(); +#+end_src + +The declaration and implementation of class Averager must be split +between header file (=averager.h=, containing declaration) and +implementation file (=averager.cpp=, containing implementation). + +/Note: The above functions have already been declared in averager.h for +you. You only need to provide function definitions in/ =averager.cpp=. + +* Solution +:PROPERTIES: +:CUSTOM_ID: solution +:END: +#+begin_src cpp +#include "averager.h" + +void Averager::add_value(double value) { + sum += value; + ++count; +} + +double Averager::get_average() { + double res; + if (count == 0) + res = 0; + else + res = sum / count; + return res; +} + +void Averager::reset() { + sum = 0; + count = 0; +} +#+end_src + +-------------- + +Made by JirR02 in Switzerland 🇨🇭 diff --git a/Informatik_I/Exercise_9/Task_4/README.org b/Informatik_I/Exercise_9/Task_4/README.org new file mode 100644 index 0000000..707eedb --- /dev/null +++ b/Informatik_I/Exercise_9/Task_4/README.org @@ -0,0 +1,111 @@ +#+title: Task 4: [Hidden tests][Exam 2019.02 RW] Number Pairs with Sum + +#+author: JirR02 +* Number of pairs with given sum +:PROPERTIES: +:CUSTOM_ID: number-of-pairs-with-given-sum +:END: +In this exercise, you are going to use iterators to count the number of +pairs in a vector which sum up to a given value. + +More formally, given a vector \(v\) of length \(n\) and a value \(s\), +we are interested in the number of pairs \(i\),\(j\) for which the +following conditions hold: + +1. \(0 leq i < j < n\) +2. \(v\[i\] + v\[j\] = s\) + +* Task +:PROPERTIES: +:CUSTOM_ID: task +:END: +The function =pairs_with_sum= declared in =pair_sum.h= computes the +number of pairs which sum up to a given value. Your task is implementing +this function in =pair_sum.cpp=. + +* Input & Output +:PROPERTIES: +:CUSTOM_ID: input-output +:END: +The program first reads a list of integers (separated by spaces) from +=std::cin=. The first integer specifies the value \(s\). The other +integers specify the vector \(s\). + +The program then calls the function +=pairs_with_sum(s, v.begin(), v.end())= to compute the number of pairs +that sum up to \(s\). + +Finally, the result is printed to the console. + +*** Example: +:PROPERTIES: +:CUSTOM_ID: example +:END: +- sum = 8, vector = 1 7 2 6 6 +- pairs with sum(1,7), (2,6), (2,6) +- \(Rightarrow\) number pairs = 3. + +#+begin_src shell +8 1 7 2 6 6 +number of pairs with sum 8: 3 +#+end_src + +*Note*: This was a task in the 2019.02 RW exam but has since been +adapted slightly: better input handling (no need to press CTRL+D/CTRL+Z +to end vector), description, file structure, and master solution. + +*Note*: You can safely assume that the sum of two values in the vector +does not cause an overflow. + +* 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 "pair_sum.h" +#include + +// PRE: for any two indices i and j, v[i] + v[j] ≤ INT_MAX +// POST: returns the number of indices (i,j), i