Exercise 8
Added Exercise 8 to repository
This commit is contained in:
parent
c71d2e026f
commit
950098d35e
@ -1,7 +1,9 @@
|
|||||||
#+title: Task 1: Recursive function analysis
|
#+title: Task 1: Recursive function analysis
|
||||||
|
|
||||||
#+author: JirR02
|
#+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)./
|
/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
|
* Task
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
@ -50,22 +52,30 @@ g(n - 1);
|
|||||||
// PRE: n is a positive integer
|
// PRE: n is a positive integer
|
||||||
// POST: returns true if n is even and false if n is odd.
|
// POST: returns true if n is even and false if n is odd.
|
||||||
```
|
```
|
||||||
|
#+end_src
|
||||||
|
|
||||||
ii) The function =plain|f= terminates because it has a termination
|
2) [@2] The function =plain|f= terminates because it has a termination
|
||||||
condition. It will terminate once n reaches 0. If the number is
|
condition. It will terminate once n reaches 0. If the number is
|
||||||
negative, it will be in an infinite loop.
|
negative, it will be in an infinite loop.
|
||||||
|
|
||||||
iii) $\text{Calls}_{f}(n) = n$
|
3) \(\text{Calls}_{f}(n) = n\)
|
||||||
|
|
||||||
2. i) Pre- and post conditions
|
2. [@2]
|
||||||
|
1) Pre- and post conditions
|
||||||
|
|
||||||
```cpp
|
#+begin_src cpp
|
||||||
// PRE: n is a positive integer
|
// PRE: n is a positive integer
|
||||||
// POST: print 2^n *
|
// 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
|
#+end_src
|
||||||
|
|
||||||
|
2) [@2] 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.
|
||||||
|
|
||||||
|
3) \(\text{Calls}_{g}(n) = 2^n\)
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
|
||||||
|
___
|
||||||
|
Made by JirR02 in Switzerland 🇨🇭
|
||||||
|
#+end_example
|
||||||
|
@ -86,3 +86,7 @@ vec all_bitstrings_up_to_n(int n) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Made by JirR02 in Switzerland 🇨🇭
|
||||||
|
@ -195,3 +195,7 @@ void print_hourglass(int base_width) {
|
|||||||
print_trapezoid(base_width, base_width, 0, true);
|
print_trapezoid(base_width, base_width, 0, true);
|
||||||
print_trapezoid(base_width, base_width - 1, 0, false);
|
print_trapezoid(base_width, base_width - 1, 0, false);
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Made by JirR02 in Switzerland 🇨🇭
|
||||||
|
@ -99,3 +99,7 @@ int best_two_elements(const vec &values, const vec &weights, int weight_limit) {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Made by JirR02 in Switzerland 🇨🇭
|
||||||
|
69
Informatik_I/Exercise_8/Task_1/README.org
Normal file
69
Informatik_I/Exercise_8/Task_1/README.org
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#+title: Task 1: Reverse Digits
|
||||||
|
|
||||||
|
#+author: JirR02
|
||||||
|
* Task
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: task
|
||||||
|
:END:
|
||||||
|
The goal of this task is to implement a program to read a number and
|
||||||
|
print its reverse.
|
||||||
|
|
||||||
|
You should complete the implementation of the reverse function in
|
||||||
|
=reverse.cpp=. This function gets an =int= as input parameter, and it
|
||||||
|
should print the digits of the number in reverse.
|
||||||
|
|
||||||
|
The =reverse= function must be implemented recursively (without any
|
||||||
|
loop). To enforce this, we disallow the use of =for= or =while=.
|
||||||
|
|
||||||
|
* Input
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: input
|
||||||
|
:END:
|
||||||
|
The input is a single non-negative =int= number.
|
||||||
|
|
||||||
|
An input example:
|
||||||
|
|
||||||
|
#+begin_src shell
|
||||||
|
321231
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* Output
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: output
|
||||||
|
:END:
|
||||||
|
For the above input, the output should be:
|
||||||
|
|
||||||
|
#+begin_src shell
|
||||||
|
132123
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Note: You are not allowed to use the string library to solve this task!
|
||||||
|
|
||||||
|
* Solution
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: solution
|
||||||
|
:END:
|
||||||
|
#+begin_src cpp
|
||||||
|
#include "reverse.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
// PRE: n >= 0
|
||||||
|
// POST: print the digits of the input in reverse order to std::cout
|
||||||
|
void reverse(int n) {
|
||||||
|
|
||||||
|
int res = n % 10;
|
||||||
|
std::cout << res;
|
||||||
|
|
||||||
|
int new_int = n / 10;
|
||||||
|
|
||||||
|
if (new_int == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
reverse(new_int);
|
||||||
|
}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Made by JirR02 in Switzerland 🇨🇭
|
123
Informatik_I/Exercise_8/Task_2/README.org
Normal file
123
Informatik_I/Exercise_8/Task_2/README.org
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
#+title: Task 2: Set Product
|
||||||
|
|
||||||
|
#+author: JirR02
|
||||||
|
* Task
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: task
|
||||||
|
:END:
|
||||||
|
In this exercise, you are going to implement a function which computes
|
||||||
|
the /n-fold Cartesian product/ for sets. The n-fold Cartesian product is
|
||||||
|
a way to combine multiple sets of items. Imagine you have multiple sets,
|
||||||
|
denoted as \(A_1, A_2, ..., A_n\). The n-fold Cartesian product is like
|
||||||
|
taking one item from each set and combining them into a new set.
|
||||||
|
|
||||||
|
For example, let's say you have two sets:
|
||||||
|
|
||||||
|
\[
|
||||||
|
A_1 = \{a,b,c\} \text{ and } A_2 = \{ x, y, z \}
|
||||||
|
\]
|
||||||
|
|
||||||
|
The Cartesian product of these two sets would be a new set that contains
|
||||||
|
all possible combinations of one item from \(A_1\) and one item from
|
||||||
|
\(A_2\):
|
||||||
|
|
||||||
|
\[
|
||||||
|
A_1 \times A_2 = \{(a,x),(a,y),(a,z),(b,x),(b,y),(b,z),(c,x),(c,y),(c,z)\}
|
||||||
|
\]
|
||||||
|
|
||||||
|
In general, for any two sets \(A\) and \(B\), the Cartesian product
|
||||||
|
\(A times B\) is defined as:
|
||||||
|
|
||||||
|
\[
|
||||||
|
A \times B \{(a,b) | a \in A \text{ and } b \in B\}
|
||||||
|
\]
|
||||||
|
|
||||||
|
This can be generalized to the n-fold Cartesian product. For any \(n\)
|
||||||
|
sets \(A_1, A_2, ... , A_n\), the n-fold Cartesian product is defined
|
||||||
|
as:
|
||||||
|
|
||||||
|
\[
|
||||||
|
A_1 \times A_2 \times ... \times A_n = \{(a_1, a_2, ..., a_n) | a_i \in A_i \text{ for all } i = 1, 2, ... , n\}
|
||||||
|
\]
|
||||||
|
|
||||||
|
Note: This task naturally lends itself to a *recursive implementation*.
|
||||||
|
|
||||||
|
** The Set class
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: the-set-class
|
||||||
|
:END:
|
||||||
|
A set class is implemented in =set.h= and =set.ipp=. This class
|
||||||
|
implements a number of useful operations on sets. *For an overview of
|
||||||
|
its functionalities, please refer to this week's Power Set code
|
||||||
|
example*. Note that you do not need to understand any of the code in
|
||||||
|
=set.h= and =set.ipp= in order to use it!
|
||||||
|
|
||||||
|
* Input & Output
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: input-output
|
||||||
|
:END:
|
||||||
|
When the program starts, you are first prompted to enter the number of
|
||||||
|
sets. Then, you are prompted to enter each set. Sets are entered on a
|
||||||
|
single line using the format
|
||||||
|
=<number of char elements> <elements separated by spaces>=.
|
||||||
|
|
||||||
|
Once all sets are entered, the set product is computed using the
|
||||||
|
=set_product= function. Finally, the resulting set is printed to the
|
||||||
|
console.
|
||||||
|
|
||||||
|
*** Example
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: example
|
||||||
|
:END:
|
||||||
|
#+begin_src shell
|
||||||
|
Number of sets: 2
|
||||||
|
Set 0: 3 a b c
|
||||||
|
Set 1: 2 x y
|
||||||
|
Product Set:
|
||||||
|
{ax,ay,bx,by,cx,cy}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
*Note*: Each input set is a set of char elements. At least 1 set must be
|
||||||
|
inputted.
|
||||||
|
|
||||||
|
* Solution
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: solution
|
||||||
|
:END:
|
||||||
|
#+begin_src cpp
|
||||||
|
#include <iterator>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "set.h"
|
||||||
|
#include "solution.h"
|
||||||
|
|
||||||
|
StringSet set_product(const std::vector<CharSet> &sets) {
|
||||||
|
StringSet res;
|
||||||
|
StringSet ram;
|
||||||
|
if (sets.size() == 1) {
|
||||||
|
for (int i = 0; i < sets[0].size(); ++i) {
|
||||||
|
std::string j(1, sets[0][i]);
|
||||||
|
res.insert(j);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
CharSet first_subset = sets[0];
|
||||||
|
std::vector<CharSet> remaining_set(sets.begin() + 1, sets.end());
|
||||||
|
|
||||||
|
StringSet res_subset = set_product(remaining_set);
|
||||||
|
|
||||||
|
for (char char_first_subset : first_subset.elements()) {
|
||||||
|
for (std::string str_res_subset : res_subset.elements()) {
|
||||||
|
res.insert(std::string(1, char_first_subset) + str_res_subset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Made by JirR02 in Switzerland 🇨🇭
|
85
Informatik_I/Exercise_8/Task_3/README.org
Normal file
85
Informatik_I/Exercise_8/Task_3/README.org
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#+title: Task 3: All permutations
|
||||||
|
|
||||||
|
#+author: JirR02
|
||||||
|
* Task
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: task
|
||||||
|
:END:
|
||||||
|
In this exercise, you are going to implement a function which computes
|
||||||
|
the set of all permutations of a given string.
|
||||||
|
|
||||||
|
Note: This task naturally lends itself to a *recursive implementation*.
|
||||||
|
|
||||||
|
** Example
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: example
|
||||||
|
:END:
|
||||||
|
The string "abc" has the following set of permutations:
|
||||||
|
|
||||||
|
{ abc, acb, bac, bca, cab, cba }
|
||||||
|
|
||||||
|
** The Set class
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: the-set-class
|
||||||
|
:END:
|
||||||
|
A set class is implemented in =set.h= and =set.ipp=. This class
|
||||||
|
implements a number of useful operations on sets. *For an overview of
|
||||||
|
its functionalities, please refer to the Power Set code example*. Note
|
||||||
|
that you do not need to understand any of the code in =set.h= and
|
||||||
|
=set.ipp= in order to use it!
|
||||||
|
|
||||||
|
* Input & Output
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: input-output
|
||||||
|
:END:
|
||||||
|
When the program starts, you are first prompted to enter a string.
|
||||||
|
|
||||||
|
Then, the program computes the set of all permutations using the
|
||||||
|
function *all_permutations*. Finally, the resulting set is printed to
|
||||||
|
the console.
|
||||||
|
|
||||||
|
*** Example
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: example-1
|
||||||
|
:END:
|
||||||
|
#+begin_src shell
|
||||||
|
String: abc
|
||||||
|
Permutations:
|
||||||
|
{abc,acb,bac,bca,cab,cba}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Hint: You may find the substr method useful. The method is documented
|
||||||
|
here.
|
||||||
|
|
||||||
|
* Solution
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: solution
|
||||||
|
:END:
|
||||||
|
#+begin_src cpp
|
||||||
|
#include "pair_sum.h"
|
||||||
|
#include <climits>
|
||||||
|
|
||||||
|
// PRE: for any two indices i and j, v[i] + v[j] ≤ INT_MAX
|
||||||
|
// POST: returns the number of indices (i,j), i<j of a vector v
|
||||||
|
// that corresponds to the given iterator range such that
|
||||||
|
// v[i] + v[j] == sum.
|
||||||
|
int pairs_with_sum(int sum, iterator begin, iterator end) {
|
||||||
|
int count = 0;
|
||||||
|
int size = end - begin;
|
||||||
|
|
||||||
|
for (int i = 0; i < size; ++i) {
|
||||||
|
for (int j = i + 1; j < size; ++j) {
|
||||||
|
iterator cur_begin = begin + i;
|
||||||
|
iterator cur_end = begin + j;
|
||||||
|
if (*cur_begin + *cur_end == sum)
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Made by JirR02 in Switzerland 🇨🇭
|
122
Informatik_I/Exercise_8/Task_4/README.org
Normal file
122
Informatik_I/Exercise_8/Task_4/README.org
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#+title: Task 4: Dual Numbers
|
||||||
|
|
||||||
|
#+author: JirR02
|
||||||
|
* Dual Numbers
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: dual-numbers
|
||||||
|
:END:
|
||||||
|
In this task, you are required to implement a basic version of /dual
|
||||||
|
number/. Dual numbers are conceptually similar to complex number.
|
||||||
|
|
||||||
|
A dual numbers \(n\) is of the following form:
|
||||||
|
|
||||||
|
\[
|
||||||
|
z = a + \epsilon b
|
||||||
|
\]
|
||||||
|
|
||||||
|
with the following identity:
|
||||||
|
|
||||||
|
\[
|
||||||
|
\epsilon ^2 = 0
|
||||||
|
\]
|
||||||
|
|
||||||
|
Adding two dual numbers is done component-wise:
|
||||||
|
|
||||||
|
\[
|
||||||
|
(a + \epsilon b) + (c + \epsilon d) + (a+c) + \epsilon (b + d)
|
||||||
|
\]
|
||||||
|
|
||||||
|
Subtracting two dual numbers is also done component-wise:
|
||||||
|
|
||||||
|
\[
|
||||||
|
(a + \epsilon b) - (c + \epsilon d) = (a + \epsilon b) + (-c - \epsilon d) = (a - c) + \epsilon(b - d)
|
||||||
|
\]
|
||||||
|
|
||||||
|
Using the identity above, multiplying two dual numbers gives
|
||||||
|
|
||||||
|
\[
|
||||||
|
(a + \epsilon b)(c + \epsilon d) = ac + \epsilon(ad + bc)
|
||||||
|
\]
|
||||||
|
|
||||||
|
** Tasks
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: tasks
|
||||||
|
:END:
|
||||||
|
You are required to extend the provided implementation of dual numbers
|
||||||
|
by adding the implementation for various arithmetic operators in
|
||||||
|
=DualNumber.cpp=.
|
||||||
|
|
||||||
|
*** Task 1: Addition operator
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: task-1-addition-operator
|
||||||
|
:END:
|
||||||
|
Implement the addition operator
|
||||||
|
|
||||||
|
#+begin_src shell
|
||||||
|
DualNumber operator+(const DualNumber& dn1, const DualNumber& dn2)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
in file =DualNumber.cpp=.
|
||||||
|
|
||||||
|
*** Task 2: Subtraction operator
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: task-2-subtraction-operator
|
||||||
|
:END:
|
||||||
|
Implement the subtraction operator
|
||||||
|
|
||||||
|
#+begin_src shell
|
||||||
|
DualNumber operator-(const DualNumber& dn1, const DualNumber& dn2)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
in file =DualNumber.cpp=.
|
||||||
|
|
||||||
|
*** Task 3: Multiplication operator
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: task-3-multiplication-operator
|
||||||
|
:END:
|
||||||
|
Implement the multiplication operator
|
||||||
|
|
||||||
|
#+begin_src shell
|
||||||
|
DualNumber operator*(const DualNumber& dn1, const DualNumber& dn2)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
in file =DualNumber.cpp=.
|
||||||
|
|
||||||
|
* Solution
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: solution
|
||||||
|
:END:
|
||||||
|
#+begin_src cpp
|
||||||
|
#include "DualNumber.h"
|
||||||
|
|
||||||
|
DualNumber operator+(const DualNumber &dn1, const DualNumber &dn2) {
|
||||||
|
DualNumber res;
|
||||||
|
double a = dn1.a + dn2.a;
|
||||||
|
double b = dn1.b + dn2.b;
|
||||||
|
res.a = a;
|
||||||
|
res.b = b;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
DualNumber operator-(const DualNumber &dn1, const DualNumber &dn2) {
|
||||||
|
DualNumber res;
|
||||||
|
double a = dn1.a - dn2.a;
|
||||||
|
double b = dn1.b - dn2.b;
|
||||||
|
res.a = a;
|
||||||
|
res.b = b;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
DualNumber operator*(const DualNumber &dn1, const DualNumber &dn2) {
|
||||||
|
DualNumber res;
|
||||||
|
double a = dn1.a * dn2.a;
|
||||||
|
double b = (dn1.a * dn2.b) + (dn1.b * dn2.a);
|
||||||
|
res.a = a;
|
||||||
|
res.b = b;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Made by JirR02 in Switzerland 🇨🇭
|
Loading…
x
Reference in New Issue
Block a user