This shows you the differences between two versions of the page.
dss:laboratoare:04 [2019/06/24 12:28] razvan.nitu1305 [Exercises] |
dss:laboratoare:04 [2021/07/12 18:58] (current) razvan.nitu1305 [5. Ranges] |
||
---|---|---|---|
Line 497: | Line 497: | ||
===== Exercises ===== | ===== Exercises ===== | ||
+ | |||
+ | The lab can be found at this [[https://github.com/RazvanN7/D-Summer-School/tree/master/lab-04|link]]. | ||
==== 1. Complex numbers ==== | ==== 1. Complex numbers ==== | ||
- | Implement a struct that will emulate a [[https://en.wikipedia.org/wiki/Complex_number|complex number]]. The operations that need to be implement on complex numbers are: assignment, addition, subtraction, multiply and division. Write a unittest to assure the validity of the implementation. | + | Implement a struct that will emulate a [[https://en.wikipedia.org/wiki/Complex_number|complex number]]. The operations that need to be implemented on complex numbers are: assignment, addition, subtraction, multiply and division. Write a unittest to assure the validity of the implementation. |
<note> | <note> | ||
Line 506: | Line 508: | ||
</note> | </note> | ||
+ | ==== 2. Alias ==== | ||
+ | |||
+ | Navigate to the ''2-alias'' directory. Inspect the two source files. Compile de code: | ||
+ | |||
+ | <code bash> | ||
+ | dmd main.d func.d | ||
+ | </code> | ||
+ | |||
+ | What happens? Why? Before invoking function **fun**, add the line: | ||
+ | |||
+ | <code D> | ||
+ | alias fun = func.fun; | ||
+ | </code> | ||
+ | |||
+ | What happens? Why? | ||
+ | |||
+ | ==== 3. Nullable ==== | ||
+ | |||
+ | Implement a [[https://dlang.org/library/std/typecons/nullable.html#2|Nullable]] object. In D, there are certain types that cannot be null (such as int, struct objects etc.), also there are algorithms that work only for types that can be in the null state; for those algorithms to work with non-nullable types, an abstraction is considered in the form of a Nullable object. | ||
+ | |||
+ | * Implement the Nullable(T) struct by having a templated field which is the value and a boolean that keeps track whether the value is null or not; the Nullable object is considered null if the field holds the **.init** value | ||
+ | * Implement the methods: | ||
+ | - get: returns the value of the object if not null; if null, halts execution raising an assert error with the appropriate message; | ||
+ | - opAssign: a Nullable!T object can be assigned a value of type T; | ||
+ | - a constructor that takes a value of type T; | ||
+ | |||
+ | What is the problem with this implementation? | ||
+ | |||
+ | ==== 4. Alias this ==== | ||
+ | |||
+ | Solve the problem of the previous **Nullable!T** implementation by forwarding unknown operations to the T object contained. Test the new implementation by adding instances of **Nullable** with int, struct and class. | ||
+ | |||
+ | ==== 5. Ranges ==== | ||
+ | |||
+ | Implement a stack that respects the range interface. | ||
+ | |||
+ | - Implement the stack as an input range (you may use builtin arrays as the underlying data structure); | ||
+ | - Improve the stack by adding support for forward range methods; | ||
+ | - Improve the stack by adding support for bidirectional range methods; | ||
+ | - Improve the stack by adding support for random access range methods; | ||
+ | |||
+ | To test your implementation you can use these [[https://dlang.org/phobos/std_range_primitives.html|range primitives]] |