less_retarded_wiki/exercises.md

85 lines
4.5 KiB
Markdown
Raw Normal View History

2021-12-31 23:56:32 +01:00
# Exercises
Here let be listed exercises for the readers of this wiki. You can allow yourself to as many helpers and resources as you find challenging: with each problem you should either find out you know the solution or learn something new while solving it.
2022-01-01 03:11:00 +01:00
1. What's the difference between [free software](free_software.md) and [open source](open_source.md)?
2021-12-31 23:56:32 +01:00
2. Write a program in [C](c.md) that computes the value of [pi](pi.md) without using float/double and any libraries except for `stdio.h` and `stdint.h` -- you can only use built-in integer types and those from `stdint.h`. The program must compute pi as accurately as possible (at least 2 decimals) and write the value out as base 10 decimal.
2022-01-01 03:11:00 +01:00
3. Say we have an algorithm that finds all pairs of equal numbers in an array of numbers of length *N* and adds all of these (unordered) pairs to a set *S*. The algorithm is: `for i := 0 to N: for j := 0 to N: if numbers[i] == numbers[j]: add(S,set(i,j))`. How can we optimize the algorithm in terms of its execution speed (i.e. make it perform fewer operations)? How did the asymptotic time complexity ("big O") class change?
2022-01-15 06:55:13 +01:00
4. In computer graphics, what is the difference between ray casting, ray tracing and path tracing?
2022-01-01 03:11:00 +01:00
2021-12-31 23:56:32 +01:00
## Solutions
A solution to each problem should be listed here -- keep in mind there may exist other solutions that those listed here.
**solution 1**:
2022-01-01 03:11:00 +01:00
Both movements share very similar rules of licensing and technically free software and open-source are largely the same. However, free software is fundamentally aiming for the creation ethical software -- that which respects its user's freedom -- while open source is a later movement that tries to adapt free software for the business and abandons the pursuit of ethics.
2021-12-31 23:56:32 +01:00
**solution 2**:
```
#include <stdio.h>
#include <stdint.h>
#define DECIMALS 10000
int main(void)
{
int64_t previousError = 10000000000;
uint64_t previousPi = 0;
for (uint64_t gridSize = 2; gridSize < 200000; gridSize *= 2)
{
/* We'll sample a grid of points and count those that fall inside the
circle with radius of gridSize. Thanks to the 8-symmtery of a circle we
only sample the 1/8th of the plane. */
uint64_t inCircle = 0;
for (int y = 0; y < gridSize; ++y)
for (int x = y; x <= gridSize; ++x)
if ((x * x + y * y) / gridSize <= gridSize) // if distance is < radius
inCircle++; // count the point
// compute pi from the formula for circle area (area = 2 * pi * r):
uint64_t pi = (inCircle * 8 * DECIMALS) / (gridSize * gridSize);
int64_t error = pi - previousPi;
if (error < 0)
error *= -1;
if (error > previousError) // error got bigger due to overflows, stop
{
puts("that's it");
break;
}
previousError = error;
previousPi = pi;
printf("%d.%d\n",pi / DECIMALS,pi % DECIMALS);
}
}
2022-01-01 03:11:00 +01:00
```
**solution 3**:
In the given algorithm we compare all numbers twice. This can be avoided by not comparing a number to previous numbers in the array (because these have already been compared). Additionally we don't have to compare the same number to itself, a number will always be equal to itself:
```
for i := 0 to N:
add(S,i,i) // no need to compare
for i := 0 to N:
for j := i + 1 to N:
if numbers[i] == numbers[j]:
add(S,set(i,j))
```
2022-01-15 06:55:13 +01:00
While the first algorithm performs N^2 comparisons, the new one only needs N - 1 + N - 2 + N - 3 + ... ~= N * N / 2 = N^2 / 2 comparisons. Even though the new version is always twice as fast, its time complexity class remains the same, that is O(N^2).
**solution 4**:
They are all image-order methods of 3D [rendering](rendering.md). [Ray casting](ray_casting.md) casts a single ray for each screen pixel and determines the pixel color from a single hit of the ray. [Ray tracing](ray_tracing.md) is a [recursive](recursion.md) form of ray casting -- it recursively spawns secondary rays from the first hit to more accurately determine the pixel color, allowing for effects such as shadows, reflections or refractions. Path tracing is a method also based on casting rays, but except for the primary rays the rays are cast at random (i.e. it is a [Monte Carlo](monte_carlo.md) method) to approximately solve the rendering equation, progressively computing a more accurate version of the image (i.e. the image contains significant noise at the beginning which lowers with more iterations performed) -- this allows computing [global illumination](global_illumination.md), i.e. a very realistic lighting that the two previous methods can't achieve.