This commit is contained in:
Miloslav Ciz 2022-03-07 14:02:19 +01:00
parent 4c73283f7c
commit 2358418fd2
5 changed files with 11 additions and 59 deletions

View file

@ -3,9 +3,8 @@
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.
1. What's the difference between [free software](free_software.md) and [open source](open_source.md)?
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.
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?
4. In computer graphics, what is the difference between ray casting, ray tracing and path tracing?
2. 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,pair(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?
3. In computer graphics, what is the difference between ray casting, ray tracing and path tracing?
## Solutions
@ -18,54 +17,6 @@ Both movements share very similar rules of licensing and technically free softwa
**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);
}
}
```
**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:
```
@ -75,11 +26,11 @@ for i := 0 to N:
for i := 0 to N:
for j := i + 1 to N:
if numbers[i] == numbers[j]:
add(S,set(i,j))
add(S,pair(i,j))
```
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**:
**solution 3**:
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.