This commit is contained in:
Miloslav Ciz 2024-08-31 14:44:45 +02:00
parent 124b9d1e7c
commit 3f374a4713
85 changed files with 2281 additions and 2272 deletions

View file

@ -65,9 +65,9 @@ Let's take a look at a simple polygonal 3D model. The following is a primitive,
``` ```
I I
.:.. .:..
.' :':::.. .' :':::..
_-' H.' '. ''-. _-' H.' '. ''-.
.' .:...'.......''..G .' .:...'.......''..G
.' ...'' : '. ..' : .' ...'' : '. ..' :
.::''......:.....'.-'' : .::''......:.....'.-'' :
@ -75,7 +75,7 @@ Let's take a look at a simple polygonal 3D model. The following is a primitive,
: : : : : : : :
: : : : : : : :
: :......:.......: : :......:.......:
: .' D : .' C : .' D : .' C
: .'' : -' : .'' : -'
: .'' : .' : .'' : .'
::'...............:' ::'...............:'
@ -105,7 +105,7 @@ AFB AEF (front wall)
BGC BFG (right wall) BGC BFG (right wall)
CGH CHD (back wall) CGH CHD (back wall)
DHE DEA (left wall) DHE DEA (left wall)
EIF FIG GIH HIE (roof) EIF FIG GIH HIE (roof)
``` ```
We see the model consists of 9 vertices and 14 triangles. Notice that the order in which we specify triangles follows the rule that looking at the front side of the triangle its vertices are specified clockwise (or counterclockwise, depending on chosen convention) -- sometimes this may not matter, but many 3D engines perform so called [backface culling](backface_culling.md), i.e. they only draw the front faces and there some faces would be invisible from the outside if their winding was incorrect, so it's better to stick to the rule if possible. We see the model consists of 9 vertices and 14 triangles. Notice that the order in which we specify triangles follows the rule that looking at the front side of the triangle its vertices are specified clockwise (or counterclockwise, depending on chosen convention) -- sometimes this may not matter, but many 3D engines perform so called [backface culling](backface_culling.md), i.e. they only draw the front faces and there some faces would be invisible from the outside if their winding was incorrect, so it's better to stick to the rule if possible.
@ -230,7 +230,7 @@ OK, back to the mainstream now. Nowadays as a [FOSS](foss.md) user you will most
- A 3D renderer will draw the triangles the model consists of by applying **[shading](shading.md)** to determine color of each [pixel](pixel.md) of the [rasterized](rasterization.md) triangle. Shading takes into account besides others texture(s) of the model, its material properties and light falling on the model (in which the model normals play a big role). Shading can be modified by creating **[shaders](shader.md)** (if you don't create custom shaders, some default one will be used). - A 3D renderer will draw the triangles the model consists of by applying **[shading](shading.md)** to determine color of each [pixel](pixel.md) of the [rasterized](rasterization.md) triangle. Shading takes into account besides others texture(s) of the model, its material properties and light falling on the model (in which the model normals play a big role). Shading can be modified by creating **[shaders](shader.md)** (if you don't create custom shaders, some default one will be used).
- Briefly learn about other concepts such as low/high poly modeling and basic **3D formats** such as [OBJ](obj.md) and [COLLADA](collada.md) (which features they support etc.), possible other models representations ([voxels](voxel.md), [point clouds](point_cloud.md), ...) etc. - Briefly learn about other concepts such as low/high poly modeling and basic **3D formats** such as [OBJ](obj.md) and [COLLADA](collada.md) (which features they support etc.), possible other models representations ([voxels](voxel.md), [point clouds](point_cloud.md), ...) etc.
2. **Manually create a few extremely simple [low-poly](low_poly.md) untextured models**, e.g. that of a simple house, laptop, hammer, bottle etc. Keep the vertex and triangle count very low (under 100), make the model by MANUALLY creating every vertex and triangle and focus only on learning this low level geometry manipulation well (how to create a vertex, how to split an edge, how to rotate a triangle, ...), making the model conform to good practice and get familiar with tools you're using, i.e. learn the key binds, locking movement direction to principal axes, learn manipulating your 3D view, setting up the free/side/front/top view with reference images etc. Make the model nice! I.e. make it have correctly facing triangles (turn [backface culling](backface_culling.md) on to check this), avoid intersecting triangles, unnecessary triangles and vertices, remove all duplicate vertices (don't have multiple vertices with the same position), connect all that should be connected, avoid badly shaped triangles (e.g. extremely acute/long ones) etc. Keep the triangle count as low as possible, remember, **there always has to be a very good reason to add a triangle** -- there must be no triangle at all whose purpose is not justified, i.e. which is not absolutely necessary to achieve something about the model's look. If you can take the triangle away and still make the model look more or less the same, the triangle must be taken away. Also learn about normals and make them nice! I.e. try automatic normal generation (fiddle e.g. with angle thresholds for sharp/smooth edges), see how they affect the model look, try manually marking some edges sharp, try out smoothing groups etc. Save your final models in OBJ format (one of the simplest and most common formats supporting all you need at this stage). All this will be a lot to learn, that's why you must not try to create a complex model at this stage. You can keep yourself "motivated" e.g. by aiming for creating a low-poly model collection you can share at opengameart or somewhere :) 2. **Manually create a few extremely simple [low-poly](low_poly.md) untextured models**, e.g. that of a simple house, laptop, hammer, bottle etc. Keep the vertex and triangle count very low (under 100), make the model by MANUALLY creating every vertex and triangle and focus only on learning this low level geometry manipulation well (how to create a vertex, how to split an edge, how to rotate a triangle, ...), making the model conform to good practice and get familiar with tools you're using, i.e. learn the key binds, locking movement direction to principal axes, learn manipulating your 3D view, setting up the free/side/front/top view with reference images etc. Make the model nice! I.e. make it have correctly facing triangles (turn [backface culling](backface_culling.md) on to check this), avoid intersecting triangles, unnecessary triangles and vertices, remove all duplicate vertices (don't have multiple vertices with the same position), connect all that should be connected, avoid badly shaped triangles (e.g. extremely acute/long ones) etc. Keep the triangle count as low as possible, remember, **there always has to be a very good reason to add a triangle** -- there must be no triangle at all whose purpose is not justified, i.e. which is not absolutely necessary to achieve something about the model's look. If you can take the triangle away and still make the model look more or less the same, the triangle must be taken away. Also learn about normals and make them nice! I.e. try automatic normal generation (fiddle e.g. with angle thresholds for sharp/smooth edges), see how they affect the model look, try manually marking some edges sharp, try out smoothing groups etc. Save your final models in OBJ format (one of the simplest and most common formats supporting all you need at this stage). All this will be a lot to learn, that's why you must not try to create a complex model at this stage. You can keep yourself "motivated" e.g. by aiming for creating a low-poly model collection you can share at opengameart or somewhere :)
3. **Learn texturing** -- just take the models you have and try to put a simple texture on them by drawing a simple image, then unwrapping the UV coordinates and MANUALLY editing the UV map to fit on the model. Again the goal is to get familiar with the tools and concepts now; experiment with helpers such as unwrapping by "projecting from 3D view", using "smart" UV unwrap etc. Make the UV map nice! Just as model geometry, UV maps also have good practice -- e.g. you should utilize as many texture pixels as possible (otherwise you're wasting space in the image), watch out for [color bleeding](color_bleeding.md), the mapping should have kind of "uniform pixel density" (or possibly increased density on triangles where more details is supposed to be), some pixels of the texture may be mapped to multiple triangles if possible (to efficiently utilize them) etc. Only make a simple diffuse texture (don't do [PBR](pbr.md), material textures etc., that's too advanced now). Try out texture painting and manual texture creation in a 2D image program, get familiar with both. 3. **Learn texturing** -- just take the models you have and try to put a simple texture on them by drawing a simple image, then unwrapping the UV coordinates and MANUALLY editing the UV map to fit on the model. Again the goal is to get familiar with the tools and concepts now; experiment with helpers such as unwrapping by "projecting from 3D view", using "smart" UV unwrap etc. Make the UV map nice! Just as model geometry, UV maps also have good practice -- e.g. you should utilize as many texture pixels as possible (otherwise you're wasting space in the image), watch out for [color bleeding](color_bleeding.md), the mapping should have kind of "uniform pixel density" (or possibly increased density on triangles where more details is supposed to be), some pixels of the texture may be mapped to multiple triangles if possible (to efficiently utilize them) etc. Only make a simple diffuse texture (don't do [PBR](pbr.md), material textures etc., that's too advanced now). Try out texture painting and manual texture creation in a 2D image program, get familiar with both.
4. **Learn modifiers and advanced tools**. Modifiers help you e.g. with the creation of symmetric models: you only model one side and the other one gets mirrored. Subdivide modifier will automatically create a higher poly version of your model (but you need to help it by telling it which sides are sharp etc.). [Boolean](bool.md) operations allow you to apply set operations like unification or subtraction of shapes (but usually create a messy geometry you have to repair!). There are many tools, experiment and learn about their pros and cons, try to incorporate them to your modeling. 4. **Learn modifiers and advanced tools**. Modifiers help you e.g. with the creation of symmetric models: you only model one side and the other one gets mirrored. Subdivide modifier will automatically create a higher poly version of your model (but you need to help it by telling it which sides are sharp etc.). [Boolean](bool.md) operations allow you to apply set operations like unification or subtraction of shapes (but usually create a messy geometry you have to repair!). There are many tools, experiment and learn about their pros and cons, try to incorporate them to your modeling.
5. **Learn retopology and possibly sculpting**. Topology is an extremely important concept -- it says what the structure of triangles/polygons is, how they are distributed, how they are connected, which curves their edges follow etc. Good topology has certain rules (e.g. ideally only being composed of quads, being denser where the shape has more detail and sparser where it's flat, having edges so that animation won't deform the model badly etc.). Topology is important for efficiency (you utilize your polygon budget well), texturing and especially animation (nice deformation of the model). Creating more complex models is almost always done in the following two steps: 5. **Learn retopology and possibly sculpting**. Topology is an extremely important concept -- it says what the structure of triangles/polygons is, how they are distributed, how they are connected, which curves their edges follow etc. Good topology has certain rules (e.g. ideally only being composed of quads, being denser where the shape has more detail and sparser where it's flat, having edges so that animation won't deform the model badly etc.). Topology is important for efficiency (you utilize your polygon budget well), texturing and especially animation (nice deformation of the model). Creating more complex models is almost always done in the following two steps:
- Creating the shape while ignoring topology, for example with sculpting (but also other techniques, e.g. just throwing shapes together). The goal is to just make the desired shape. - Creating the shape while ignoring topology, for example with sculpting (but also other techniques, e.g. just throwing shapes together). The goal is to just make the desired shape.
@ -253,4 +253,4 @@ So finally let's recount some of the advice:
- [KEEP IT SIMPLE](kiss.md). Use only one diffuse texture if it's [good enough](good_enough.md), bake everything in it, don't use 10 PBR texture just because your engine supports it and your favorite jewtuber says that it's "[modern](modern.md)". Use vertex morphing animation instead of armature, you basically never NEED armatures/skeletal animation. And so on. - [KEEP IT SIMPLE](kiss.md). Use only one diffuse texture if it's [good enough](good_enough.md), bake everything in it, don't use 10 PBR texture just because your engine supports it and your favorite jewtuber says that it's "[modern](modern.md)". Use vertex morphing animation instead of armature, you basically never NEED armatures/skeletal animation. And so on.
- ... - ...
Good luck with your modeling! Good luck with your modeling!

View file

@ -137,7 +137,7 @@ void clearScreen(void)
} }
// Draws point to 2D ASCII screen, [0,0] means center. // Draws point to 2D ASCII screen, [0,0] means center.
int drawPoint2D(int x, int y, char c) int drawPoint2D(int x, int y, char c)
{ {
x = SCREEN_W / 2 + x; x = SCREEN_W / 2 + x;
y = SCREEN_H / 2 + y; y = SCREEN_H / 2 + y;
@ -587,4 +587,4 @@ So the rasterization algorithm just shits out individual pixels and hands them o
- [3d modeling](3d_model.md) - [3d modeling](3d_model.md)
- [software rendering](sw_rendering.md) - [software rendering](sw_rendering.md)
- [autostereogram](autostereogram.md) - [autostereogram](autostereogram.md)

View file

@ -10,13 +10,13 @@ Smith was formed as a failed alchemist experiment in 18th century when some mad
_______ _______
_.",,----.'. _.",,----.'.
[o )/ ( X)\ \ [o )/ ( X)\ \
__-' / | __-' / |
(__o__O_) | | _...._ (__o__O_) | | _...._
.-""./ /_________ ( | / .--. '. .-""./ /_________ ( | / .--. '.
| /"\ [_|_|_|___\ \ "\ (__) ) | | /"\ [_|_|_|___\ \ "\ (__) ) |
| \__/ (".____ :\ ''-..-' .' | \__/ (".____ :\ ''-..-' .'
'.__.'( '._______.- '.._____.--' '.__.'( '._______.- '.._____.--'
/ "-._______--' / "-._______--'
(_ ___.' (_ ___.'
``` ```
@ -32,4 +32,4 @@ Smith was formed as a failed alchemist experiment in 18th century when some mad
- [evil](evil.md) - [evil](evil.md)
- [stupidity](stupidity.md) - [stupidity](stupidity.md)
- [shit](shit.md) - [shit](shit.md)
- [hitler](hitler.md) - [hitler](hitler.md)

View file

@ -8,7 +8,7 @@ A simple example showing how sampling at discrete points can quite dramatically
``` ```
| .|-'-'.' ' .--. | |'''' | .|-'-'.' ' .--. | |''''
| . ' | ' . .' '. | | | . ' | ' . .' '. | |
'|- - -O+ - -O- - .| | O O | '---+---. '|- - -O+ - -O- - .| | O O | '---+---.
| \|_ _ / || | \__/ | | | | \|_ _ / || | \__/ | | |
_ _'_._ | . '| '. .' ____| | _ _'_._ | . '| '. .' ____| |
@ -19,7 +19,7 @@ _ _'_._ | . '| '. .' ____| |
The following diagram shows the principle of aliasing with a mathematical function: The following diagram shows the principle of aliasing with a mathematical function:
``` ```
^ original sampling period ^ original sampling period
| | | |<------------->| | | | |<------------->|
| | _ | _ | _ | | | _ | _ | _ |
| .'|'. .' '| .' '. | .' '. | | .'|'. .' '| .' '. | .' '. |
@ -35,9 +35,9 @@ V : : : :
|---o---...____ : : : |---o---...____ : : :
| | '''''o...____ : : | | '''''o...____ : :
|___|_______________|______ ''''----o_______________:___ |___|_______________|______ ''''----o_______________:___
| '''----___ | | '''----___ |
| ''''o--- | ''''o---
| reconstructed | reconstructed
| |
V V
``` ```
@ -58,4 +58,4 @@ The same thing may happen in [ray tracing](ray_tracing.md) if we shoot a single
**Why doesn't aliasing happen in our eyes and ears?** Because our senses don't sample the world discretely, i.e. in single points -- our senses [integrate](integration.md). E.g. a rod or a cone in our eyes doesn't just see exactly one point in the world but rather an averaged light over a small area (which is ideally right next to another small area seen by another cell, so there is no information to "hide" in between them), and it also doesn't sample the world at specific moments like cameras do, its excitation by light falls off gradually which averages the light over time, preventing temporal aliasing (instead of aliasing we get [motion blur](motion_blur.md)). Also our brain does a lot of filtering and postprocessing of the raw input, what we see is not really what comes out of the retina, so EVEN IF there was a bit of aliasing here and there (because of some blind spots or something maybe?), the brain would probably learn to filter it out with "AI-style" magic, just like it filters out noise in low light conditions and so on. **Why doesn't aliasing happen in our eyes and ears?** Because our senses don't sample the world discretely, i.e. in single points -- our senses [integrate](integration.md). E.g. a rod or a cone in our eyes doesn't just see exactly one point in the world but rather an averaged light over a small area (which is ideally right next to another small area seen by another cell, so there is no information to "hide" in between them), and it also doesn't sample the world at specific moments like cameras do, its excitation by light falls off gradually which averages the light over time, preventing temporal aliasing (instead of aliasing we get [motion blur](motion_blur.md)). Also our brain does a lot of filtering and postprocessing of the raw input, what we see is not really what comes out of the retina, so EVEN IF there was a bit of aliasing here and there (because of some blind spots or something maybe?), the brain would probably learn to filter it out with "AI-style" magic, just like it filters out noise in low light conditions and so on.
So all in all, **how to prevent aliasing?** As said above, we always try to satisfy the sampling theorem, i.e. make our sampling frequency at least twice as high as the highest frequency in the signal we're sampling, or at least get close to this situation and lower the probability of aliasing. This can be done by either increasing sampling frequency (which can be done smart, some methods try to detect where sampling should be denser), or by preprocessing the input signal with a low pass filter or otherwise ensure there won't be too high frequencies (e.g. using lower resolution textures). So all in all, **how to prevent aliasing?** As said above, we always try to satisfy the sampling theorem, i.e. make our sampling frequency at least twice as high as the highest frequency in the signal we're sampling, or at least get close to this situation and lower the probability of aliasing. This can be done by either increasing sampling frequency (which can be done smart, some methods try to detect where sampling should be denser), or by preprocessing the input signal with a low pass filter or otherwise ensure there won't be too high frequencies (e.g. using lower resolution textures).

View file

@ -138,14 +138,12 @@ ASCII was approved as an [ANSI](ansi.md) standard in 1963 and since then underwe
| 125 | 7d | 175 | 1111101 | | `}` | | 125 | 7d | 175 | 1111101 | | `}` |
| 126 | 7e | 176 | 1111110 | | `~` | | 126 | 7e | 176 | 1111110 | | `~` |
| 127 | 7f | 177 | 1111111 | \\177 ^? | DEL | | 127 | 7f | 177 | 1111111 | \\177 ^? | DEL |
## See Also ## See Also
- [Unicode](unicode.md) - [Unicode](unicode.md)
- [PETSCII](petscii.md) - [PETSCII](petscii.md)
- [ATASCII](atascii.md) - [ATASCII](atascii.md)
- [ASCII art](ascii_art.md) - [ASCII art](ascii_art.md)
- [base64](base64.md) - [base64](base64.md)
- [Morse code](morse_code.md) - [Morse code](morse_code.md)

View file

@ -8,7 +8,7 @@ Arcus tangent, written as *atan* or *tan^-1*, is the inverse [function](function
``` ```
| y | y
pi/2 + pi/2 +
| _..---'''''' | _..---''''''
| _.'' | _.''
| .' | .'
@ -20,4 +20,4 @@ Arcus tangent, written as *atan* or *tan^-1*, is the inverse [function](function
| |
``` ```
*plot of atan(x)* *plot of atan(x)*

View file

@ -50,25 +50,25 @@ The following is a [C](c.md) program that generates the above image.
char patternSeed[PATTERN_SEED_SIZE] = " .:,oX#r-'/=*miQ)35;_0p]w@x4EY!{"; char patternSeed[PATTERN_SEED_SIZE] = " .:,oX#r-'/=*miQ)35;_0p]w@x4EY!{";
char depth[RES_X * RES_Y + 1] = // must be big and simple to be easily seen char depth[RES_X * RES_Y + 1] = // must be big and simple to be easily seen
" " " "
" " " "
" " " "
" 1111111111111 " " 1111111111111 "
" 11111111111 22222222222222222 " " 11111111111 22222222222222222 "
" 1111111 222222222222222222 1111111111 " " 1111111 222222222222222222 1111111111 "
" 1111111 2222222 2222222 1111111111111111 " " 1111111 2222222 2222222 1111111111111111 "
" 1111111 2222222 222222 11111111 111111 " " 1111111 2222222 222222 11111111 111111 "
" 1111111 2222222 222222 1111111 111111 " " 1111111 2222222 222222 1111111 111111 "
" 1111111 2222222 2222222 11111111 " " 1111111 2222222 2222222 11111111 "
" 1111111 2222222222222222 111111111111 " " 1111111 2222222222222222 111111111111 "
" 1111111 11 2222222222222222 111111111111 " " 1111111 11 2222222222222222 111111111111 "
" 1111111 11 2222222 222222 111111111 " " 1111111 11 2222222 222222 111111111 "
" 1111111 1111 2222222 222222 1111111 11111111 " " 1111111 1111 2222222 222222 1111111 11111111 "
" 1111111111111111111 2222222 222222 1111111 1111111 " " 1111111111111111111 2222222 222222 1111111 1111111 "
" 11111111111111111111 22222222 2222222 11111111 11111111 " " 11111111111111111111 22222222 2222222 11111111 11111111 "
" 2222222222 22222222 1111111111111111111 " " 2222222222 22222222 1111111111111111111 "
" 1111111111111 " " 1111111111111 "
" " " "
" "; " ";
char buffer1[PATTERN_SIZE + 1]; char buffer1[PATTERN_SIZE + 1];
@ -100,7 +100,7 @@ int main(void)
if (i % PATTERN_SIZE == 0) if (i % PATTERN_SIZE == 0)
{ {
printf("%s",lineCurrent); // print the rendered line printf("%s",lineCurrent); // print the rendered line
char *tmp = lineCurrent; // swap previous and current buffer char *tmp = lineCurrent; // swap previous and current buffer
lineCurrent = linePrev; lineCurrent = linePrev;
linePrev = tmp; linePrev = tmp;
@ -117,4 +117,4 @@ int main(void)
return 0; return 0;
} }
``` ```

View file

@ -5,8 +5,8 @@ Bilinear interpolation (also bilinear filtering) is a simple way of creating a s
Why is it named *bilinear*? Probably because it's doing linear interpolation twice: once in *X* direction, then in *Y* direction. Why is it named *bilinear*? Probably because it's doing linear interpolation twice: once in *X* direction, then in *Y* direction.
``` ```
####OOOOVVVVaaaaxxxxssssffffllllcccc////!!!!;;;;,,,,....---- ####OOOOVVVVaaaaxxxxssssffffllllcccc////!!!!;;;;,,,,....----
####OOOOVVVVaaaaxxxxxssssffffllllcccc////!!!!;;;;,,,,.....---- ####OOOOVVVVaaaaxxxxxssssffffllllcccc////!!!!;;;;,,,,.....----
####OOOOVVVVaaaaaxxxxssssfffflllllcccc////!!!!!;;;;,,,,....----- ####OOOOVVVVaaaaaxxxxssssfffflllllcccc////!!!!!;;;;,,,,....-----
###OOOOOVVVVaaaaaxxxxsssssfffflllllcccc////!!!!!;;;;,,,,,....--- ###OOOOOVVVVaaaaaxxxxsssssfffflllllcccc////!!!!!;;;;,,,,,....---
###OOOOVVVVVaaaaaxxxxsssssfffffllllccccc/////!!!!!;;;;,,,,,..... ###OOOOVVVVVaaaaaxxxxsssssfffffllllccccc/////!!!!!;;;;,,,,,.....
@ -74,7 +74,7 @@ int interpolateBilinear(int topLeft, int topRight, int bottomLeft, int bottomRig
int x, int y) int x, int y)
{ {
#define FPP 16 // we'll use fixed point to prevent rounding errors #define FPP 16 // we'll use fixed point to prevent rounding errors
#if 1 // switch between the two versions, should give same results: #if 1 // switch between the two versions, should give same results:
// horizontal first, then vertical // horizontal first, then vertical
int a = interpolateLinear(topLeft * FPP,topRight * FPP,x); int a = interpolateLinear(topLeft * FPP,topRight * FPP,x);
@ -97,7 +97,7 @@ int main(void)
putchar('\n'); putchar('\n');
} }
return 0; return 0;
} }
``` ```

View file

@ -56,7 +56,7 @@ One of a very frequent questions you may hear a noob ask is **"How can bloat lim
``` ```
external external
"richness" "richness"
A A
shiny | : : shiny | : :
bullshit | NO : YES : NO bullshit | NO : YES : NO
| : : ____... . | : : ____... .
@ -194,4 +194,4 @@ The concept of bloat can be applied even outside the computing world, e.g. to no
- [obscurity](obscurity.md) - [obscurity](obscurity.md)
- [shit](shit.md) - [shit](shit.md)
- [cyclomatic complexity](cyclomatic_complexity.md) - [cyclomatic complexity](cyclomatic_complexity.md)
- [freedom distance](freedom_ditance.md) - [freedom distance](freedom_ditance.md)

View file

@ -50,7 +50,7 @@ int main(void)
unsigned int cell = 0; unsigned int cell = 0;
const char *i = program; const char *i = program;
int bDir, bCount; int bDir, bCount;
while (*i != 0) while (*i != 0)
{ {
switch (*i) switch (*i)
@ -68,28 +68,28 @@ int main(void)
bDir = (*i == '[') ? 1 : -1; bDir = (*i == '[') ? 1 : -1;
bCount = 0; bCount = 0;
while (1) while (1)
{ {
if (*i == '[') if (*i == '[')
bCount += bDir; bCount += bDir;
else if (*i == ']') else if (*i == ']')
bCount -= bDir; bCount -= bDir;
if (bCount == 0) if (bCount == 0)
break; break;
i += bDir; i += bDir;
} }
break; break;
default: break; default: break;
} }
i++; i++;
} }
return 0; return 0;
} }
``` ```

View file

@ -242,12 +242,12 @@ And the bytecode we get (e.g. with `python -m dis program.py`):
12 LOAD_NAME 2 (raw_input) 12 LOAD_NAME 2 (raw_input)
15 CALL_FUNCTION 0 15 CALL_FUNCTION 0
18 LOAD_CONST 1 (0) 18 LOAD_CONST 1 (0)
21 BINARY_SUBSCR 21 BINARY_SUBSCR
22 CALL_FUNCTION 1 22 CALL_FUNCTION 1
25 LOAD_NAME 1 (ord) 25 LOAD_NAME 1 (ord)
28 LOAD_CONST 2 ('0') 28 LOAD_CONST 2 ('0')
31 CALL_FUNCTION 1 31 CALL_FUNCTION 1
34 BINARY_SUBTRACT 34 BINARY_SUBTRACT
35 STORE_NAME 3 (n) 35 STORE_NAME 3 (n)
8 38 SETUP_LOOP 43 (to 84) 8 38 SETUP_LOOP 43 (to 84)
@ -255,15 +255,15 @@ And the bytecode we get (e.g. with `python -m dis program.py`):
44 POP_JUMP_IF_FALSE 83 44 POP_JUMP_IF_FALSE 83
9 47 LOAD_NAME 3 (n) 9 47 LOAD_NAME 3 (n)
50 PRINT_ITEM 50 PRINT_ITEM
51 PRINT_NEWLINE 51 PRINT_NEWLINE
11 52 LOAD_NAME 3 (n) 11 52 LOAD_NAME 3 (n)
55 LOAD_CONST 3 (1) 55 LOAD_CONST 3 (1)
58 COMPARE_OP 2 (==) 58 COMPARE_OP 2 (==)
61 POP_JUMP_IF_FALSE 68 61 POP_JUMP_IF_FALSE 68
12 64 BREAK_LOOP 12 64 BREAK_LOOP
65 JUMP_FORWARD 0 (to 68) 65 JUMP_FORWARD 0 (to 68)
14 >> 68 LOAD_NAME 0 (next) 14 >> 68 LOAD_NAME 0 (next)
@ -271,11 +271,11 @@ And the bytecode we get (e.g. with `python -m dis program.py`):
74 CALL_FUNCTION 1 74 CALL_FUNCTION 1
77 STORE_NAME 3 (n) 77 STORE_NAME 3 (n)
80 JUMP_ABSOLUTE 41 80 JUMP_ABSOLUTE 41
>> 83 POP_BLOCK >> 83 POP_BLOCK
>> 84 LOAD_CONST 4 (None) >> 84 LOAD_CONST 4 (None)
87 RETURN_VALUE 87 RETURN_VALUE
``` ```
TODO: make sense of it and analyze it TODO: make sense of it and analyze it
TODO: web assembly TODO: web assembly

12
c.md
View file

@ -45,9 +45,9 @@ void printDivisorTree(unsigned int x)
if (b <= a) if (b <= a)
break; break;
} }
putchar('('); putchar('(');
if (a > 1) if (a > 1)
{ {
printDivisorTree(a); printDivisorTree(a);
@ -55,8 +55,8 @@ void printDivisorTree(unsigned int x)
printDivisorTree(b); printDivisorTree(b);
} }
else else
printf("%d",x); printf("%d",x);
putchar(')'); putchar(')');
} }
@ -66,7 +66,7 @@ int main(void)
{ {
unsigned int number; unsigned int number;
printf("enter a number: "); printf("enter a number: ");
if (scanf("%u",&number) == 1 && number < 1000) if (scanf("%u",&number) == 1 && number < 1000)
{ {
printDivisorTree(number); printDivisorTree(number);
@ -192,7 +192,7 @@ A simple program in C that writes "welcome to C" looks like this:
int main(void) int main(void)
{ {
// this is the main program // this is the main program
puts("welcome to C"); puts("welcome to C");
return 0; // end with success return 0; // end with success

View file

@ -70,7 +70,7 @@ Open your text editor and paste this code:
int main(void) int main(void)
{ {
puts("It works."); puts("It works.");
return 0; return 0;
} }
``` ```
@ -115,7 +115,7 @@ To sum up let's see a general structure of a typical C program. You can just cop
int main(void) int main(void)
{ {
// write commands here // write commands here
return 0; // always the last command return 0; // always the last command
} }
``` ```
@ -138,13 +138,13 @@ Let's see an example.
int main(void) int main(void)
{ {
int myVariable; int myVariable;
myVariable = 5; myVariable = 5;
printf("%d\n",myVariable); printf("%d\n",myVariable);
myVariable = 8; myVariable = 8;
printf("%d\n",myVariable); printf("%d\n",myVariable);
} }
``` ```
@ -247,7 +247,7 @@ The **while** loop is used when we want to repeat something without knowing in a
``` ```
while (x > y) // as long as x is greater than y while (x > y) // as long as x is greater than y
{ {
printf("%d %d\n",x,y); // prints x and y printf("%d %d\n",x,y); // prints x and y
x = x - 1; // decrease x by 1 x = x - 1; // decrease x by 1
y = y * 2; // double y y = y * 2; // double y
@ -296,10 +296,10 @@ Any loop can be exited at any time with a special command called `break`. This i
while (1) // infinite loop while (1) // infinite loop
{ {
x = x - 1; x = x - 1;
if (x == 0) if (x == 0)
break; // this exits the loop! break; // this exits the loop!
y = y / x; y = y / x;
} }
``` ```
@ -320,36 +320,36 @@ With what we've learned so far we can already make a simple [game](game.md): gue
int main(void) int main(void)
{ {
srand(clock()); // random seed srand(clock()); // random seed
while (1) // infinite loop while (1) // infinite loop
{ {
int randomNumber = rand() % 10; int randomNumber = rand() % 10;
puts("I think a number. What is it?"); puts("I think a number. What is it?");
int guess; int guess;
scanf("%d",&guess); // read the guess scanf("%d",&guess); // read the guess
getchar(); getchar();
if (guess == randomNumber) if (guess == randomNumber)
puts("You guessed it!"); puts("You guessed it!");
else else
printf("Wrong. The number was %d.\n",randomNumber); printf("Wrong. The number was %d.\n",randomNumber);
puts("Play on? [y/n]"); puts("Play on? [y/n]");
char answer; char answer;
scanf("%c",&answer); // read the answer scanf("%c",&answer); // read the answer
if (answer == 'n') if (answer == 'n')
break; break;
} }
puts("Bye."); puts("Bye.");
return 0; // return success, always here return 0; // return success, always here
} }
``` ```
@ -431,10 +431,10 @@ Let's see another function:
int power(int x, int n) int power(int x, int n)
{ {
int result = 1; int result = 1;
for (int i = 0; i < n; ++i) // repeat n times for (int i = 0; i < n; ++i) // repeat n times
result = result * x; result = result * x;
return result; return result;
} }
@ -479,7 +479,7 @@ These is the most basic knowledge to have about C functions. Let's see one more
void writeFactors(int x) // writes divisors of x void writeFactors(int x) // writes divisors of x
{ {
printf("factors of %d:\n",x); printf("factors of %d:\n",x);
while (x > 1) // keep dividing x by its factors while (x > 1) // keep dividing x by its factors
{ {
for (int i = 2; i <= x; ++i) // search for a factor for (int i = 2; i <= x; ++i) // search for a factor
@ -495,10 +495,10 @@ void writeFactors(int x) // writes divisors of x
int readNumber(void) int readNumber(void)
{ {
int number; int number;
puts("Please enter a number to factor (0 to quit)."); puts("Please enter a number to factor (0 to quit).");
scanf("%d",&number); scanf("%d",&number);
return number; return number;
} }
@ -510,10 +510,10 @@ int main(void)
if (number == 0) // 0 means quit if (number == 0) // 0 means quit
break; break;
writeFactors(number); // <- function call writeFactors(number); // <- function call
} }
return 0; return 0;
} }
``` ```
@ -588,9 +588,9 @@ void printMoney(void)
void playLottery(void) void playLottery(void)
{ {
puts("I'm playing lottery."); puts("I'm playing lottery.");
money -= 10; // price of lottery ticket money -= 10; // price of lottery ticket
if (rand() % 5) // 1 in 5 chance if (rand() % 5) // 1 in 5 chance
{ {
money += 100; money += 100;
@ -605,7 +605,7 @@ void playLottery(void)
void work(void) void work(void)
{ {
puts("I'm going to work :("); puts("I'm going to work :(");
money += 200; // salary money += 200; // salary
printMoney(); printMoney();
@ -617,7 +617,7 @@ int main()
playLottery(); playLottery();
work(); work();
playLottery(); playLottery();
return 0; return 0;
} }
``` ```
@ -652,22 +652,22 @@ int main(void)
{ {
char c; char c;
float f; float f;
puts("Enter character."); puts("Enter character.");
c = getchar(); // read character c = getchar(); // read character
puts("Enter float."); puts("Enter float.");
scanf("%f",&f); scanf("%f",&f);
printf("Your character is :%c.\n",c); printf("Your character is :%c.\n",c);
printf("Your float is %lf\n",f); printf("Your float is %lf\n",f);
float fSquared = f * f; float fSquared = f * f;
int wholePart = f; // this can be done int wholePart = f; // this can be done
printf("It's square is %lf.\n",fSquared); printf("It's square is %lf.\n",fSquared);
printf("It's whole part is %d.\n",wholePart); printf("It's whole part is %d.\n",wholePart);
return 0; return 0;
} }
``` ```
@ -684,24 +684,24 @@ void printDecorated2(int x, int fancy); // forward declaration
void printDecorated1(int x, int fancy) void printDecorated1(int x, int fancy)
{ {
putchar('~'); putchar('~');
if (fancy) if (fancy)
printDecorated2(x,0); // would be error without f. decl. printDecorated2(x,0); // would be error without f. decl.
else else
printf("%d",x); printf("%d",x);
putchar('~'); putchar('~');
} }
void printDecorated2(int x, int fancy) void printDecorated2(int x, int fancy)
{ {
putchar('>'); putchar('>');
if (fancy) if (fancy)
printDecorated1(x,0); printDecorated1(x,0);
else else
printf("%d",x); printf("%d",x);
putchar('<'); putchar('<');
} }
@ -879,14 +879,14 @@ int bmi(Human human)
int main(void) int main(void)
{ {
Human carl; Human carl;
carl.initial = 'C'; carl.initial = 'C';
carl.weightKg = 100; carl.weightKg = 100;
carl.heightCm = 180; carl.heightCm = 180;
if (bmi(carl) > 25) if (bmi(carl) > 25)
puts("Carl is fat."); puts("Carl is fat.");
return 0; return 0;
} }
``` ```
@ -906,30 +906,30 @@ Another extremely important compound type is **[array](array.md)** -- a sequence
int main(void) int main(void)
{ {
float vector[5]; float vector[5];
vector[0] = 1; vector[0] = 1;
vector[1] = 2.5; vector[1] = 2.5;
vector[2] = 0; vector[2] = 0;
vector[3] = 1.1; vector[3] = 1.1;
vector[4] = -405.054; vector[4] = -405.054;
puts("The vector is:"); puts("The vector is:");
for (int i = 0; i < 5; ++i) for (int i = 0; i < 5; ++i)
printf("%lf ",vector[i]); printf("%lf ",vector[i]);
putchar('\n'); // newline putchar('\n'); // newline
/* compute vector length with /* compute vector length with
pythagoren theorem: */ pythagoren theorem: */
float sum = 0; float sum = 0;
for (int i = 0; i < 5; ++i) for (int i = 0; i < 5; ++i)
sum += vector[i] * vector[i]; sum += vector[i] * vector[i];
printf("Vector length is: %lf\n",sqrt(sum)); printf("Vector length is: %lf\n",sqrt(sum));
return 0; return 0;
} }
``` ```
@ -976,14 +976,14 @@ int main(void)
{ {
int array10[10]; int array10[10];
int array20[20]; int array20[20];
fillArrayN(array10,10); fillArrayN(array10,10);
fillArrayN(array20,20); fillArrayN(array20,20);
printArray10(array10); printArray10(array10);
putchar('\n'); putchar('\n');
printArrayN(array20,20); printArrayN(array20,20);
return 0; return 0;
} }
``` ```
@ -1004,14 +1004,14 @@ The [syntax](syntax.md) that allows us to create strings with double quotes (`"`
int main(void) int main(void)
{ {
char alphabet[27]; // 26 places for letters + 1 for temrinating 0 char alphabet[27]; // 26 places for letters + 1 for temrinating 0
for (int i = 0; i < 26; ++i) for (int i = 0; i < 26; ++i)
alphabet[i] = 'A' + i; alphabet[i] = 'A' + i;
alphabet[26] = 0; // terminate the string alphabet[26] = 0; // terminate the string
puts(alphabet); puts(alphabet);
return 0; return 0;
} }
``` ```
@ -1049,11 +1049,11 @@ void printCreature(Creature c)
int main(void) int main(void)
{ {
// generate random creatures: // generate random creatures:
for (int i = 0; i < 100; ++i) for (int i = 0; i < 100; ++i)
{ {
Creature c; Creature c;
c.name[0] = 'A' + (rand() % 26); c.name[0] = 'A' + (rand() % 26);
c.name[1] = 'a' + (rand() % 26); c.name[1] = 'a' + (rand() % 26);
c.name[2] = 'a' + (rand() % 26); c.name[2] = 'a' + (rand() % 26);
@ -1064,12 +1064,12 @@ int main(void)
creatures[i] = c; creatures[i] = c;
} }
// print the creatures: // print the creatures:
for (int i = 0; i < 100; ++i) for (int i = 0; i < 100; ++i)
printCreature(creatures[i]); printCreature(creatures[i]);
return 0; return 0;
} }
``` ```
@ -1140,9 +1140,9 @@ Macros can optionally take parameters similarly to functions. There are no data
int main() int main()
{ {
int n = MEAN3(10,20,25); int n = MEAN3(10,20,25);
printf("%d\n",n); printf("%d\n",n);
return 0; return 0;
} }
``` ```
@ -1167,7 +1167,7 @@ void printNumber(int x)
"The number is:" "The number is:"
#endif #endif
); );
printf("%d\n",x); printf("%d\n",x);
} }
@ -1175,11 +1175,11 @@ int main()
{ {
printNumber(3); printNumber(3);
printNumber(100); printNumber(100);
#if RUDE #if RUDE
puts("Bye bitch."); puts("Bye bitch.");
#endif #endif
return 0; return 0;
} }
``` ```
@ -1251,16 +1251,16 @@ int main(void)
{ {
int normalVariable = 10; int normalVariable = 10;
int *pointer; int *pointer;
pointer = &normalVariable; pointer = &normalVariable;
printf("address in pointer: %p\n",pointer); printf("address in pointer: %p\n",pointer);
printf("value at this address: %d\n",*pointer); printf("value at this address: %d\n",*pointer);
*pointer = *pointer + 10; *pointer = *pointer + 10;
printf("normalVariable: %d\n",normalVariable); printf("normalVariable: %d\n",normalVariable);
return 0; return 0;
} }
``` ```
@ -1308,13 +1308,13 @@ void buyGas(void)
int main(void) int main(void)
{ {
// let Jose pay first // let Jose pay first
payingAccount = &bankAccountJose; payingAccount = &bankAccountJose;
payBills(); payBills();
buyFood(); buyFood();
buyGas(); buyGas();
// that's enough, now let Monica pay // that's enough, now let Monica pay
payingAccount = &bankAccountMonica; payingAccount = &bankAccountMonica;
@ -1323,20 +1323,20 @@ int main(void)
buyGas(); buyGas();
buyFood(); buyFood();
buyFood(); buyFood();
// now it's Bob's turn // now it's Bob's turn
payingAccount = &bankAccountBob; payingAccount = &bankAccountBob;
payBills(); payBills();
buyFood(); buyFood();
buyFood(); buyFood();
buyGas(); buyGas();
printf("Monika has $%d left.\n",bankAccountMonica); printf("Monika has $%d left.\n",bankAccountMonica);
printf("Jose has $%d left.\n",bankAccountJose); printf("Jose has $%d left.\n",bankAccountJose);
printf("Bob has $%d left.\n",bankAccountBob); printf("Bob has $%d left.\n",bankAccountBob);
return 0; return 0;
} }
``` ```
@ -1361,12 +1361,12 @@ int main(void)
for (int i = 0; i < 8; ++i) for (int i = 0; i < 8; ++i)
{ {
float pointX, pointY; float pointX, pointY;
getUnitCirclePoint(i * 0.125 * 2 * PI,&pointX,&pointY); getUnitCirclePoint(i * 0.125 * 2 * PI,&pointX,&pointY);
printf("%lf %lf\n",pointX,pointY); printf("%lf %lf\n",pointX,pointY);
} }
return 0; return 0;
} }
``` ```
@ -1390,13 +1390,13 @@ SomeStruct *sPointer;
int main(void) int main(void)
{ {
sPointer = &s; sPointer = &s;
(*sPointer).a = 10; // without arrow (*sPointer).a = 10; // without arrow
sPointer->b = 20; // same as (*sPointer).b = 20 sPointer->b = 20; // same as (*sPointer).b = 20
printf("%d\n",s.a); printf("%d\n",s.a);
printf("%d\n",s.b); printf("%d\n",s.b);
return 0; return 0;
} }
``` ```
@ -1418,7 +1418,7 @@ This may be a lot information to digest. Let's provide an example to show all th
void printString(char *s) void printString(char *s)
{ {
int position = 0; int position = 0;
while (s[position] != 0) while (s[position] != 0)
{ {
putchar(s[position]); putchar(s[position]);
@ -1430,26 +1430,26 @@ void printString(char *s)
int stringLength(char *s) int stringLength(char *s)
{ {
int length = 0; int length = 0;
while (*s != 0) // count until terminating 0 while (*s != 0) // count until terminating 0
{ {
length += 1; length += 1;
s += 1; // shift the pointer one character to right s += 1; // shift the pointer one character to right
} }
return length; return length;
} }
int main(void) int main(void)
{ {
char testString[] = "catdog"; char testString[] = "catdog";
printString("The string '"); printString("The string '");
printString(testString); printString(testString);
printString("' has length "); printString("' has length ");
int l = stringLength(testString); int l = stringLength(testString);
printf("%d.",l); printf("%d.",l);
return 0; return 0;
@ -1471,6 +1471,8 @@ Now that know about pointers, we can finally completely explain the functions fr
- `int getchar(void)`: Reads a single text character from the input and returns it. Why does the function return `int` and not `char`? Because the function can return additional special values such as `EOF` (end of file) which couldn't be stored in plain `char`. - `int getchar(void)`: Reads a single text character from the input and returns it. Why does the function return `int` and not `char`? Because the function can return additional special values such as `EOF` (end of file) which couldn't be stored in plain `char`.
- `int scanf(char *format, ...)`: Function for reading various data types from the input. Like `printf` it takes a variable number of parameters. The first one is a string that specifies which data type(s) to read -- this is a bit complicated but "%d" reads an `int`, "%f" `float`, "%c" `char` and "%s" string. The following arguments are **pointers** to expected data types, so e.g. if we've provided the format string "%d", a pointer to `int` has to follow. Through this parameter the value that's been read will be returned (in the same way we've seen in one example above). - `int scanf(char *format, ...)`: Function for reading various data types from the input. Like `printf` it takes a variable number of parameters. The first one is a string that specifies which data type(s) to read -- this is a bit complicated but "%d" reads an `int`, "%f" `float`, "%c" `char` and "%s" string. The following arguments are **pointers** to expected data types, so e.g. if we've provided the format string "%d", a pointer to `int` has to follow. Through this parameter the value that's been read will be returned (in the same way we've seen in one example above).
[Nigger](nigger.md).
## Files ## Files
Now we'll take a look at how we can read and write from/to files on the computer disk which enables us to store information permanently or potentially process data such as images or audio. Files aren't so difficult. Now we'll take a look at how we can read and write from/to files on the computer disk which enables us to store information permanently or potentially process data such as images or audio. Files aren't so difficult.
@ -1547,7 +1549,7 @@ int main(void)
255,255,255, 0, 0, 0, 255,255,255, 0, 0, 0, 255,255,255, 255,255,255, 0, 0, 0, 255,255,255, 0, 0, 0, 255,255,255,
255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255,
0, 0, 0, 255,255,255, 255,255,255, 255,255,255, 0, 0, 0, 0, 0, 0, 255,255,255, 255,255,255, 255,255,255, 0, 0, 0,
255,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,255,255 255,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,255,255
}; };
FILE *binFile = fopen("image.ppm","wb"); FILE *binFile = fopen("image.ppm","wb");
@ -1620,13 +1622,13 @@ unsigned int factorialRecursive(unsigned int x)
unsigned int factorialIterative(unsigned int x) unsigned int factorialIterative(unsigned int x)
{ {
unsigned int result = 1; unsigned int result = 1;
while (x > 1) while (x > 1)
{ {
result *= x; result *= x;
x--; x--;
} }
return result; return result;
} }
@ -1675,21 +1677,21 @@ int main(void)
{ {
inputChars = // we need more space, resize the array inputChars = // we need more space, resize the array
realloc(inputChars,(charsRead / ALLOCATION_CHUNK + 1) * ALLOCATION_CHUNK * sizeof(char)); realloc(inputChars,(charsRead / ALLOCATION_CHUNK + 1) * ALLOCATION_CHUNK * sizeof(char));
resized++; resized++;
} }
inputChars[charsRead - 1] = c; inputChars[charsRead - 1] = c;
if (c == '\n') if (c == '\n')
{ {
charsRead--; // don't count the last newline character charsRead--; // don't count the last newline character
break; break;
} }
} }
puts("The string you entered backwards:"); puts("The string you entered backwards:");
while (charsRead > 0) while (charsRead > 0)
{ {
putchar(inputChars[charsRead - 1]); putchar(inputChars[charsRead - 1]);
@ -1697,10 +1699,10 @@ int main(void)
} }
free(inputChars); // important! free(inputChars); // important!
putchar('\n'); putchar('\n');
printf("I had to resize the input buffer %d times.",resized); printf("I had to resize the input buffer %d times.",resized);
return 0; return 0;
} }
``` ```
@ -1855,7 +1857,7 @@ int main(int argc, char **argv)
case 'w': case 'w':
if (fileOffset >= COLS) if (fileOffset >= COLS)
fileOffset -= COLS; fileOffset -= COLS;
break; break;
case 'a': case 'a':

View file

@ -63,47 +63,47 @@ int main(void)
It outputs the following: It outputs the following:
``` ```
0.000| * 0.000| *
0.098| * 0.098| *
0.195| * 0.195| *
0.293| * 0.293| *
0.391| * 0.391| *
0.488| * 0.488| *
0.586| * 0.586| *
0.684| * 0.684| *
0.781| * 0.781| *
0.879| * 0.879| *
0.977| * 0.977| *
1.074| ***** 1.074| *****
1.172| ** *** 1.172| ** ***
1.270| ** ** 1.270| ** **
1.367| * ** 1.367| * **
1.465| * * 1.465| * *
1.562| * ** 1.562| * **
1.660| * * 1.660| * *
1.758| * * 1.758| * *
1.855| * * 1.855| * *
1.953| * * 1.953| * *
2.051| * * 2.051| * *
2.148| * * 2.148| * *
2.246| * * 2.246| * *
2.344| * * 2.344| * *
2.441| * * 2.441| * *
2.539| * * 2.539| * *
2.637| * * 2.637| * *
2.734| * * 2.734| * *
2.832| * * 2.832| * *
2.930| * ** 2.930| * **
3.027| * ********* 3.027| * *********
3.125| * * * * 3.125| * * * *
3.223| * * * * 3.223| * * * *
3.320| * * ** 3.320| * * **
3.418| * ** * ** 3.418| * ** * **
3.516| * ** * * ** * ***** 3.516| * ** * * ** * *****
3.613| * **** *** * * ** * * * ******** 3.613| * **** *** * * ** * * * ********
3.711| * ** ** ** ***** * ** 3.711| * ** ** ** ***** * **
3.809| * * ** * * * * * * * *** * 3.809| * * ** * * * * * * * *** *
3.906| * * * *** * * * * * *** * 3.906| * * * *** * * * * * *** *
``` ```
Vertical axis is the *r* parameter, i.e. the population growth speed. Horizontal axis shows stable population size after 1000 generations, starting with different initial population sizes. We can see that up until about *r = 3* the stable population size always stabilizes at around the same size, which gradually increases with *r*. However then the line splits and after around *r = 3.56* the stable population sizes are quite spread out and unpredictable, greatly depending on the initial population size. Pure CHAOS! Vertical axis is the *r* parameter, i.e. the population growth speed. Horizontal axis shows stable population size after 1000 generations, starting with different initial population sizes. We can see that up until about *r = 3* the stable population size always stabilizes at around the same size, which gradually increases with *r*. However then the line splits and after around *r = 3.56* the stable population sizes are quite spread out and unpredictable, greatly depending on the initial population size. Pure CHAOS!

View file

@ -1,6 +1,9 @@
#!/bin/sh #!/bin/sh
# Checks for potential errors in articles. # Checks for potential errors in articles.
echo "===== trailing spaces:"
grep -rno " \+$" *.md
echo "===== links not ending in .md:" echo "===== links not ending in .md:"
grep -rno "\[[^]]*\]([^)]*\([^.)][^)][^)]\|[^)][^m)][^)]\|[^)][^)][^d)]\))" *.md grep -rno "\[[^]]*\]([^)]*\([^.)][^)][^)]\|[^)][^m)][^)]\|[^)][^)][^d)]\))" *.md

View file

@ -21,7 +21,7 @@ We can divide computers based on many attributes, e.g.:
______________ ______________
| ________ | \_ | ________ | \_
| |>.. | | : \ || | |>.. | | : \ ||
| | | | : ] |:==-' | | | | : ] |:==-'
| |________| | :_/ ___||___ | |________| | :_/ ___||___
___ |____________|_/'. ___ /########\ ___ |____________|_/'. ___ /########\
/ \ \ \...../ '. / \ \ |""""""""| / \ \ \...../ '. / \ \ |""""""""|
@ -33,7 +33,7 @@ We can divide computers based on many attributes, e.g.:
___________;__ _:_ ___________;__ _:_
/:::::::.::'::/| /-'-) /:::::::.::'::/| /-'-)
/:::::::'.:.::// (___/ /:::::::'.:.::// (___/
""""""""""""""" """""""""""""""
``` ```
*On the left typical personal computer, with case, monitor, keyboard, mouse and speakers; on the right a pocket mechanical calculator of the Curta type.* *On the left typical personal computer, with case, monitor, keyboard, mouse and speakers; on the right a pocket mechanical calculator of the Curta type.*

8
cpp.md
View file

@ -28,7 +28,7 @@ void printDivisorTree(unsigned int x)
} }
cout << '('; cout << '(';
if (a > 1) if (a > 1)
{ {
printDivisorTree(a); printDivisorTree(a);
@ -37,7 +37,7 @@ void printDivisorTree(unsigned int x)
} }
else else
cout << x; cout << x;
cout << ')'; cout << ')';
} }
@ -48,7 +48,7 @@ int main()
unsigned int number; unsigned int number;
cout << "enter a number: " << flush; cout << "enter a number: " << flush;
cin >> number; cin >> number;
if (!cin.fail() && number < 1000) if (!cin.fail() && number < 1000)
{ {
printDivisorTree(number); printDivisorTree(number);
@ -60,4 +60,4 @@ int main()
return 0; return 0;
} }
``` ```

2
cpu.md
View file

@ -62,7 +62,7 @@ TODO: add more, mark CPUs with ME, add features like MMX, FPU, ...
| Intel 8008 |1972 | 8 / 14 | own | 3.5 K | 10 um | 800 K | 18 | 1 | | | | Intel 8008 |1972 | 8 / 14 | own | 3.5 K | 10 um | 800 K | 18 | 1 | | |
| Intel 8080 |1974 | 8 / 16 | own | 6 K | 6 um | 3 M | 40 | 1 | | | | Intel 8080 |1974 | 8 / 16 | own | 6 K | 6 um | 3 M | 40 | 1 | | |
| AMD Am9080 |1975 | 8 / 16 | own | 6 K | 6 um | 4 M | 40 | 1 | | reverse-eng. clone of i8080 | | AMD Am9080 |1975 | 8 / 16 | own | 6 K | 6 um | 4 M | 40 | 1 | | reverse-eng. clone of i8080 |
| MOS Technology 6502 |1975 | 8 / 16 | own | 3.5 K | 8 um | 3 M | 40 | 1 | | popular, cheap, Atari 2600, C64, ... | | MOS Technology 6502 |1975 | 8 / 16 | own | 3.5 K | 8 um | 3 M | 40 | 1 | | popular, cheap, Atari 2600, C64, ... |
| Zilog Z80 |1976 | 8 / 16 | own | 8.5 K | 4 um | 10 M | 40 | 1 | | popular | | Zilog Z80 |1976 | 8 / 16 | own | 8.5 K | 4 um | 10 M | 40 | 1 | | popular |
| Intel 8086 |1978 | 16 / 20 | x86 (x86-16) | 29 K | 3 um | 10 M | 40 | 1 | | started x86 ISA | | Intel 8086 |1978 | 16 / 20 | x86 (x86-16) | 29 K | 3 um | 10 M | 40 | 1 | | started x86 ISA |
| Motorola 68000 |1979 | 32 / 24 | own (CISC) | 68 K | | | 64 | 1 | | popular, e.g. Amiga, Mega Drive, ... | | Motorola 68000 |1979 | 32 / 24 | own (CISC) | 68 K | | | 64 | 1 | | popular, e.g. Amiga, Mega Drive, ... |

View file

@ -1,6 +1,6 @@
# Diogenes # Diogenes
*"The most beautiful thing in the world is freedom of speech."* --Diogenes *"The most beautiful thing in the world is [freedom of speech](free_speech.md)."* --Diogenes
Diogenes (412 BC - 323 BC, not to be confused with the other Diogenes that recorded his life) was one of the biggest, most significant ancient Greek [philosophers](philosophy.md), the best known proponent of [Cynicism](cynicism.md) and one of the absolutely most [based](based.md) men in [history](history.md) as by his philosophy he practiced extreme life [minimalism](minimalism.md) (he lived in a barrel), [asceticism](asceticism.md), self-sufficiency, nonconformism, he refused to [work](work.md), [refused all authority](anarchism.md), criticized absolutely everything and was always extremely [logically](logic.md) consistent and behaved in accordance to what he taught, which is really what makes all his critics -- mostly just big [hypocrite](hypocrisy.md) pussies -- so greatly pissed; the philosophy of Diogenes is quite close to [our own ideals](less_retarded_society.md). The word "cynic" itself comes from a word for "[dog](dog.md)" and indeed, Diogenes lived as one, he just roamed the streets barefoot with a stick, he wore a robe that at night he used to cover himself ([two in one](two_in_one.md)), he didn't give a [shit](shit.md) about anything, preached his [wisdom](wisdom.md), he basically didn't own anything as he believed possession only enslaves us and that everything we need is already there in the nature. He didn't seek [popularity](hero_culture.md), approval, wealth or power, he desired [freedom](freedom.md), spiritual and moral purity, he wanted to let go of absolutely all [bullshit](bullshit.md). The man was also pretty [funny](fun.md), reading about him is really on the level of [4chan](4chan.md) humor, more than 2000 years ahead of his time -- Socrates, Plato and Aristotle wrote pages and pages of boring, serious as fuck walls of text; Diogenes overshadowed them all just with a third party record of his existence. Diogenes wrote some stuff, most famously his *Republic* describing an ideal society, however none of his writings sadly survived, we now only know what others have written about him (there are possibly some recounts of the works who have read them). Let's remember we shouldn't call him a [hero](hero_culture.md), that would itself contradict both his and our philosophy, but if we are to see anyone as a good inspiration and moral example, Diogenes is among the best (well, at least in most things, it goes without saying we can't absolutely embrace everything someone ever did). Diogenes (412 BC - 323 BC, not to be confused with the other Diogenes that recorded his life) was one of the biggest, most significant ancient Greek [philosophers](philosophy.md), the best known proponent of [Cynicism](cynicism.md) and one of the absolutely most [based](based.md) men in [history](history.md) as by his philosophy he practiced extreme life [minimalism](minimalism.md) (he lived in a barrel), [asceticism](asceticism.md), self-sufficiency, nonconformism, he refused to [work](work.md), [refused all authority](anarchism.md), criticized absolutely everything and was always extremely [logically](logic.md) consistent and behaved in accordance to what he taught, which is really what makes all his critics -- mostly just big [hypocrite](hypocrisy.md) pussies -- so greatly pissed; the philosophy of Diogenes is quite close to [our own ideals](less_retarded_society.md). The word "cynic" itself comes from a word for "[dog](dog.md)" and indeed, Diogenes lived as one, he just roamed the streets barefoot with a stick, he wore a robe that at night he used to cover himself ([two in one](two_in_one.md)), he didn't give a [shit](shit.md) about anything, preached his [wisdom](wisdom.md), he basically didn't own anything as he believed possession only enslaves us and that everything we need is already there in the nature. He didn't seek [popularity](hero_culture.md), approval, wealth or power, he desired [freedom](freedom.md), spiritual and moral purity, he wanted to let go of absolutely all [bullshit](bullshit.md). The man was also pretty [funny](fun.md), reading about him is really on the level of [4chan](4chan.md) humor, more than 2000 years ahead of his time -- Socrates, Plato and Aristotle wrote pages and pages of boring, serious as fuck walls of text; Diogenes overshadowed them all just with a third party record of his existence. Diogenes wrote some stuff, most famously his *Republic* describing an ideal society, however none of his writings sadly survived, we now only know what others have written about him (there are possibly some recounts of the works who have read them). Let's remember we shouldn't call him a [hero](hero_culture.md), that would itself contradict both his and our philosophy, but if we are to see anyone as a good inspiration and moral example, Diogenes is among the best (well, at least in most things, it goes without saying we can't absolutely embrace everything someone ever did).

View file

@ -23,7 +23,7 @@ int distTaxi(int x0, int y0, int x1, int y1)
{ {
x0 = x1 > x0 ? x1 - x0 : x0 - x1; // dx x0 = x1 > x0 ? x1 - x0 : x0 - x1; // dx
y0 = y1 > y0 ? y1 - y0 : y0 - y1; // dy y0 = y1 > y0 ? y1 - y0 : y0 - y1; // dy
return x0 + y0; return x0 + y0;
} }
@ -31,7 +31,7 @@ int distCheb(int x0, int y0, int x1, int y1)
{ {
x0 = x1 > x0 ? x1 - x0 : x0 - x1; // dx x0 = x1 > x0 ? x1 - x0 : x0 - x1; // dx
y0 = y1 > y0 ? y1 - y0 : y0 - y1; // dy y0 = y1 > y0 ? y1 - y0 : y0 - y1; // dy
return x0 > y0 ? x0 : y0; return x0 > y0 ? x0 : y0;
} }
``` ```
@ -45,7 +45,7 @@ int dist8(int x0, int y0, int x1, int y1)
{ {
x0 = x1 > x0 ? x1 - x0 : x0 - x1; // dx x0 = x1 > x0 ? x1 - x0 : x0 - x1; // dx
y0 = y1 > y0 ? y1 - y0 : y0 - y1; // dy y0 = y1 > y0 ? y1 - y0 : y0 - y1; // dy
return (x0 + y0 + (x0 > y0 ? x0 : y0)) / 2; return (x0 + y0 + (x0 > y0 ? x0 : y0)) / 2;
} }
``` ```
@ -89,7 +89,7 @@ int32_t dist48(
if (x0 < z0) if (x0 < z0)
{ // y0 < x0 < z0 { // y0 < x0 < z0
int32_t t = y0; y0 = z0; z0 = t; int32_t t = y0; y0 = z0; z0 = t;
t = x0; x0 = y0; y0 = t; t = x0; x0 = y0; y0 = t;
} }
else else
{ // y0 < z0 < x0 { // y0 < z0 < x0
@ -97,7 +97,7 @@ int32_t dist48(
} }
} }
} }
return (893 * x0 + 446 * y0 + 223 * z0) / 1024; return (893 * x0 + 446 * y0 + 223 * z0) / 1024;
} }
``` ```
@ -109,16 +109,16 @@ int dist2DApprox(int x0, int y0, int x1, int y1)
{ {
x0 = x0 > x1 ? (x0 - x1) : (x1 - x0); x0 = x0 > x1 ? (x0 - x1) : (x1 - x0);
y0 = y0 > y1 ? (y0 - y1) : (y1 - y0); y0 = y0 > y1 ? (y0 - y1) : (y1 - y0);
if (x0 < y0) if (x0 < y0)
{ {
x1 = x0; // swap x1 = x0; // swap
x0 = y0; x0 = y0;
y0 = x1; y0 = x1;
} }
return (123 * x0 + 51 * y0) / 128; // max error = ~4% return (123 * x0 + 51 * y0) / 128; // max error = ~4%
//return x0 + y0 / 2; // faster, less accurate //return x0 + y0 / 2; // faster, less accurate
} }
``` ```
@ -126,4 +126,4 @@ TODO: this https://www.flipcode.com/archives/Fast_Approximate_Distance_Functions
## See Also ## See Also
- [freedom distance](freedom_distance.md) - [freedom distance](freedom_distance.md)

View file

@ -28,18 +28,18 @@ int fib(int n)
{ {
if (n < 2) if (n < 2)
return n; return n;
int current = 1, prev = 0; int current = 1, prev = 0;
for (int i = 2; i <= n; ++i) for (int i = 2; i <= n; ++i)
{ {
int tmp = current; int tmp = current;
current += prev; current += prev;
prev = tmp; prev = tmp;
} }
return current; return current;
} }
``` ```
Now the code is longer, but it is faster. In this specific case we only need to remember the previously computed Fibonacci number (in practice we may need much more memory for remembering the partial results). Now the code is longer, but it is faster. In this specific case we only need to remember the previously computed Fibonacci number (in practice we may need much more memory for remembering the partial results).

View file

@ -21,9 +21,9 @@ X v v v v v v v v v v v
\ \_/| -=- OCEAN ) :AFRICA \\_.-" """\ .' \ \_/| -=- OCEAN ) :AFRICA \\_.-" """\ .'
PACIFIC "--._\ \___: "/ \ .""\_ <^,..-" __ PACIFIC "--._\ \___: "/ \ .""\_ <^,..-" __
OCEAN \"""-""-.._ :""\ / " | _) \_\INDONESIA OCEAN \"""-""-.._ :""\ / " | _) \_\INDONESIA
>.............................|..........",.............:...\......./................_\\_....__/\..,__..........< >.............................|..........",.............:...\......./................_\\_....__/\..,__..........<
| SOUTH \ : / | "-._\_ \__/ \ ""-_ | SOUTH \ : / | "-._\_ \__/ \ ""-_
\ AMERICA / : ( } """""===- """""_ \ AMERICA / : ( } """""===- """""_
\_ | : \ \ __.-""._,"", \_ | : \ \ __.-""._,"",
> \ / : / / |\ ," AUSTRALIA \ < > \ / : / / |\ ," AUSTRALIA \ <
| | : \ / \/ INDIAN "; __ ) | | : \ / \/ INDIAN "; __ )
@ -64,4 +64,4 @@ Some numbers about the planet Earth:
"""----""" """----"""
``` ```
*Earth from space* *Earth from space*

View file

@ -32,11 +32,11 @@ Here is a list of notable encyclopedias, focused on general knowledge English la
| Chambers Encyclopedia (new) | 2001 | proprietary | 1 vol. 980p | | 1 vol republication of old multivol. enc. (going back to 1800s, already PD), topic-sorted | | Chambers Encyclopedia (new) | 2001 | proprietary | 1 vol. 980p | | 1 vol republication of old multivol. enc. (going back to 1800s, already PD), topic-sorted |
| Collier's New Encyclopedia | 1921 | PD (old) | 10 vol. | | NOT TO BE CONFUSED with Collier's Encyclopedia (different one), digitized on Wikisource (txt) | | Collier's New Encyclopedia | 1921 | PD (old) | 10 vol. | | NOT TO BE CONFUSED with Collier's Encyclopedia (different one), digitized on Wikisource (txt) |
| Columbia Encyclopedia |1935...| proprietary | 1 vol. ~3Kp | ~50K | high quality, lots of information { Read the 1993 edition, it's super nice. ~drummyfish } | | Columbia Encyclopedia |1935...| proprietary | 1 vol. ~3Kp | ~50K | high quality, lots of information { Read the 1993 edition, it's super nice. ~drummyfish } |
|[Conservaped.](conservapedia.md)|2006...| proprietary | online | 52K | American fascist wiki, has basic factual errors | |[Conservaped.](conservapedia.md)|2006...| proprietary | online | 52K | American fascist wiki, has basic factual errors |
| Larousse Desk Reference Enc. | 1995 | proprietary | 1 vol. 800p | 200K? | by James Hughes, nice, quality general overviews, topic-ordered { I bought this, it's nice. ~drummyfish } | | Larousse Desk Reference Enc. | 1995 | proprietary | 1 vol. 800p | 200K? | by James Hughes, nice, quality general overviews, topic-ordered { I bought this, it's nice. ~drummyfish } |
| Domestic Encyclopaedia | 1802 | PD (old) | 4 vol. | | shorter articles, partially digitized on Wikisource | | Domestic Encyclopaedia | 1802 | PD (old) | 4 vol. | | shorter articles, partially digitized on Wikisource |
| Encyclopedia Americana |1820...| PD (old) | ~30 vol. | | longer articles, one of "Big Three", several editions (1906, 1920) partly digitized on wikisource | | Encyclopedia Americana |1820...| PD (old) | ~30 vol. | | longer articles, one of "Big Three", several editions (1906, 1920) partly digitized on wikisource |
| Encyclopedia Dramatica |2004...| PD (CC0) | online | 15K | informal/fun/"offensive" but valuable info (on society, tech, ...), basically no censorship, no propaganda | | Encyclopedia Dramatica |2004...| PD (CC0) | online | 15K | informal/fun/"offensive" but valuable info (on society, tech, ...), basically no censorship, no propaganda |
| Encyclopedia of Marxism |1999...| CC BY-SA | online | ~3K | focused on Marxism, quality, shorter articles | | Encyclopedia of Marxism |1999...| CC BY-SA | online | ~3K | focused on Marxism, quality, shorter articles |
| Everybodywiki |2017...| CC BY-SA | online | ~300K | alternative to Wikipedia allowing articles on non notable things and people | | Everybodywiki |2017...| CC BY-SA | online | ~300K | alternative to Wikipedia allowing articles on non notable things and people |
| Google Knol | ~2010 | proprietary | online | | failed online enc. by Google, archived on archive.org | | Google Knol | ~2010 | proprietary | online | | failed online enc. by Google, archived on archive.org |

View file

@ -31,7 +31,7 @@ However these kinds of people may also pose a hope: if we could educate them and
``` ```
__ __
.' '. .' '.
/ \ drummyfish / \ drummyfish
_.' '._ | _.' '._ |
___....---'' ''---....___________v___ ___....---'' ''---....___________v___
@ -42,4 +42,4 @@ ___....---'' ''---....___________v___
## See Also ## See Also
- [idiot fallacy](idiot_fallacy.md) - [idiot fallacy](idiot_fallacy.md)

View file

@ -43,13 +43,13 @@ float
a = 21, a = 21,
b = 3.0 / 4.0, b = 3.0 / 4.0,
c = -10.0 / 3.0; c = -10.0 / 3.0;
a = a * b; // multiplication a = a * b; // multiplication
a += c; // addition a += c; // addition
a /= b; // division a /= b; // division
a -= 10; // subtraction a -= 10; // subtraction
a /= 3; // division a /= 3; // division
printf("%f\n",a); printf("%f\n",a);
``` ```
@ -68,7 +68,7 @@ a += c; // addition, no normalization needed
a = (a * UNIT) / b; // division, normalization needed, note the brackets a = (a * UNIT) / b; // division, normalization needed, note the brackets
a -= 10 * UNIT; // subtraction a -= 10 * UNIT; // subtraction
a /= 3; // division by a number NOT in UNITs, no normalization needed a /= 3; // division by a number NOT in UNITs, no normalization needed
printf("%d.%d%d%d\n", // writing a nice printing function is left as an exercise :) printf("%d.%d%d%d\n", // writing a nice printing function is left as an exercise :)
a / UNIT, a / UNIT,
((a * 10) / UNIT) % 10, ((a * 10) / UNIT) % 10,
@ -94,7 +94,7 @@ Fixed fixedSqrt(Fixed x)
// stupid brute force square root // stupid brute force square root
int previousError = -1; int previousError = -1;
for (int test = 0; test <= x; ++test) for (int test = 0; test <= x; ++test)
{ {
int error = x - (test * test) / UNIT_FRACTIONS; int error = x - (test * test) / UNIT_FRACTIONS;
@ -124,12 +124,12 @@ int main(void)
for (int i = 0; i <= 10; ++i) for (int i = 0; i <= 10; ++i)
{ {
printf("%d: ",i); printf("%d: ",i);
fixedPrint(fixedSqrt(INT_TO_FIXED(i))); fixedPrint(fixedSqrt(INT_TO_FIXED(i)));
putchar('\n'); putchar('\n');
} }
return 0; return 0;
} }
``` ```

View file

@ -2,9 +2,9 @@
{ I'm a bit ashamed but I really got into Forth quite recently, it's possible I spread some misinformation here, please let me know if I do, thanks <3 ~drummyfish } { I'm a bit ashamed but I really got into Forth quite recently, it's possible I spread some misinformation here, please let me know if I do, thanks <3 ~drummyfish }
Forth ("fourth generation" shortened to four characters due to technical limitations) is a very [elegant](beauty.md), extremely [minimalist](minimalism.md) [stack](stack.md)-based, untyped [programming language](programming_language.md) (and a general computing environment) that uses [postfix](notation.md) (reverse Polish) notation -- it is one of the very best programming languages ever conceived. Forth's vanilla form is super simple, much simpler than [C](c.md), its design is ingenious and a compiler/interpreter can be made with relatively little effort, giving it high [practical freedom](freedom_distance.md) (that is to say Forth can really be in the hands of the people). As of writing this the smallest Forth implementation, [milliforth](milliforth.md), has just **340 bytes** (!!!) of [machine code](machine_code.md), that's just incredible. Forth finds use for example in [space](space.md) computers (e.g. [RTX2010](rtx2010.md), a radiation hardened space computer directly executing Forth) and [embedded](embedded.md) systems as a way to write efficient [low level](low_level.md) programs that are, unlike those written in [assembly](assembly.md), [portable](portability.md). Forth stood as the main influence for [Comun](comun.md), the [LRS](lrs.md) programming language, it is also used by [Collapse OS](collapseos.md) and [Dusk OS](duskos.md) as the main language. In minimalism Forth competes a bit with [Lisp](lisp.md), however, to Lisp fan's dismay, Forth seems to ultimately come out as superior, especially in performance, but ultimately probably even in its elegance (while Lisp may be more mathematically elegant, Forth appears to be the most elegant fit for real hardware). Forth ("fourth generation" shortened to four characters due to technical limitations) is a very [elegant](beauty.md), extremely [minimalist](minimalism.md) [stack](stack.md)-based, untyped [programming language](programming_language.md) (and a general computing environment) that uses [postfix](notation.md) (reverse Polish) notation -- it is one of the very best programming languages ever conceived. Forth's vanilla form is super simple, much simpler than [C](c.md), its design is ingenious and a compiler/interpreter can be made with relatively little effort, giving it high [practical freedom](freedom_distance.md) (that is to say Forth can really be in the hands of the people). As of writing this the smallest Forth implementation, [milliforth](milliforth.md), has just **340 bytes** (!!!) of [machine code](machine_code.md), that's just incredible (the size is very close to [Brainfuck](brainfuck.md)'s compiler size, a language whose primary purpose was to have the smallest compiler possible). Forth finds use for example in [space](space.md) computers (e.g. [RTX2010](rtx2010.md), a radiation hardened space computer directly executing Forth) and [embedded](embedded.md) systems as a way to write efficient [low level](low_level.md) programs that are, unlike those written in [assembly](assembly.md), [portable](portability.md). Forth stood as the main influence for [Comun](comun.md), the [LRS](lrs.md) programming language, it is also used by [Collapse OS](collapseos.md) and [Dusk OS](duskos.md) as the main language. In minimalism Forth competes a bit with [Lisp](lisp.md), however, to Lisp fan's dismay, Forth seems to ultimately come out as superior, especially in performance, but ultimately probably even in its elegance (while Lisp may be more mathematically elegant, Forth appears to be the most elegant fit for real hardware).
Not wanting to invoke a fanboy mentality, the truth still has to be left known that **Forth may be one of best [programming](programming.md) systems yet conceived**, it is a pinnacle of programming genius. While in the realm of "normal" programming languages we're used to suffering tradeoffs such as sacrificing performance for flexibility, Forth dodges this seemingly inevitable mathematical curse and manages to beat virtually all such traditional languages at EVERYTHING at once: [simplicity](minimalism.md), [beauty](beauty.md), memory compactness, flexibility, performance and [portability](portability.md). It's also much more than a programming language, it is an overall system for computing, a calculator, programming language and its own debugger but may also serve for example as a [text editor](text_editor.md) and even, without exaggeration, a whole [operating system](os.md) (that is why e.g. DuskOS is written in Forth -- it is not as much written in Forth as it actually IS Forth). Understandably you may ask: if it's so great, why isn't it very much used "in the business"? Once someone summed it up as follow: Forth gives us unprecedented freedom and that allows [retards](soydev.md) to come up with bad design and unleash destruction -- [capitalism](capitalism.md) needs languages for monkeys, that's why [bad languages](rust.md) prosper. Remember: popularity has never been a measure of quality -- the best art will never be mainstream, it can only be understood and mastered by a few. Not wanting to invoke a fanboy mentality, the truth still has to be left known that **Forth may be one of best [programming](programming.md) systems yet conceived**, it is a pinnacle of programming genius. While in the realm of "normal" programming languages we're used to suffering tradeoffs such as sacrificing performance for flexibility, Forth dodges this seemingly inevitable mathematical curse and manages to beat virtually all such traditional languages at EVERYTHING at once: [simplicity](minimalism.md), [beauty](beauty.md), memory compactness, flexibility, performance and [portability](portability.md). It's also much more than a programming language, it is an overall system for computing, a calculator, programming language and its own debugger but may also serve for example as a [text editor](text_editor.md) and even, without exaggeration, a whole [operating system](os.md) (that is why e.g. DuskOS is written in Forth -- it is not as much written in Forth as it actually IS Forth). Understandably you may ask: if it's so great, why isn't it very much used "in the business"? Once someone summed it up as follows: Forth gives us unprecedented freedom and that allows [retards](soydev.md) to come up with bad design and unleash destruction -- [capitalism](capitalism.md) needs languages for monkeys, that's why [bad languages](rust.md) prosper. Remember: popularity has never been a measure of quality -- the best art will never be mainstream, it can only be understood and mastered by a few.
Forth is unique in its philosophy, we might almost go as far as calling Forth a programming [paradigm](paradigm.md) of its own. It can really be hardly compared to traditional languages such as [C++](cpp.md) or [Java](java.md) -- while the "typical language" is always more or less the same thing from the programmer's point of view by providing a few predefined, hardwired, usually complex but universal constructs that are simply there and cannot be changed in any way (such as an [OOP](oop.md) system, template system, macro language, control structures, primitive types, ...), **Forth adopts [Unix philosophy](unix_philosophy.md)** (and dare we say probably better than Unix itself) by defining just the concept of a *word*, maybe providing a handful of simple words for the start, and then letting the programmer extend the language (that is even the compiler/interpreter itself) by creating new words out of the simpler ones, and this includes even things such as control structures (branches, loops, ...), variables and constant. For instance: in traditional languages we find a few predefined formats in which numbers may be written -- let's say C lets us use decimal numbers as `123` or hexadecimal numbers as `0x7b` -- in Forth you may change the base at any time to any value by assigning to the `base` variable which will change how Forth parses and outputs numbers (while a number is considered any word that's not been found in dictionary), and it is even possible to completely rewrite the number parsing procedure itself. Almost everything in Forth can be modified this way, so pure Forth without any words is not much more than a description of a [data structure](data_structure.md) and simpler parser of space-separated words, it plainly dictates a format of how words will be represented and handled on a very basic level (that's on the simplicity level of, let's say, [lambda calculus](lambda_calculus.md)) and only a *Forth system* (i.e. one with a specific dictionary of defined words, such as that defined by ANS Forth standard) provides a basic "practically usable" language. The point is this can still be extended yet further, without any end or limitation. Forth is unique in its philosophy, we might almost go as far as calling Forth a programming [paradigm](paradigm.md) of its own. It can really be hardly compared to traditional languages such as [C++](cpp.md) or [Java](java.md) -- while the "typical language" is always more or less the same thing from the programmer's point of view by providing a few predefined, hardwired, usually complex but universal constructs that are simply there and cannot be changed in any way (such as an [OOP](oop.md) system, template system, macro language, control structures, primitive types, ...), **Forth adopts [Unix philosophy](unix_philosophy.md)** (and dare we say probably better than Unix itself) by defining just the concept of a *word*, maybe providing a handful of simple words for the start, and then letting the programmer extend the language (that is even the compiler/interpreter itself) by creating new words out of the simpler ones, and this includes even things such as control structures (branches, loops, ...), variables and constant. For instance: in traditional languages we find a few predefined formats in which numbers may be written -- let's say C lets us use decimal numbers as `123` or hexadecimal numbers as `0x7b` -- in Forth you may change the base at any time to any value by assigning to the `base` variable which will change how Forth parses and outputs numbers (while a number is considered any word that's not been found in dictionary), and it is even possible to completely rewrite the number parsing procedure itself. Almost everything in Forth can be modified this way, so pure Forth without any words is not much more than a description of a [data structure](data_structure.md) and simpler parser of space-separated words, it plainly dictates a format of how words will be represented and handled on a very basic level (that's on the simplicity level of, let's say, [lambda calculus](lambda_calculus.md)) and only a *Forth system* (i.e. one with a specific dictionary of defined words, such as that defined by ANS Forth standard) provides a basic "practically usable" language. The point is this can still be extended yet further, without any end or limitation.

View file

@ -185,7 +185,7 @@ void idft(void)
} }
data[k] /= N; data[k] /= N;
} }
} }
int main(void) int main(void)

View file

@ -39,7 +39,7 @@ Mathematically fractal is a shape whose [Hausdorff dimension](hausdorff_dimensio
/\/\ /\/\ /\/\ /\/\
/\ /\ /\ /\ /\ /\ /\ /\
/\/\/\/\/\/\/\/\ /\/\/\/\/\/\/\/\
Sierpinski Triangle Sierpinski Triangle
``` ```
@ -76,4 +76,4 @@ There also exist such things as fractal antennas and fractal transistors.
- [cardioid](cardioid.md) - [cardioid](cardioid.md)
- [spirograph](spirograph.md) - [spirograph](spirograph.md)
- [procedural generation](procgen.md) - [procedural generation](procgen.md)
- [turtle graphics](turtle_graphics.md) - [turtle graphics](turtle_graphics.md)

1
fun.md
View file

@ -9,6 +9,7 @@ Fun is a rewarding lighthearted satisfying feeling you get as a result of doing
This is subjective AF, even within a single man this depends on day, hour and mood. Anyway some fun stuff may include: This is subjective AF, even within a single man this depends on day, hour and mood. Anyway some fun stuff may include:
- the `#capitalistchallenge`: Try to win this game, you have as many shots as you want. Go to some tech store, seek the shop assistant and tell him you are deciding to buy one of two products, ask which one he would recommend. If he recommends the cheaper one you win. - the `#capitalistchallenge`: Try to win this game, you have as many shots as you want. Go to some tech store, seek the shop assistant and tell him you are deciding to buy one of two products, ask which one he would recommend. If he recommends the cheaper one you win.
- the *filters* package you will likely find in you distro's repos: You can apply funny filters to text, like for example `links -dump ~/git/less_retarded_wiki/html/algorithm.html | tail -n +10 | head -n 10 | pirate`. You may turn Wikipedia articles to Brooklyn English or haxor 1337 speech.
- the [fight culture](fight_culture.md) drinking game: Watch some [modern](modern.md) documentary, take a drink every time someone says the word *fight*. Harder mode: also drink when they say the word *[right](rights_culture.md)*. - the [fight culture](fight_culture.md) drinking game: Watch some [modern](modern.md) documentary, take a drink every time someone says the word *fight*. Harder mode: also drink when they say the word *[right](rights_culture.md)*.
- [programming](programming.md) - [programming](programming.md)
- [games](game.md) such as [chess](chess.md), [go](go.md) and [shogi](shogi.md), [racetrack](racetrack.md), even vidya gaymes (programming them and/or playing them), but only old+libre ones - [games](game.md) such as [chess](chess.md), [go](go.md) and [shogi](shogi.md), [racetrack](racetrack.md), even vidya gaymes (programming them and/or playing them), but only old+libre ones

View file

@ -56,9 +56,9 @@ To get better overview of a certain function we may try to represent it graphica
``` ```
|f(x) |f(x)
2+ 2+
'.._ | '.._ |
''--1+.____...--' ''--1+.____...--'
___,__,__|__,__,_____x ___,__,__|__,__,_____x
-2 -1 |0 1 2 -2 -1 |0 1 2
@ -135,4 +135,4 @@ unsigned int pseudoRandom(unsigned int maxValue) // impure function
In older languages functions were also called *[procedures](procedure.md)* or *[routines](routine.md)*. Sometimes there was some distinction between them, e.g. in [Pascal](pascal.md) functions returned a value while procedures didn't. In older languages functions were also called *[procedures](procedure.md)* or *[routines](routine.md)*. Sometimes there was some distinction between them, e.g. in [Pascal](pascal.md) functions returned a value while procedures didn't.
Just as in mathematics, a function in programming may be [recursive](recursion.md) -- here we define recursion as a function that calls itself. Just as in mathematics, a function in programming may be [recursive](recursion.md) -- here we define recursion as a function that calls itself.

View file

@ -41,8 +41,8 @@ The following ASCII masterpiece shows the number [2](two.md) in the territory of
| | / ____________________/ | | / ____________________/
| | / / | | / /
2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 ... multiplication 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 ... multiplication
| |4 8 __/ 16 32 64 128 256 | |4 8 __/ 16 32 64 128 256
| | / | | /
| | / ~10^(6 * 10^19728) | | / ~10^(6 * 10^19728)
2 ^ (2 ^ (2 ^ (2 ^ (2 ^ (2 ^ (2 ^ (2 ... exponentiation 2 ^ (2 ^ (2 ^ (2 ^ (2 ^ (2 ^ (2 ^ (2 ... exponentiation
| |4 16__/ 65536 ~10^19728 ~10^(10^(10^19728)) | |4 16__/ 65536 ~10^19728 ~10^(10^(10^19728))
@ -72,7 +72,7 @@ Some things generally hold about hyperoperations, for example for any operation
| | / ____________________/ | | / ____________________/
| | / / | | / /
2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 ... multiplication 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 ... multiplication
| |4 __/ 16 32 64 128 / 256 | |4 __/ 16 32 64 128 / 256
| | / ____________________/ | | / ____________________/
| | / / | | / /
(2 ^ 2) ^ 2) ^ 2) ^ 2) ^ 2) ^ 2) ^ 2 ... left exponentiation (2 ^ 2) ^ 2) ^ 2) ^ 2) ^ 2) ^ 2) ^ 2 ... left exponentiation
@ -80,7 +80,7 @@ Some things generally hold about hyperoperations, for example for any operation
| | / ____________________________ | | / ____________________________
| | / / | | / /
(2 ^^ 2) ^^ 2) ^^ 2) ^^ 2) ^^ 2) ^^ 2) ^^ 2 ... left tetration (2 ^^ 2) ^^ 2) ^^ 2) ^^ 2) ^^ 2) ^^ 2) ^^ 2 ... left tetration
| |4 256 2^1048576 | |4 256 2^1048576
| | TODO: arrows? | | TODO: arrows?
| | | |
(2 ^^^ 2)^^^ 2)^^^ 2)^^^ 2)^^^ 2)^^^ 2)^^^ 2 ... left pentation (2 ^^^ 2)^^^ 2)^^^ 2)^^^ 2)^^^ 2)^^^ 2)^^^ 2 ... left pentation
@ -233,4 +233,4 @@ In this form the code prints a table for right associativity tetration:
## See Also ## See Also
- [googology](googology.md) - [googology](googology.md)
- [p-adic numbers](p_adic.md) - [p-adic numbers](p_adic.md)

View file

@ -59,11 +59,11 @@ Now we can perform a computation of 2 + 1. We first set up the interaction net t
| | | |==>---|______| | | | |==>---|______|
| ZERO |==>---| SUCC | | ZERO |==>---| SUCC |
|______| |______| |______| |______|
representation of 1 representation of 1
apply rule 2: apply rule 2:
______ ______ ______ ______
| | | | ______ ______ | | | | ______ ______
| ZERO |==>---| SUCC |==><==| | | | | ZERO |==>---| SUCC |==><==| | | |
@ -83,14 +83,14 @@ apply rule 2:
| ZERO |==>---| SUCC | | ZERO |==>---| SUCC |
|______| |______| |______| |______|
apply rule 1: apply rule 1:
______ ______ ______ ______ ______ ______ ______ ______
| | | | | | | | | | | | | | | |
| ZERO |==>---| SUCC |==>---| SUCC |==>---| SUCC |==> z | ZERO |==>---| SUCC |==>---| SUCC |==>---| SUCC |==> z
|______| |______| |______| |______| |______| |______| |______| |______|
representation of 3 (the result) representation of 3 (the result)
no more rules to apply no more rules to apply
``` ```
@ -101,12 +101,12 @@ One specific very important interaction system is called **"interaction combinat
erasing rule: _____ erasing rule: _____
_____ _____ | | _____ _____ | |
x ---| | | | x <==| E | x ---| | | | x <==| E |
{...}| t |==><==| E | rewrites to |_____| {...}| t |==><==| E | rewrites to |_____|
y ---|_____| |_____| {...} _____ y ---|_____| |_____| {...} _____
| | | |
y <==| E | y <==| E |
|_____| |_____|
duplication rule: duplication rule:
_____ _____ _____ _____
| |------| | | |------| |
@ -132,4 +132,4 @@ TODO: text representation, compare text representation of interaction nets with
## See Also ## See Also
- [rule 110](rule110.md) - [rule 110](rule110.md)

4
iq.md
View file

@ -8,7 +8,7 @@
|CONSTRUCTION| |CONSTRUCTION|
\ / \ /
\________/ \________/
Please wear a hard hat when reading this page. Please wear a hard hat when reading this page.
``` ```
@ -41,7 +41,7 @@ TODO: more details, history, where to measure (web vs Mensa vs SAT etc.)
---------------------------------------------asians----------------------------------------------- ---------------------------------------------asians-----------------------------------------------
---------------------------------------------jews------------------------------------------------- ---------------------------------------------jews-------------------------------------------------
----------likely called genius-------- ----------likely called genius--------
-------fascists----- ------likely called retarded----- -------fascists----- ------likely called retarded-----
--influencers-- _.---._ --influencers-- _.---._
.' '. .' '.
.' '. .' '.

View file

@ -11,7 +11,7 @@ This is the freedom island where [we](less_retarded_society.md) live. Many would
The Freedom Island The Freedom Island
-~"--'"~' ____ -~"--'"~' -~"--'"~' ____ -~"--'"~'
__X/ '-X_ __X/ '-X_
'"-~-._ ____./ i# X xx'-__ '"-~-._ ____./ i# X xx'-__
__.-' [E]/' XX i: "x \_ '"-~-._ __.-' [E]/' XX i: "x \_ '"-~-._
___,--' x x_/' X Xi O:. '-_ ___,--' x x_/' X Xi O:. '-_
___/ ##__-'' X X( x# i x# '-._ ___/ ##__-'' X X( x# i x# '-._
@ -46,4 +46,4 @@ TODO: food sources: fields and sea farms (only vegetarian), chickens for eggs, f
- [Utopia](utopia.md) - [Utopia](utopia.md)
- [Atlantis](atlantis.md) - [Atlantis](atlantis.md)
- [Loquendo City](loquendo.md) - [Loquendo City](loquendo.md)

View file

@ -1,6 +1,6 @@
# Jargon File # Jargon File
Jargon File (also Hacker's Dictionary) is a computer [hacker](hacking.md) dictionary/compendium that's been written and updated by a number of prominent hackers, such as [Richard Stallman](rms.md) and [Erik S Raymond](esr.md), since 1970. It is a chiefly important part of hacker culture and has also partly inspired [this very wiki](lrs_wiki.md). Jargon File (also Hacker's Dictionary) is a [computer](computer.md) [hacker](hacking.md) dictionary/compendium that's been written and updated by a number of prominent hackers, such as [Richard Stallman](rms.md) and [Erik S Raymond](esr.md), since 1970. It is a chiefly important part of hacker culture and has also partly inspired [this very wiki](lrs_wiki.md).
{ A similar but smaller encyclopedia is at https://www.erzo.org/shannon/writing/csua/encyclopedia.html (originally and encyclopedia at soda.csua.berkeley.edu). ~drummyfish } { A similar but smaller encyclopedia is at https://www.erzo.org/shannon/writing/csua/encyclopedia.html (originally and encyclopedia at soda.csua.berkeley.edu). ~drummyfish }

View file

@ -11,6 +11,7 @@ Also remember the worst thing you can do to a joke is put a [disclaimer](disclai
{ I would like to thank my friend Ramon who contributed to me many ideas for jokes here :D I usually modified them slightly. ~drummyfish } { I would like to thank my friend Ramon who contributed to me many ideas for jokes here :D I usually modified them slightly. ~drummyfish }
- [C++](cpp.md) - [C++](cpp.md)
- Why doesn't [C++](cpp.md) have [garbage collection](garbage_collection.md)? Because then it would have to collect itself.
- Why is the maximum speed called terminal velocity? Because [GUI](gui.md)s are slow. - Why is the maximum speed called terminal velocity? Because [GUI](gui.md)s are slow.
- What's the worst kind of [lag](lag.md)? Gulag. - What's the worst kind of [lag](lag.md)? Gulag.
- Ingame chat: "What's the country in the middle of north Africa?" [{BANNED}](niger.md) - Ingame chat: "What's the country in the middle of north Africa?" [{BANNED}](niger.md)
@ -53,9 +54,11 @@ Also remember the worst thing you can do to a joke is put a [disclaimer](disclai
- One of the great milestones yet left to be achieved by science is to find intelligent life in our Solar System. - One of the great milestones yet left to be achieved by science is to find intelligent life in our Solar System.
- An evil capitalist, good capitalist and [female](woman.md) genius walk in the park. A bee stings one of them. Who did it sting? The evil capitalists, the other two don't exist. - An evil capitalist, good capitalist and [female](woman.md) genius walk in the park. A bee stings one of them. Who did it sting? The evil capitalists, the other two don't exist.
- Cool statistics: 9 out of 10 people enjoy a gang [rape](rape.md). - Cool statistics: 9 out of 10 people enjoy a gang [rape](rape.md).
- What does a shitty programmer say when his program crashes? [OOP](oop.md)s. { Thanks my secret friend. :D ~drummyfish }
- Basement hackers never die, they just smell that way. Musicians never die, they just decompose (and musicians working part time are [semiconductors](semiconductor.md)). - Basement hackers never die, they just smell that way. Musicians never die, they just decompose (and musicians working part time are [semiconductors](semiconductor.md)).
- `int randomInt(void) { int x; return x; }` - `int randomInt(void) { int x; return x; }`
- Boss: "We're going to need to store additional information about gender of all 1600 people in our database." Me: "OK that's only 200 extra bytes.". Diversity department: "You're fired." - Boss: "We're going to need to store additional information about gender of all 1600 people in our database." Me: "OK that's only 200 extra bytes.". Diversity department: "You're fired."
- [Java](java.md) is like Alzheimers -- starts slow and eventually takes away all your memory.
- the [downto](downto.md) operator - the [downto](downto.md) operator
- My girlfriend just left me, she said it's because she thought I was a [pedophile](pedophilia.md). Those are some strong words for an eleven year old. - My girlfriend just left me, she said it's because she thought I was a [pedophile](pedophilia.md). Those are some strong words for an eleven year old.
- [Schizophrenia](schizo.md) beats being alone. - [Schizophrenia](schizo.md) beats being alone.

View file

@ -81,7 +81,7 @@ int main(void)
for (int x = 0; x < COLS; ++x) for (int x = 0; x < COLS; ++x)
{ {
unsigned int point = unsigned int point =
julia(cx,cy) + (julia(cx,cy + STEP) * 2); julia(cx,cy) + (julia(cx,cy + STEP) * 2);
putchar(point == 3 ? ':' : (point == 2 ? '\'' : putchar(point == 3 ? ':' : (point == 2 ? '\'' :
(point == 1 ? '.' : ' '))); (point == 1 ? '.' : ' ')));

View file

@ -4,7 +4,7 @@
KISS (Keep It Simple, Stupid!; also KISR, *keep it simple, retard*) is a [minimalist](minimalism.md) design philosophy that favors simplicity, both internal and external, [technology](tech.md) that is **as simple as possible** to achieve given task. This philosophy doesn't primarily stem from [laziness](laziness.md) or a desire to rush something (though these are completely valid reasons too), but mainly from the fact that higher [complexity](complexity.md) comes with increasingly negative effects such as the cost of development, cost of [maintenance](maintenance.md), greater probability of [bugs](bug.md) and failure, more [dependencies](dependency.md) etc. KISS (Keep It Simple, Stupid!; also KISR, *keep it simple, retard*) is a [minimalist](minimalism.md) design philosophy that favors simplicity, both internal and external, [technology](tech.md) that is **as simple as possible** to achieve given task. This philosophy doesn't primarily stem from [laziness](laziness.md) or a desire to rush something (though these are completely valid reasons too), but mainly from the fact that higher [complexity](complexity.md) comes with increasingly negative effects such as the cost of development, cost of [maintenance](maintenance.md), greater probability of [bugs](bug.md) and failure, more [dependencies](dependency.md) etc.
WATCH OUT: various scum has started to ride on the wave of the "KISS" trend and abuse the term, twisting its true meaning; for example GNU/Linux Mint has started to market itself as "KISS" -- that's of course ridiculous and all Mint developers are cretins and idiots. **Maximum INTERNAL simplicity is a necessary prerequisite for the KISS philosophy**, anything that's just simple on the outside is a mere harmful [pseudominimalism](pseudominimalism.md) -- you may as well use a [Mac](mac.md). WATCH OUT: various scum has started to ride on the wave of the "KISS" trend and abuse the term, twisting its true meaning; for example GNU/Linux Mint has started to [market](marketing.md) itself as "KISS" -- that's of course ridiculous and all Mint developers are cretins and idiots. **Maximum INTERNAL simplicity is a necessary prerequisite for the KISS philosophy**, anything that's just simple on the outside is a mere harmful [pseudominimalism](pseudominimalism.md) -- you may as well use a [Mac](mac.md).
Under dystopian [capitalism](capitalism.md) simple [technology](tech.md), such as simple [software](software.md), has at least one more advantage connected to "[intellectual property](intellectual_property.md)": a simple solution is less likely to step on a [patent](patent.md) landmine because such a simple solution will either be hard to patent or as more obvious will have been discovered and patented sooner and the patent is more likely to already be expired. So in this sense KISS technology is legally safer. Under dystopian [capitalism](capitalism.md) simple [technology](tech.md), such as simple [software](software.md), has at least one more advantage connected to "[intellectual property](intellectual_property.md)": a simple solution is less likely to step on a [patent](patent.md) landmine because such a simple solution will either be hard to patent or as more obvious will have been discovered and patented sooner and the patent is more likely to already be expired. So in this sense KISS technology is legally safer.

View file

@ -101,7 +101,7 @@ int main(void)
ant.direction = 0; ant.direction = 0;
for (unsigned int step = 0; step < STEPS; ++step) for (unsigned int step = 0; step < STEPS; ++step)
{ {
unsigned int fieldIndex = ant.y * FIELD_SIZE + ant.x; unsigned int fieldIndex = ant.y * FIELD_SIZE + ant.x;
unsigned char color = field[fieldIndex]; unsigned char color = field[fieldIndex];
@ -156,4 +156,4 @@ int main(void)
- [turmite](turmite.md) - [turmite](turmite.md)
- [rule 110](rule_110.md) - [rule 110](rule_110.md)
- [cellular automaton](cellular_automaton.md) - [cellular automaton](cellular_automaton.md)
- [turtle graphics](turtle_graphics.md) - [turtle graphics](turtle_graphics.md)

View file

@ -70,7 +70,7 @@ The result, *AB*, will be a 2x4 matrix in which e.g. the top-left element is equ
``` ```
|7 8 9 10 | |7 8 9 10 |
|11 12 13 14 | |11 12 13 14 |
|15 16 17 18 | |15 16 17 18 |
|7 8 9 10| |7 8 9 10|
|1 2 3| |11 12 13 14| = |1 2 3| |74 80 86 92 | |1 2 3| |11 12 13 14| = |1 2 3| |74 80 86 92 |
@ -92,26 +92,26 @@ int main()
{7, 8, 9, 10}, {7, 8, 9, 10},
{11, 12, 13, 14}, {11, 12, 13, 14},
{15, 16, 17, 18}}; {15, 16, 17, 18}};
for (int row = 0; row < 2; ++row) for (int row = 0; row < 2; ++row)
{ {
for (int col = 0; col < 4; ++col) for (int col = 0; col < 4; ++col)
{ {
int sum = 0; int sum = 0;
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i)
sum += A[row][i] * B[i][col]; sum += A[row][i] * B[i][col];
printf("%d ",sum); printf("%d ",sum);
} }
putchar('\n'); putchar('\n');
} }
return 0; return 0;
} }
``` ```
## See Also ## See Also
- [analytic geometry](analytic_geometry.md) - [analytic geometry](analytic_geometry.md)

View file

@ -31,7 +31,7 @@ The truth table of these gates is as follows:
``` ```
___ ___ _____ _____ ___ ___ _____ _____
---\ ''-. ---\ ''-. ---| '. ---| '. ---\ ''-. ---\ ''-. ---| '. ---| '.
) )--- ) )O-- | )--- | )O-- ) )--- ) )O-- | )--- | )O--
---/__..-' ---/__..-' ---|_____.' ---|_____.' ---/__..-' ---/__..-' ---|_____.' ---|_____.'
OR NOR AND NAND OR NOR AND NAND
@ -47,11 +47,11 @@ The truth table of these gates is as follows:
| |--- | |--- | |--- ---| |o-- | |--- | |--- | |--- ---| |o--
---|____| ---|____| ---|____| |____| ---|____| ---|____| ---|____| |____|
OR AND XOR NOT OR AND XOR NOT
or even: or even:
___ ___ ___ ___ ___ ___ ___ ___
--|OR |-- --|AND|-- --|XOR|-- --|NOT|-- --|OR |-- --|AND|-- --|XOR|-- --|NOT|--
--|___| --|___| --|___| |___| --|___| --|___| --|___| |___|
``` ```
*symbols often used for logic gates* *symbols often used for logic gates*

View file

@ -20,7 +20,7 @@ WORK IN PROGRESS
| [CEO](ceo.md) | capitalist evil oppressor | | [CEO](ceo.md) | capitalist evil oppressor |
| [cloud](cloud.md) computing | clown computing | | [cloud](cloud.md) computing | clown computing |
| [cloudflare](cloudfalre.md) | cuckflare, clownflare, crimeflare | | [cloudflare](cloudfalre.md) | cuckflare, clownflare, crimeflare |
| code of conduct ([COC](coc.md)) | code of coercion, code of censorship | | code of conduct ([COC](coc.md)) | code of coercion, code of censorship |
| [comun](comun.md) | coomun { One friend suggested this :D ~drummyfish } | | [comun](comun.md) | coomun { One friend suggested this :D ~drummyfish } |
| consume | consoom (see also [coom](coom.md)) | | consume | consoom (see also [coom](coom.md)) |
| [copyright](copyright.md) | copywrong, copyrestriction, copyrape | | [copyright](copyright.md) | copywrong, copyrestriction, copyrape |
@ -54,7 +54,7 @@ WORK IN PROGRESS
| job | slavery | | job | slavery |
| "left" | [pseudoleft](pseudoleft.md), SJW | | "left" | [pseudoleft](pseudoleft.md), SJW |
| [LGBT](lgbt.md) | FGTS, TTTT | | [LGBT](lgbt.md) | FGTS, TTTT |
| [liberal](liberal.md) | libtard | | [liberal](liberal.md) | libtard |
| "[Linux](linux.md)" | [GNU](gnu.md), lunix, loonix | | "[Linux](linux.md)" | [GNU](gnu.md), lunix, loonix |
| [logic gate](logic_gate.md) | logic gayte | | [logic gate](logic_gate.md) | logic gayte |
| Macintosh | Macintoy, Macintrash, Maggotbox | | Macintosh | Macintoy, Macintrash, Maggotbox |

View file

@ -51,7 +51,7 @@ This is a Wiki for [less retarded software](lrs.md), [less retarded society](les
You ask how could people of the past have been so stupid, how they could have believed obviously nonsensical "[pseudoscience](pseudoscience.md)" and religious fairy tales, how could the past peasant take part in [witch hunts](witch_hunt.md), how could so many people support [Hitler](hitler.md) and let [Holocaust](holocaust.md) happen? Well, don't judge them so fast -- if you disagree with this wiki, you are just like them. No, there was no magical turn around of society from [evil](evil.md) to good just before your birth, times are still the same, except much worse; if you don't see the catastrophic state of the world, you are most likely blissfully brainwashed beyond the level of any medieval peasant. But don't worry, it's not your fault, you are just among the 99.9999%. We are here to help. Keep an open mind and the [truth](truth.md) will show. But beware, truth comes for the price of irreversible [depression](depression.md). You ask how could people of the past have been so stupid, how they could have believed obviously nonsensical "[pseudoscience](pseudoscience.md)" and religious fairy tales, how could the past peasant take part in [witch hunts](witch_hunt.md), how could so many people support [Hitler](hitler.md) and let [Holocaust](holocaust.md) happen? Well, don't judge them so fast -- if you disagree with this wiki, you are just like them. No, there was no magical turn around of society from [evil](evil.md) to good just before your birth, times are still the same, except much worse; if you don't see the catastrophic state of the world, you are most likely blissfully brainwashed beyond the level of any medieval peasant. But don't worry, it's not your fault, you are just among the 99.9999%. We are here to help. Keep an open mind and the [truth](truth.md) will show. But beware, truth comes for the price of irreversible [depression](depression.md).
Or perhaps you see the [evil](evil.md) but play along with the system out of [fear](fear_culture.md)? Because [everyone does it](everyone_does_it.md)? Because everyone tells you? Are you afraid then of thinking with your own brain and following what you sincerely judge as honest truth? Are you afraid of losing the comfort and luxury you live in? Think again then: are you not just a slave? Are you not rather afraid of living a bad life, of wasting the only opportunity at living you will ever have? It's not tool late to change. Or perhaps you see the [evil](evil.md) but play along with the system out of [fear](fear_culture.md)? Because [everyone does it](everyone_does_it.md)? Because everyone tells you? Are you afraid then of thinking with your own brain and following what you sincerely judge as honest truth? Are you afraid of losing the comfort and luxury you live in? Think again then: are you not just a slave? Are you not rather afraid of living a bad life, of wasting the only opportunity at living you will ever have? It's not too late for a change.
This wiki is **NOT** a satire. Yes, everything is **UNDER CONSTRUCTION**. This wiki is **NOT** a satire. Yes, everything is **UNDER CONSTRUCTION**.
@ -125,7 +125,7 @@ Are you a noob but see our ideas as appealing and would like to join us? Say no
Here there are quick directions to some of the important topics; for more see the links provided at the top that include the list of all articles as well as a single page HTML which is good for "fulltext search" via crtl+F :) Here there are quick directions to some of the important topics; for more see the links provided at the top that include the list of all articles as well as a single page HTML which is good for "fulltext search" via crtl+F :)
- **basics**: [bloat](bloat.md) -- [capitalist software](capitalist_software.md) -- [less retarded society](less_retarded_society.md) -- [LRS](lrs.md) -- [pseudoleft](pseudoleft.md) - **basics**: [bloat](bloat.md) -- [capitalist software](capitalist_software.md) -- [less retarded society](less_retarded_society.md) -- [LRS](lrs.md) -- [pseudoleft](pseudoleft.md)
- **LRS inventions/propositions**: [A/B fail](fail_ab.md) -- [Anarch](anarch.md) -- [boat](boat.md) webring -- [comun](comun.md) -- [freedom distance](freedom_distance.md) -- less retarded [chess](chess.md) -- [less retarded hardware](less_retarded_hardware.md) -- [less retarded society](less_retarded_society.md) -- [less retarded software](lrs.md) -- [less retarded watch](less_retarded_watch.md) -- [less retarded wiki](lrs_wiki.md) -- [macrofucker](macrofucker.md) -- [public domain computer](public_domain_computer.md) -- [raycastlib](raycastlib.md) -- [rock carved binary data](rock_carved_binary_data.md) -- [SAF](saf.md) -- [small3dlib](small3dlib.md) -- [smallchesslib](smallchesslib.md) -- [tinyphysicsengine](tinyphysicsengine.md) -- [world broadcast](world_broadcast.md) -- [unretardation](unretard.md) - **LRS inventions/propositions**: [A/B fail](fail_ab.md) -- [Anarch](anarch.md) -- [boat](boat.md) webring -- [comun](comun.md) -- [freedom distance](freedom_distance.md) -- [gege](gege.md) -- less retarded [chess](chess.md) -- [less retarded hardware](less_retarded_hardware.md) -- [less retarded society](less_retarded_society.md) -- [less retarded software](lrs.md) -- [less retarded watch](less_retarded_watch.md) -- [less retarded wiki](lrs_wiki.md) -- [macrofucker](macrofucker.md) -- [public domain computer](public_domain_computer.md) -- [raycastlib](raycastlib.md) -- [rock carved binary data](rock_carved_binary_data.md) -- [SAF](saf.md) -- [small3dlib](small3dlib.md) -- [smallchesslib](smallchesslib.md) -- [tinyphysicsengine](tinyphysicsengine.md) -- [world broadcast](world_broadcast.md) -- [unretardation](unretard.md)
- **programming/computers**: [3D rendering](3d_rendering.md) -- [binary](binary.md) -- [computer](computer.md) -- [AI](ai.md) -- [algorithm](algorithm.md) -- [C](c.md) -- [C tutorial](c_tutorial.md) -- [computer](computer.md) -- [computer graphics](graphics.md) -- [CPU](cpu.md) -- [data structure](data_structure.md) -- [demoscene](demoscene.md) -- [GNU](gnu.md) -- [hacker culture](hacking.md) -- [hardware](hardware.md) -- [Internet](internet.md) -- [KISS](kiss.md) -- [Linux](linux.md) -- [OOP](oop.md) -- [open consoles](open_console.md) -- [operating system](os.md) -- [optimization](optimization.md) -- [portability](portability.md) -- [procedural generation](procgen.md) -- [programming](programming.md) -- [programming language](programming_language.md) -- [suckless](suckless.md) -- [Unix philosophy](unix_philosophy.md) -- [web](www.md) - **programming/computers**: [3D rendering](3d_rendering.md) -- [binary](binary.md) -- [computer](computer.md) -- [AI](ai.md) -- [algorithm](algorithm.md) -- [C](c.md) -- [C tutorial](c_tutorial.md) -- [computer](computer.md) -- [computer graphics](graphics.md) -- [CPU](cpu.md) -- [data structure](data_structure.md) -- [demoscene](demoscene.md) -- [GNU](gnu.md) -- [hacker culture](hacking.md) -- [hardware](hardware.md) -- [Internet](internet.md) -- [KISS](kiss.md) -- [Linux](linux.md) -- [OOP](oop.md) -- [open consoles](open_console.md) -- [operating system](os.md) -- [optimization](optimization.md) -- [portability](portability.md) -- [procedural generation](procgen.md) -- [programming](programming.md) -- [programming language](programming_language.md) -- [suckless](suckless.md) -- [Unix philosophy](unix_philosophy.md) -- [web](www.md)
- **math/theory**: [aliasing](aliasing.md) -- [chaos](chaos.md) -- [combinatorics](combinatorics.md) -- [fractal](fractal.md) -- [formal languages](formal_language.md) -- [information](information.md) -- [linear algebra](linear_algebra.md) -- [logic](logic.md) -- [math](math.md) -- [number](number.md) -- [pi](pi.md) -- [prime number](prime.md) -- [probability](probability.md) -- [Turing machine](turing_machine.md) -- [zero](zero.md) - **math/theory**: [aliasing](aliasing.md) -- [chaos](chaos.md) -- [combinatorics](combinatorics.md) -- [fractal](fractal.md) -- [formal languages](formal_language.md) -- [information](information.md) -- [linear algebra](linear_algebra.md) -- [logic](logic.md) -- [math](math.md) -- [number](number.md) -- [pi](pi.md) -- [prime number](prime.md) -- [probability](probability.md) -- [Turing machine](turing_machine.md) -- [zero](zero.md)
- **society**: [anarchism](anarchism.md) -- [anarcho pacifism](anpac.md) -- [capitalism](capitalism.md) -- [censorship](censorship.md) -- [collapse](collapse.md) -- [communism](communism.md) -- [democracy](democracy.md) -- [everyone does it](everyone_does_it.md) -- [fascism](fascism.md) -- [feminism](feminism.md) -- [fight culture](fight_culture.md) -- [history](history.md) -- [homosexuality](gay.md) -- [left vs right vs pseudoleft](left_right.md) -- [Jesus](jesus.md) -- [less retarded society](less_retarded_society.md) -- [LGBTQWTF](lgbt.md) -- [science](science.md) vs [soyence](soyence.md) -- [productivity cult](productivity_cult.md) -- [selflessness](selflessness.md) -- [socialism](socialism.md) -- [Venus project](venus_project.md) -- [work](work.md) - **society**: [anarchism](anarchism.md) -- [anarcho pacifism](anpac.md) -- [capitalism](capitalism.md) -- [censorship](censorship.md) -- [collapse](collapse.md) -- [communism](communism.md) -- [democracy](democracy.md) -- [everyone does it](everyone_does_it.md) -- [fascism](fascism.md) -- [feminism](feminism.md) -- [fight culture](fight_culture.md) -- [history](history.md) -- [homosexuality](gay.md) -- [left vs right vs pseudoleft](left_right.md) -- [Jesus](jesus.md) -- [less retarded society](less_retarded_society.md) -- [LGBTQWTF](lgbt.md) -- [science](science.md) vs [soyence](soyence.md) -- [productivity cult](productivity_cult.md) -- [selflessness](selflessness.md) -- [socialism](socialism.md) -- [Venus project](venus_project.md) -- [work](work.md)

View file

@ -17,7 +17,7 @@ FILECOUNT=`ls *.md | wc -l`
FILELIST="wiki_pages" FILELIST="wiki_pages"
RANDPAGE="random_page" RANDPAGE="random_page"
HEADER1="<html><head><link rel=\"stylesheet\" href=\"style.css\"><title> LRS Wiki: " HEADER1="<html><head><link rel=\"stylesheet\" href=\"style.css\"><title> LRS Wiki: "
HEADER2="</title></head><body><h1>less_retarded_wiki</h1><span class=\"nav\"><a href=\"main.html\">main page</a>, <a class=\"notdead\" href=\"$FILELIST.html\">file list ($FILECOUNT)</a>, <a class=\"notdead\" href=\"https://git.coom.tech/drummyfish/less_retarded_wiki/archive/master.zip\">source</a>, <a class=\"notdead\" href=\"lrs_wiki.7z\">all in md+txt+html+pdf</a>, <a class=\"notdead\" href=\"report.html\">report abuse</a>, <a class=\"notdead\" href=\"wiki_stats.html\">stats</a>, <a class=\"notdead\" href=\"$RANDPAGE.html\">random article</a>, <a class=\"notdead\" id=\"fancylink\" href=\"pimp_my_lrs.html?p=main.html&s=style_fancy.css\">consoomer version</a></span><hr />" HEADER2="</title></head><body><h1>less_retarded_wiki</h1><span class=\"nav\"><a href=\"main.html\">main page</a>, <a class=\"notdead\" href=\"$FILELIST.html\">file list ($FILECOUNT)</a>, <a class=\"notdead\" href=\"https://git.coom.tech/drummyfish/less_retarded_wiki/archive/master.zip\">source</a>, <a class=\"notdead\" href=\"lrs_wiki.7z\">all in md+txt+html+pdf</a>, <a class=\"notdead\" href=\"https://git.coom.tech/drummyfish/less_retarded_wiki.atom\">commit RSS feed</a>, <a class=\"notdead\" href=\"report.html\">report abuse</a>, <a class=\"notdead\" href=\"wiki_stats.html\">stats</a>, <a class=\"notdead\" href=\"$RANDPAGE.html\">random article</a>, <a class=\"notdead\" id=\"fancylink\" href=\"pimp_my_lrs.html?p=main.html&s=style_fancy.css\">consoomer version</a></span><hr />"
FOOTER="<hr /><p> Powered by nothing. All content available under <a class=\"notdead\" href=\"https://creativecommons.org/publicdomain/zero/1.0/\">CC0 1.0</a> (public domain). Send comments and corrections to drummyfish at disroot dot org. </p></body></html>" FOOTER="<hr /><p> Powered by nothing. All content available under <a class=\"notdead\" href=\"https://creativecommons.org/publicdomain/zero/1.0/\">CC0 1.0</a> (public domain). Send comments and corrections to drummyfish at disroot dot org. </p></body></html>"
rm $RANDPAGE.md rm $RANDPAGE.md

View file

@ -148,7 +148,7 @@ int main(void)
for (int x = 0; x < COLS; ++x) for (int x = 0; x < COLS; ++x)
{ {
unsigned int point = unsigned int point =
mandelbrot(cx,cy) + (mandelbrot(cx,cy + STEP) * 2); mandelbrot(cx,cy) + (mandelbrot(cx,cy + STEP) * 2);
putchar(point == 3 ? ':' : (point == 2 ? '\'' : putchar(point == 3 ? ':' : (point == 2 ? '\'' :
(point == 1 ? '.' : ' '))); (point == 1 ? '.' : ' ')));

View file

@ -65,7 +65,7 @@ Besides others gears/wheels can be used to:
| '-;, ,-;' { o } | | '-;, ,-;' { o } |
| _|||____{ o }____;-; | | _|||____{ o }____;-; |
| '-;-. { o } | | '-;-. { o } |
|_____________ { o } _'-'__| |_____________ { o } _'-'__|
'-' '-'
1 1
@ -76,7 +76,7 @@ Besides others gears/wheels can be used to:
| ,;-' ,-, '-'{ o } | | ,;-' ,-, '-'{ o } |
| _|||__{ o }_____;-; | | _|||__{ o }_____;-; |
| '-' .-{ o } | | '-' .-{ o } |
|_____________ { o }-'_____| |_____________ { o }-'_____|
'-' '-'
0 0
``` ```
@ -199,4 +199,4 @@ Whether the use of fluids/gases (water, air, steam, maybe even sand, ...) is sti
Don't forget there exist many other possible components and concepts a mechanical computer can internally use -- many things we leave out above for the questionability of their practical usability can be used to in fact carry out computation, for example dominoes or slinkies. Furthermore many actually useful things exist, e.g. teethed **cylinders/disks** may be used to record plots of data over time or to store and deliver read/only data (e.g. the program instructions) easily, see music boxes and gramophones; **[punch card](punch_card.md) and paper tapes** have widely been used for storing read-only data too. Sometimes deformed cylinders were used as an analog **2D [look up table](lut.md)** for some mathematical [function](function.md) -- imagine e.g. a device that has input *x* (rotating cylinder along its axis) and *y* (shifting it left/right); the cylinder can then at each surface point record function *f(x,y)* by its width which will in turn displace some stick that will mark the function value on a scale. To transfer movement **strings, chains and belts** may also be used. [Random number generation](rng.md) may be implemented e.g. with [Galton board](galton_board.md). If timing is needed, pendulums can be used just like in clock. Some mechanical computers even use pretty complex parts such as mechanical arms, but these are firstly hard to make and secondly prone to breaking, so try to avoid complexity as much as possible. Some old mechanical calculators worked by requiring the user to plug a stick into some hole (e.g. number he wanted to add) and then manually trace some path -- this can work on the same principle as e.g. the marble computer, but without needing the marbles complexity and size are drastically reduced. Another ideas is a "combing" computer which is driven by its user repeatedly sliding some object through the mechanism (as if combing it) which performs the steps (sequential computation) and changes the state (which is either stored inside the computer or in the combing object). Don't forget there exist many other possible components and concepts a mechanical computer can internally use -- many things we leave out above for the questionability of their practical usability can be used to in fact carry out computation, for example dominoes or slinkies. Furthermore many actually useful things exist, e.g. teethed **cylinders/disks** may be used to record plots of data over time or to store and deliver read/only data (e.g. the program instructions) easily, see music boxes and gramophones; **[punch card](punch_card.md) and paper tapes** have widely been used for storing read-only data too. Sometimes deformed cylinders were used as an analog **2D [look up table](lut.md)** for some mathematical [function](function.md) -- imagine e.g. a device that has input *x* (rotating cylinder along its axis) and *y* (shifting it left/right); the cylinder can then at each surface point record function *f(x,y)* by its width which will in turn displace some stick that will mark the function value on a scale. To transfer movement **strings, chains and belts** may also be used. [Random number generation](rng.md) may be implemented e.g. with [Galton board](galton_board.md). If timing is needed, pendulums can be used just like in clock. Some mechanical computers even use pretty complex parts such as mechanical arms, but these are firstly hard to make and secondly prone to breaking, so try to avoid complexity as much as possible. Some old mechanical calculators worked by requiring the user to plug a stick into some hole (e.g. number he wanted to add) and then manually trace some path -- this can work on the same principle as e.g. the marble computer, but without needing the marbles complexity and size are drastically reduced. Another ideas is a "combing" computer which is driven by its user repeatedly sliding some object through the mechanism (as if combing it) which performs the steps (sequential computation) and changes the state (which is either stored inside the computer or in the combing object).
BONUS THOUGHT: We have gotten so much used to using our current electronic digital computers for everything that sometimes we forget that at simulating actual physical reality they may still fail (or just be very overcomplicated) compared to a mechanical simulation which USES the physical reality itself; for example to make a simulation of a tsunami wave it may be more accurate to build an actual small model of a city and flood it with water than to make a computer simulation. That's why aerodynamic tunnels are still a thing. Ancient NASA flight simulators of space ships did use some electronics, but they did not use computer graphics to render the view from the ship, instead they used a screen projecting view from a tiny camera controlled by the simulator, moving inside a tiny environment, which basically achieved photorealistic graphics. Ideas like these may come in handy when designing mechanical computers as simulating reality is often what we want to do with the computer; for example if we want to model a [sine](sin.md) function, we don't have to go through the pain of implementing binary logic and performing iterative calculation of sine approximation, we may simply use a pendulum whose swinging draws the function simply and precisely. BONUS THOUGHT: We have gotten so much used to using our current electronic digital computers for everything that sometimes we forget that at simulating actual physical reality they may still fail (or just be very overcomplicated) compared to a mechanical simulation which USES the physical reality itself; for example to make a simulation of a tsunami wave it may be more accurate to build an actual small model of a city and flood it with water than to make a computer simulation. That's why aerodynamic tunnels are still a thing. Ancient NASA flight simulators of space ships did use some electronics, but they did not use computer graphics to render the view from the ship, instead they used a screen projecting view from a tiny camera controlled by the simulator, moving inside a tiny environment, which basically achieved photorealistic graphics. Ideas like these may come in handy when designing mechanical computers as simulating reality is often what we want to do with the computer; for example if we want to model a [sine](sin.md) function, we don't have to go through the pain of implementing binary logic and performing iterative calculation of sine approximation, we may simply use a pendulum whose swinging draws the function simply and precisely.

View file

@ -20,7 +20,7 @@ For start let's see which kinds of allocation (and their associated parts of mem
- **local variables** (including function arguments and local **variable size arrays**) - **local variables** (including function arguments and local **variable size arrays**)
- **dynamic allocation (heap memory)**: A kind of more complex manual allocation that happens at run time and is initiated by the programmer calling special functions such as `malloc` from the `stdlib` standard library, which return [pointers](pointer.md) to the allocated memory. This memory is taken from a special part of memory known as **[heap](heap.md)**. This allows to allocate, resize and deallocate potentially very big parts of memory, but requires caution as working with pointers is involved and there is a danger of **memory leaks** -- it is the responsibility of the programmer to free allocated memory with the `free` function once it is no longer needed, otherwise that memory will simply remain allocated and unusable by others (if this happens for example in a loop, the program may just start eating up more and more RAM and eventually run out of memory). Dynamic allocation is also pretty complex (it usually involves communicating with operating system and also keeping track of the structure of memory) and creates a [dependency](dependency.md) on the `stdlib` library. Some implementations of the allocation functions are also infamously slow (up to the point of some programmers resorting to program their own dynamic allocation systems). Therefore only use dynamic allocation when absolutely necessary! Dynamic allocation applies to: - **dynamic allocation (heap memory)**: A kind of more complex manual allocation that happens at run time and is initiated by the programmer calling special functions such as `malloc` from the `stdlib` standard library, which return [pointers](pointer.md) to the allocated memory. This memory is taken from a special part of memory known as **[heap](heap.md)**. This allows to allocate, resize and deallocate potentially very big parts of memory, but requires caution as working with pointers is involved and there is a danger of **memory leaks** -- it is the responsibility of the programmer to free allocated memory with the `free` function once it is no longer needed, otherwise that memory will simply remain allocated and unusable by others (if this happens for example in a loop, the program may just start eating up more and more RAM and eventually run out of memory). Dynamic allocation is also pretty complex (it usually involves communicating with operating system and also keeping track of the structure of memory) and creates a [dependency](dependency.md) on the `stdlib` library. Some implementations of the allocation functions are also infamously slow (up to the point of some programmers resorting to program their own dynamic allocation systems). Therefore only use dynamic allocation when absolutely necessary! Dynamic allocation applies to:
- **memory allocated with special functions** (`malloc`, `calloc`, `realloc`) - **memory allocated with special functions** (`malloc`, `calloc`, `realloc`)
Rule of the thumb: use the simplest thing possible, i.e. static allocation if you can, if not then automatic and only as the last option resort to dynamic allocation. The good news is that **you mostly won't need dynamic allocation** -- you basically only need it when working with data whose size can potentially be VERY big and is unknown at compile time (e.g. you need to load a WHOLE file AT ONCE which may potentially be VERY big). In other cases you can get away with static allocation (just reserving some reasonable amount of memory in advance and hope the data fits, e.g. a global array such as `int myData[DATA_MAX_SIZE]`) or automatic allocation if the data is reasonably small (i.e. you just create a variable sized array inside some function that processes the data). If you end up doing dynamic allocation, be careful, but it's not THAT hard to do it right (just pay more attention) and there are tools (e.g. [valgrind](valgrind.md)) to help you find memory leaks. However by the principles of [good design](lrs.md) **you should avoid dynamic allocation** if you can, not only because of the potential for errors and worse performance, but most importantly to avoid dependencies and complexity. Rule of the thumb: use the simplest thing possible, i.e. static allocation if you can, if not then automatic and only as the last option resort to dynamic allocation. The good news is that **you mostly won't need dynamic allocation** -- you basically only need it when working with data whose size can potentially be VERY big and is unknown at compile time (e.g. you need to load a WHOLE file AT ONCE which may potentially be VERY big). In other cases you can get away with static allocation (just reserving some reasonable amount of memory in advance and hope the data fits, e.g. a global array such as `int myData[DATA_MAX_SIZE]`) or automatic allocation if the data is reasonably small (i.e. you just create a variable sized array inside some function that processes the data). If you end up doing dynamic allocation, be careful, but it's not THAT hard to do it right (just pay more attention) and there are tools (e.g. [valgrind](valgrind.md)) to help you find memory leaks. However by the principles of [good design](lrs.md) **you should avoid dynamic allocation** if you can, not only because of the potential for errors and worse performance, but most importantly to avoid dependencies and complexity.
For [pros](pro.md): you can also create your own kind of pseudo dynamic allocation in pure C if you really want to avoid using stdlib or can't use it for some reason. The idea is to allocate a big chunk of memory statically (e.g. global `unsigned char myHeap[MY_HEAP_SIZE];`) and then create functions for allocating and freeing blocks of this static memory (e.g. `myAlloc` and `myFree` with same signatures as `malloc` and `free`). This allows you to use memory more efficiently than if you just dumbly (is it a word?) preallocate everything statically, i.e. you may need less total memory; this may be useful e.g. on [embedded](embedded.md). Yet another uber [hack](hacking.md) to "improve" this may be to allocate the "personal heap" on the stack instead of statically, i.e. you create something like a global pointer `unsigned char *myHeapPointer;` and a global variable `unsigned int myHeapSize;`, then somewhere at the beginning of `main` you compute the size `myHeapSize` and then create a local array `myHeap[myHeapSize]`, then finally set the global pointer to it as `myHeapPointer = myHeap`; the rest remains the same (your allocation function will access the heap via the global pointer). Just watch out for reinventing wheels, bugs and that you actually don't end up with a worse mess that if you took a more simple approach. Hell, you might even try to write your own garbage collection and array bound checking and whatnot, but then why just not fuck it and use an already existing abomination like [Java](java.md)? :) For [pros](pro.md): you can also create your own kind of pseudo dynamic allocation in pure C if you really want to avoid using stdlib or can't use it for some reason. The idea is to allocate a big chunk of memory statically (e.g. global `unsigned char myHeap[MY_HEAP_SIZE];`) and then create functions for allocating and freeing blocks of this static memory (e.g. `myAlloc` and `myFree` with same signatures as `malloc` and `free`). This allows you to use memory more efficiently than if you just dumbly (is it a word?) preallocate everything statically, i.e. you may need less total memory; this may be useful e.g. on [embedded](embedded.md). Yet another uber [hack](hacking.md) to "improve" this may be to allocate the "personal heap" on the stack instead of statically, i.e. you create something like a global pointer `unsigned char *myHeapPointer;` and a global variable `unsigned int myHeapSize;`, then somewhere at the beginning of `main` you compute the size `myHeapSize` and then create a local array `myHeap[myHeapSize]`, then finally set the global pointer to it as `myHeapPointer = myHeap`; the rest remains the same (your allocation function will access the heap via the global pointer). Just watch out for reinventing wheels, bugs and that you actually don't end up with a worse mess that if you took a more simple approach. Hell, you might even try to write your own garbage collection and array bound checking and whatnot, but then why just not fuck it and use an already existing abomination like [Java](java.md)? :)
@ -51,7 +51,7 @@ void myFunction(int x)
int main(void) int main(void)
{ {
int localNumberInMain = 123; // this is also allocated on stack int localNumberInMain = 123; // this is also allocated on stack
myFunction(10); // change to 10000000 to see a probable stack overflow myFunction(10); // change to 10000000 to see a probable stack overflow
@ -70,9 +70,9 @@ int main(void)
dynamicMemory[i * 128] = 123; // do something with the memory dynamicMemory[i * 128] = 123; // do something with the memory
free(dynamicMemory); // if not done, memory leak occurs! try to remove this and see :) free(dynamicMemory); // if not done, memory leak occurs! try to remove this and see :)
} }
return 0; return 0;
} }
``` ```

View file

@ -4,6 +4,8 @@
So called *modern* [software](software.md)/[hardware](hardware.md) and other *modern* [technology](technology.md) might as well be synonymous with [shitty](shit.md) [bloated](bloat.md) abusive technology. It's one of the most abused [buzzwords](buzzword.md) of today, relying (successfully) on the sheeple [shortcut thinking](shortcut_thinking.md) -- in a [capitalist](capitalism.md) [age](21st_century.md) when everything is getting progressively worse in terms of design, quality, ethicality, efficiency, etc., newer means worse, therefore modern (*newest*) means *the worst*. In other words *modern* is a term that stands for "as of yet best optimized for exploiting users". At [LRS](lrs.md) we see the term *modern* as **pejorative** -- for example whenever someone says "we work with modern technology", he is really saying "we are working with as of yet worst technology". Is it shit? Does it abuse you? Is useless? Doesn't matter, it's NEW! Basically *modern* is a word that to a retard just communicates "buy it". So called *modern* [software](software.md)/[hardware](hardware.md) and other *modern* [technology](technology.md) might as well be synonymous with [shitty](shit.md) [bloated](bloat.md) abusive technology. It's one of the most abused [buzzwords](buzzword.md) of today, relying (successfully) on the sheeple [shortcut thinking](shortcut_thinking.md) -- in a [capitalist](capitalism.md) [age](21st_century.md) when everything is getting progressively worse in terms of design, quality, ethicality, efficiency, etc., newer means worse, therefore modern (*newest*) means *the worst*. In other words *modern* is a term that stands for "as of yet best optimized for exploiting users". At [LRS](lrs.md) we see the term *modern* as **pejorative** -- for example whenever someone says "we work with modern technology", he is really saying "we are working with as of yet worst technology". Is it shit? Does it abuse you? Is useless? Doesn't matter, it's NEW! Basically *modern* is a word that to a retard just communicates "buy it".
{ [GNU](gnu.md) also warns about the word "modern": https://www.gnu.org/philosophy/words-to-avoid.html. ~drummyfish }
Modern technology is also opposed by [neoluddists](neoluddism.md), a kind of anti-technology movements whose roots go back to 19th century. The word *modern* was similarly addressed e.g. by [reactionary software](reactionary_software.md) -- it correctly identifies the word as being connected to a programming orthodoxy of [current times](21st_century.md), the one that's obsessed with creating bad technology and rejecting good technology. { I only found reactionary software after this article has been written. ~drummyfish } Modern technology is also opposed by [neoluddists](neoluddism.md), a kind of anti-technology movements whose roots go back to 19th century. The word *modern* was similarly addressed e.g. by [reactionary software](reactionary_software.md) -- it correctly identifies the word as being connected to a programming orthodoxy of [current times](21st_century.md), the one that's obsessed with creating bad technology and rejecting good technology. { I only found reactionary software after this article has been written. ~drummyfish }
Sometimes random people notice the issue, though there are very few. One blog (https://blog.ari.lt/b/modernism/) for example goes on to say that "modernism sucks" and the word *modern* is basically just an excuse for being [bloated](bloat.md). Those are indeed true words. Sometimes random people notice the issue, though there are very few. One blog (https://blog.ari.lt/b/modernism/) for example goes on to say that "modernism sucks" and the word *modern* is basically just an excuse for being [bloated](bloat.md). Those are indeed true words.

View file

@ -24,7 +24,7 @@ Our current western music is almost exclusively based on major and minor diatoni
| |__| |__| | |__| |__||__| | |__ | |__| |__| | |__| |__||__| | |__
... | | | | | | | | | ... ... | | | | | | | | | ...
| C | D | E | F | G | A | B | C | | C | D | E | F | G | A | B | C |
_|___|___|___|___|___|___|___|___|__ _|___|___|___|___|___|___|___|___|__
``` ```
*Tones on piano keyboard, the "big keys" are [white](white.md), the "smaller keys on top" are [black](black.md).* *Tones on piano keyboard, the "big keys" are [white](white.md), the "smaller keys on top" are [black](black.md).*
@ -56,4 +56,4 @@ TODO
- Something like a [music box](music_box.md)? - Something like a [music box](music_box.md)?
- ... - ...
What's the most [bloated](bloat.md) instrument? Theatre organ looked like one but pipe organs may be on a similar level. Orchestrion also. We have to ask ourselves what counts as an instrument, for example if we consider orchestra to be the conductor's instrument or if we consider a super bloated DAW with hundreds of VSTs an instrument, then these may aspire for most bloated ones. What's the most [bloated](bloat.md) instrument? Theatre organ looked like one but pipe organs may be on a similar level. Orchestrion also. We have to ask ourselves what counts as an instrument, for example if we consider orchestra to be the conductor's instrument or if we consider a super bloated DAW with hundreds of VSTs an instrument, then these may aspire for most bloated ones.

View file

@ -7,10 +7,10 @@ Nigger (also nigga, niBBa, nigra, N-word or chimp) is a [forbidden word](newspea
``` ```
.988886, .988886,
,88#8888889, ,88#8888889,
88#8"' \ 88#8"' \
888" O ( HEY 888" O ( HEY
/;"\ . (o_) MUH /;"\ . (o_) MUH
{(_. ( /__\ NIGGA {(_. ( /__\ NIGGA
\_/\ \__( \__/ \_/\ \__( \__/
| /\___/ | /\___/
) ( ) (
@ -58,4 +58,4 @@ In the [gender studies](gender_studies.md) circles there is an academic debate a
- [subnormal](subnormal.md) - [subnormal](subnormal.md)
- [chink](chink.md) - [chink](chink.md)
- [no-no](nono.md) - [no-no](nono.md)
- the [C-word](capitalism.md) - the [C-word](capitalism.md)

View file

@ -70,15 +70,15 @@ There are different types of noise characterized by their properties such as num
- **explicit vs implicit**: Values of an implicit noise can relatively simply and quickly be computed at any given point in space whereas explicit noises require processing as a whole and therefore storage of the whole generated noise in memory. - **explicit vs implicit**: Values of an implicit noise can relatively simply and quickly be computed at any given point in space whereas explicit noises require processing as a whole and therefore storage of the whole generated noise in memory.
- **tiling**: Similarly to [procedural](procgen.md) [textures](texture.md), a noise generated by an algorithm may be tiling, i.e. not having visible seams when repeated in certain dimensions. - **tiling**: Similarly to [procedural](procgen.md) [textures](texture.md), a noise generated by an algorithm may be tiling, i.e. not having visible seams when repeated in certain dimensions.
- ... - ...
``` ```
..----.. ..----..
.'' ''. .'' ''.
..'' '. ..... ..'' '. .....
'''' ' ..'' '''--.. '''' ' ..'' '''--..
'. .'' ''.. '. .'' ''..
'. ..' ''' '. ..' '''
''...'' ''...''
octave1 octave1
+ +
@ -94,14 +94,14 @@ There are different types of noise characterized by their properties such as num
octave3 octave3
= =
.. ..
.'' '. .'' '.
-' ''.-'-. -' ''.-'-.
... .. ' -'''--... ... .. ' -'''--...
' '' ' . ' '' ' .
'-. -' -.. .. .' '-. -' -.. .. .'
-. -' ' '' -. -' ' ''
'...-.--'' '...-.--''
fractal noise fractal noise
@ -115,4 +115,4 @@ A super simple "poor man's noise" that can be of use sometimes is **coin flip no
TODO: code for the above, maybe even a one liner for white noise TODO: code for the above, maybe even a one liner for white noise
TODO: actual Perlin noise etc., also some nice noise that's just adding some random sine waves in a fractal fashion, like a one line formula TODO: actual Perlin noise etc., also some nice noise that's just adding some random sine waves in a fractal fashion, like a one line formula

View file

@ -35,9 +35,9 @@ Here are some [fun](fun.md) facts about numbers:
k \___\_ : , k \___\_ : ,
\_\_: 1 2 3 4 \_\_: 1 2 3 4
- - -~|~-~-~-~-~|~-~-~-~-~+~-~-|-~-~|~-~-~|~-~|~-~-~-|-~|~|~-~-~-~|~- - - - - -~|~-~-~-~-~|~-~-~-~-~+~-~-|-~-~|~-~-~|~-~|~-~-~-|-~|~|~-~-~-~|~- - -
-2 -1 0: 1/2 , phi e pi real line -2 -1 0: 1/2 , phi e pi real line
= i^2 : = 0.5 , ~= ~= ~= 3.14... (real numbers) = i^2 : = 0.5 , ~= ~= ~= 3.14... (real numbers)
: , 1.61... 2.71... : , 1.61... 2.71...
-i ~+~ ~ ~ ~ ~+ -i ~+~ ~ ~ ~ ~+
: 1 - i : 1 - i
. .
@ -198,7 +198,7 @@ While mathematicians work mostly with infinite number sets and all kind of "weir
- **[quaternion](quaternion.md)**: Analogous to mathematical quaternions. - **[quaternion](quaternion.md)**: Analogous to mathematical quaternions.
- **symbolic**: Used in some specialized mathematical software to perform symbolic computation, i.e. computation done in a human-like way, by manipulating symbols without using concrete values that would have to resort to approximation. - **symbolic**: Used in some specialized mathematical software to perform symbolic computation, i.e. computation done in a human-like way, by manipulating symbols without using concrete values that would have to resort to approximation.
- ... - ...
However some programming languages, such as [Lisp](lisp.md), sometimes treat numbers in very abstract, more mathematical ways (for the price of some performance loss and added [complexity](bloat.md)) such as exactly handling rational numbers with arbitrary precision, distinguishing between exact and inexact numbers etc. However some programming languages, such as [Lisp](lisp.md), sometimes treat numbers in very abstract, more mathematical ways (for the price of some performance loss and added [complexity](bloat.md)) such as exactly handling rational numbers with arbitrary precision, distinguishing between exact and inexact numbers etc.
## Notable Numbers ## Notable Numbers

6
oop.md
View file

@ -132,7 +132,7 @@ Cat::Cat(const char *name): Animal(name)
{ {
this->treesClimbed = 0; this->treesClimbed = 0;
} }
Dog::Dog(const char *name): Animal(name) Dog::Dog(const char *name): Animal(name)
{ {
this->ballFetched = 0; this->ballFetched = 0;
@ -307,7 +307,7 @@ int main(void)
for (int i = 0; i < ANIMALS; ++i) for (int i = 0; i < ANIMALS; ++i)
{ {
printf("%s: ",AnimalGetName(animals[i])); printf("%s: ",AnimalGetName(animals[i]));
animals[i]->makeSound(animals[i]); animals[i]->makeSound(animals[i]);
putchar('\n'); putchar('\n');
} }
@ -383,4 +383,4 @@ int main(void)
} }
``` ```
Notice the lack of bullshit. OOPers will argue something about scalability or something, but that's argument of [bloat](bloat.md) so it's invalid -- basically they tell you "just wait till you have 10 million lines of code, then it becomes elegant", but of course, such code is already bad only by its size -- code of such size should never be written. They will also likely invent some highly artificial example tailored to suit OOP which you will however never meet in practice -- you can safely ignore these. Notice the lack of bullshit. OOPers will argue something about scalability or something, but that's argument of [bloat](bloat.md) so it's invalid -- basically they tell you "just wait till you have 10 million lines of code, then it becomes elegant", but of course, such code is already bad only by its size -- code of such size should never be written. They will also likely invent some highly artificial example tailored to suit OOP which you will however never meet in practice -- you can safely ignore these.

View file

@ -1,19 +1,20 @@
# Optimization # Optimization
Optimization means making a program more efficient in terms of consumption of some computing resource or by any similar metric, commonly aiming for greater execution speed or lower memory usage (but also e.g. lower power consumption, lower network usage etc.) while preserving how the program functions externally; this can be done manually (by rewriting parts of your program) or automatically (typically by [compiler](compiler.md) when it's translating your program). Unlike [refactoring](refactoring.md), which aims primarily for a better readability of source code, optimization changes the inner behavior of the executed program to a more optimal one. Apart from optimizing programs/[algorithms](algorithm.md) we may also more widely talk about optimizing e.g. [data structures](data_structure.md), file formats, [hardware](hardware.md), [protocol](protocol.md) and so on. Optimization means making a program more efficient in terms of some computing resource usage or by any similar metric, commonly aiming for higher execution speed or lower memory usage (but also e.g. lower power consumption, lower [network](network.md) speed demand etc.) while preserving how the program functions externally; this can be done manually (by rewriting parts of your program) or automatically (typically by [compiler](compiler.md) when it's translating your program). Unlike [refactoring](refactoring.md), which aims primarily for a better readability of source code, optimization changes the inner behavior of the executed program to a more optimal one. Apart from optimizing programs/[algorithms](algorithm.md) we may also more widely talk about optimizing e.g. [data structures](data_structure.md), file formats, [hardware](hardware.md), [protocol](protocol.md) and so on.
## Manual Optimization ## Manual Optimization
These are optimizations you do yourself by writing better code. These are optimizations you do yourself by writing better code or fiddling with how you compile your code.
### General Tips'N'Tricks ### General Tips'N'Tricks
These are mainly for [C](c.md), but may be usable in other languages as well. These are mainly for [C](c.md), but may be usable in other languages as well.
- **Tell your compiler to actually optimize** (`-O3`, `-Os` flags etc.). Also check out further compiler flags that may help you turn off unnecessary things you don't need, AND try out different compilers, some may just produce better code. If you are brave also check even more aggressive flags like `-Ofast` and `-Oz`, which may be even faster than `-03`, but may break your program too. - **Tell your compiler to actually auto optimize** (`-O3`, `-Os` flags etc.). Also check out further compiler flags that may help you turn off unnecessary things you don't need, AND try out different compilers, some may just produce better code. If you are brave also check even more aggressive flags like `-Ofast` and `-Oz`, which may be even faster than `-03`, but may break your program too.
- **[gprof](gprof.md) is a utility you can use to profile your code**. - **Watch out: what's fast on one platform may be slow on another -- know your platform and compiler**. This depends on the [instruction set](isa.md) as well as on compiler, operating system, library implementation, available hardware, [driver](driver.md) implementation and other details. In the end you always need to test on the specific platform to be sure about how fast it will run. For example with simple compilers that don't do much auto optimizations you may want to do clever tricks to optimize manually, which may however in turn confuse smarter compilers that optimize well but rely on idiomatic code, i.e. optimizing something for one platform may it slower on another platform. A good approach is probably to optimize for the weakest platform you want to support -- if it runs fasts on a weak platform, a "better" platform will most likely still run it fast (even if not optimally).
- **[gprof](gprof.md) is a utility you can use to profile your code**. You can also program your own [profiling](profiling.md) but be careful, it's not trivial to do it well.
- **`<stdint.h>` has fast type nicknames**, types such as `uint_fast32_t` which picks the fastest type of at least given width on given platform. - **`<stdint.h>` has fast type nicknames**, types such as `uint_fast32_t` which picks the fastest type of at least given width on given platform.
- **Actually measure the performance** to see if your optimizations work or not. Sometimes things behave counterintuitively and you end up making your program perform worse by trying to optimize it! Also make sure that you MEASURE THE PERFORMANCE CORRECTLY, many beginners for example just try to measure run time of a single simple function call which doesn't really work, you want to try to measure something like a million of such function calls in a loop and then average the time. - **Actually measure the performance** to see if your optimizations work or not. Sometimes things behave counterintuitively and you end up making your program perform worse by trying to optimize it! Also make sure that you MEASURE THE PERFORMANCE CORRECTLY, many beginners for example just try to measure run time of a single simple function call which doesn't really work, you want to try to measure something like a million of such function calls in a loop and then average the time; also make sure the compiler doesn't auto remove your code if it happens to have no effect.
- **Keywords such as `inline`, `static`, `const` and `register` can help compiler optimize well**. - **Keywords such as `inline`, `static`, `const` and `register` can help compiler optimize well**.
- **Optimize the [bottlenecks](bottleneck.md)!** Optimizing in the wrong place is a complete waste of time. If you're optimizing a part of code that's taking 1% of your program's run time, you will never speed up your program by more than that 1% even if you speed up the specific part by 10000%. Bottlenecks are usually inner-most loops of the main program loop, you can identify them with [profiling](profiling.md). A typical bottleneck code is for example a [shader](shader.md) that processes millions of pixels per second. Generally initialization code that runs only once in a long time doesn't need much optimization -- no one is going to care if a program starts up 1 millisecond faster (but of course in special cases such as launching many processes this may start to matter). - **Optimize the [bottlenecks](bottleneck.md)!** Optimizing in the wrong place is a complete waste of time. If you're optimizing a part of code that's taking 1% of your program's run time, you will never speed up your program by more than that 1% even if you speed up the specific part by 10000%. Bottlenecks are usually inner-most loops of the main program loop, you can identify them with [profiling](profiling.md). A typical bottleneck code is for example a [shader](shader.md) that processes millions of pixels per second. Generally initialization code that runs only once in a long time doesn't need much optimization -- no one is going to care if a program starts up 1 millisecond faster (but of course in special cases such as launching many processes this may start to matter).
- **You can almost always trade space (memory usage) for time (CPU demand) and vice versa** and you can also fine-tune this. You typically gain speed by [precomputation](precomputation.md) ([look up tables](lut.md), more demanding on memory) and memory with [compression](compression.md) (more demanding on CPU). - **You can almost always trade space (memory usage) for time (CPU demand) and vice versa** and you can also fine-tune this. You typically gain speed by [precomputation](precomputation.md) ([look up tables](lut.md), more demanding on memory) and memory with [compression](compression.md) (more demanding on CPU).
@ -29,8 +30,8 @@ These are mainly for [C](c.md), but may be usable in other languages as well.
- **Use powers of 2** (1, 2, 4, 8, 16, 32, ...) whenever possible, this is efficient thanks to computers working in [binary](binary.md). Not only may this help nice utilization and alignment of memory, but mainly multiplication and division can be optimized by the compiler to mere bit shifts which is a tremendous speedup. - **Use powers of 2** (1, 2, 4, 8, 16, 32, ...) whenever possible, this is efficient thanks to computers working in [binary](binary.md). Not only may this help nice utilization and alignment of memory, but mainly multiplication and division can be optimized by the compiler to mere bit shifts which is a tremendous speedup.
- **Memory alignment usually helps speed**, i.e. variables at "nice addresses" (usually multiples of the platform's native integer size) are faster to access, but this may cost some memory (the gaps between aligned data). - **Memory alignment usually helps speed**, i.e. variables at "nice addresses" (usually multiples of the platform's native integer size) are faster to access, but this may cost some memory (the gaps between aligned data).
- **Write [cache-friendly](cache-friendly.md) code** (minimize long jumps in memory). - **Write [cache-friendly](cache-friendly.md) code** (minimize long jumps in memory).
- **Compare to [0](zero.md) rather than other values**. There's usually an instruction that just checks the zero flag which is faster than loading and comparing two arbitrary numbers. - **Compare to [zero](zero.md) rather than other values**. There's usually an instruction that just checks the zero flag which is faster than loading and comparing two arbitrary numbers. For example in for loops where order of iteration doesn't matter you may count down rather than up and compare if you're at zero. { E.g. under [tcc](tcc.md) I measured `for (int i = 1000; i; --i)` to save a bit of time compared to `for (int i = 0; i < 1000; ++i)`. ~drummyfish }
- **Use [bit tricks](bit_hack.md)**, hacks for manipulating binary numbers in clever ways only using very basic operations without which one might naively write complex inefficient code with loops and branches. Example of a simple bit trick is checking if a number is power of two as `!(x & (x - 1)) && x`. - **Consider [bit tricks](bit_hack.md)** (but be aware that [idiomatic](idiomatic.md) code may be better for advanced compilers), hacks for manipulating binary numbers in clever ways only using very basic operations without which one might naively write complex inefficient code with loops and branches. Example of a simple bit trick is checking if a number is power of two as `!(x & (x - 1)) && x`.
- **Consider moving computation from run time to compile time**, see [preprocessor](preprocessor.md), [macros](macro.md) and [metaprogramming](metaprogramming.md). E.g. if you make a resolution of your game constant (as opposed to a variable), the compiler will be able to partially precompute expressions with the display dimensions and so speed up your program (but you won't be able to dynamically change resolution). - **Consider moving computation from run time to compile time**, see [preprocessor](preprocessor.md), [macros](macro.md) and [metaprogramming](metaprogramming.md). E.g. if you make a resolution of your game constant (as opposed to a variable), the compiler will be able to partially precompute expressions with the display dimensions and so speed up your program (but you won't be able to dynamically change resolution).
- On some platforms such as [ARM](arm.md) the first **arguments to a function may be passed via registers**, so it may be better to have fewer parameters in functions. - On some platforms such as [ARM](arm.md) the first **arguments to a function may be passed via registers**, so it may be better to have fewer parameters in functions.
- **Passing arguments costs something**: passing a value to a function requires a push onto the stack and later its pop, so minimizing the number of parameters a function has, using global variables to pass arguments and doing things like passing structs by pointers rather than by value can help speed. { from *Game Programming Gurus* -drummyfish } - **Passing arguments costs something**: passing a value to a function requires a push onto the stack and later its pop, so minimizing the number of parameters a function has, using global variables to pass arguments and doing things like passing structs by pointers rather than by value can help speed. { from *Game Programming Gurus* -drummyfish }
@ -38,14 +39,13 @@ These are mainly for [C](c.md), but may be usable in other languages as well.
- **Use your own [caches](cache.md) where they help**, for example if you're frequently working with some database item you better pull it to memory and work with it there, then write it back once you're done (as opposed to communicating with the DB there and back). - **Use your own [caches](cache.md) where they help**, for example if you're frequently working with some database item you better pull it to memory and work with it there, then write it back once you're done (as opposed to communicating with the DB there and back).
- **[Single compilation unit](single_compilation_unit.md) (one big program without [linking](linking.md)) can help compiler optimize better** because it can see the whole code at once, not just its parts. It will also make your program compile faster. - **[Single compilation unit](single_compilation_unit.md) (one big program without [linking](linking.md)) can help compiler optimize better** because it can see the whole code at once, not just its parts. It will also make your program compile faster.
- Search literature for **algorithms with better [complexity class](complexity_class.md)** ([sorts](sorting.md) are a nice example). - Search literature for **algorithms with better [complexity class](complexity_class.md)** ([sorts](sorting.md) are a nice example).
- For the sake of simple computers such as [embedded](embedded.md) platforms **avoid [floating point](floating_point.md)** as that is often painfully slowly emulated in software. Use [fixed point](fixed_point.md), or at least offer it as a [fallback](fallback.md). This also applies to other hardware requirements such as [GPU](gpu.md) or sound cards: while such hardware accelerates your program on computers that have the hardware, making use of it may lead to your program being slower on computers that lack it. - For the sake of simple computers such as [embedded](embedded.md) platforms **avoid [floating point](floating_point.md)** as that is often painfully slowly emulated in software (and also inserts additional code, making the executable bigger). Use [fixed point](fixed_point.md), or at least offer it as a [fallback](fallback.md). This also applies to other hardware requirements such as [GPU](gpu.md) or sound cards: while such hardware accelerates your program on computers that have the hardware, making use of it may lead to your program being slower on computers that lack it.
- **Factoring out invariants from loops and early branching can create a speed up**: it's sometimes possible to factor things out of loops (or even long non-looping code that just repeats some things), i.e. instead of branching inside the loop create two versions of the loop and branch in front of them. This is a kind of space-time tradeoff. Consider e.g. `while (a) if (b) func1(); else func2();` -- if *b* doesn't change inside the loop, you can rewrite this as `if (b) while (a) func1(); else while (a) func2();`. Or in `while (a) b += c * d;` if *c* and *d* don't change (are invariant), we can rewrite to `cd = c * d; while (a) b += cd;`. And so on. - **Factoring out invariants from loops and early branching can create a speed up**: it's sometimes possible to factor things out of loops (or even long non-looping code that just repeats some things), i.e. instead of branching inside the loop create two versions of the loop and branch in front of them. This is a kind of space-time tradeoff. Consider e.g. `while (a) if (b) func1(); else func2();` -- if *b* doesn't change inside the loop, you can rewrite this as `if (b) while (a) func1(); else while (a) func2();`. Or in `while (a) b += c * d;` if *c* and *d* don't change (are invariant), we can rewrite to `cd = c * d; while (a) b += cd;`. And so on.
- **Division can be replaced by multiplication by [reciprocal](reciprocal.md)**, i.e. *x / y = x * 1/y*. The point is that multiplication is usually faster than division. This may not help us when performing a single division by variable value (as we still have to divide 1 by *y*) but it does help when we need to divide many numbers by the same variable number OR when we know the divisor at compile time; we save time by precomputing the reciprocal before a loop or at compile time. Of course this can also easily be done with [fixed point](fixed_point.md) and integers! - **Division can be replaced by multiplication by [reciprocal](reciprocal.md)**, i.e. *x / y = x * 1/y*. The point is that multiplication is usually faster than division. This may not help us when performing a single division by variable value (as we still have to divide 1 by *y*) but it does help when we need to divide many numbers by the same variable number OR when we know the divisor at compile time; we save time by precomputing the reciprocal before a loop or at compile time. Of course this can also easily be done with [fixed point](fixed_point.md) and integers!
- **Consider the difference between logical and bitwise operators!** For example [AND](and.md) and [OR](or.md) boolean functions in C have two variants, one bitwise (`&` and `|`) and one logical (`&&` and `||`) -- they behave a bit differently but sometimes you may have a choice which one to use, then consider this: bitwise operators usually translate to only a single fast (and small) instruction while the logical ones usually translate to a branch (i.e. multiple instructions with potentially slow jumps), however logical operators may be faster because they are evaluated as [short circuit](short_circuit_eval.md) (e.g. if first operand of OR is true, second operand is not evaluated at all) while bitwise operators will evaluate all operands. - **Consider the difference between logical and bitwise operators!** For example [AND](and.md) and [OR](or.md) boolean functions in C have two variants, one bitwise (`&` and `|`) and one logical (`&&` and `||`) -- they behave a bit differently but sometimes you may have a choice which one to use, then consider this: bitwise operators usually translate to only a single fast (and small) instruction while the logical ones usually translate to a branch (i.e. multiple instructions with potentially slow jumps), however logical operators may be faster because they are evaluated as [short circuit](short_circuit_eval.md) (e.g. if first operand of OR is true, second operand is not evaluated at all) while bitwise operators will evaluate all operands.
- **Consider the pros and cons of using indices vs pointers**: When working with arrays you usually have the choice of using either pointers or indices, each option has advantages and disadvantages; working with pointers may be faster and produce smaller code (fewer instructions), but array indices are portable, may be smaller and safer. E.g. imagine you store your game sprites as a continuous array of images in RAM and your program internally precomputes a table that says where each image starts -- here you can either use pointers (which say directly the memory address of each image) or indices (which say the offset from the start of the big image array): using indices may be better here as the table may potentially be smaller (an index into relatively small array doesn't have to be able to keep any possible memory address) and the table may even be stored to a file and just loaded next time (whereas pointers can't because on next run the memory addresses may be different), however you'll need a few extra instructions to access any image (adding the index to the array pointer), which will however most definitely be negligible. - **Consider the pros and cons of using indices vs pointers**: When working with arrays you usually have the choice of using either pointers or indices, each option has advantages and disadvantages; working with pointers may be faster and produce smaller code (fewer instructions), but array indices are portable, may be smaller and safer. E.g. imagine you store your game sprites as a continuous array of images in RAM and your program internally precomputes a table that says where each image starts -- here you can either use pointers (which say directly the memory address of each image) or indices (which say the offset from the start of the big image array): using indices may be better here as the table may potentially be smaller (an index into relatively small array doesn't have to be able to keep any possible memory address) and the table may even be stored to a file and just loaded next time (whereas pointers can't because on next run the memory addresses may be different), however you'll need a few extra instructions to access any image (adding the index to the array pointer), which will however most definitely be negligible.
- **Reuse variables to save space**. A warning about this one: readability may suffer, mainstreamers will tell you you're going against "good practice", and some compilers may do this automatically anyway. Be sure to at least make this clear in your comments. Anyway, on a lower level and/or with dumber compilers you can just reuse variables that you used for something else rather than creating a new variable that takes additional RAM; of course a prerequisite for "merging" variables is that the variables aren't used at the same time. - **Reuse variables to save space**. A warning about this one: readability may suffer, mainstreamers will tell you you're going against "good practice", and some compilers may do this automatically anyway. Be sure to at least make this clear in your comments. Anyway, on a lower level and/or with dumber compilers you can just reuse variables that you used for something else rather than creating a new variable that takes additional RAM; of course a prerequisite for "merging" variables is that the variables aren't used at the same time.
- **To save memory use [compression](compression.md) techniques.** Compression doesn't always have to mean you use a typical compression algorithm such as [jpeg](jpg.md) or [LZ77](lz77.md), you may simply just throw in a few compression techniques such as [run length](run_length.md) or word dictionaries into your data structures. E.g. in [Anarch](anarch.md) maps are kept small by consisting of a small dictionary of tile definitions and map cells referring to this dictionary (which makes the cells much smaller than if each one held a complete tile definition). - **To save memory use [compression](compression.md) techniques.** (Needless to say this will however slow down the code a bit, we're trading space for time here.) Compression doesn't always have to mean you use a typical compression algorithm such as [jpeg](jpg.md) or [LZ77](lz77.md), you may simply just throw in a few compression techniques such as [run length](run_length.md) or word dictionaries into your data structures. E.g. in [Anarch](anarch.md) maps are kept small by consisting of a small dictionary of tile definitions and map cells referring to this dictionary (which makes the cells much smaller than if each one held a complete tile definition).
- **What's fast on one platform may be slow on another**. This depends on the instruction set as well as on compiler, operating system, available hardware, [driver](driver.md) implementation and other details. In the end you always need to test on the specific platform to be sure about how fast it will run. A good approach is to optimize for the weakest platform you want to support -- if it runs fasts on a weak platform, a "better" platform will most likely still run it fast.
- **Prefer preincrement over postincrement** (typically e.g. in a for loop), i.e. rather do `++i` than `i++` as the latter is a bit more complex and normally generates more instructions. - **Prefer preincrement over postincrement** (typically e.g. in a for loop), i.e. rather do `++i` than `i++` as the latter is a bit more complex and normally generates more instructions.
- **Mental calculation tricks**, e.g. multiplying by one less or more than a power of two is equal to multiplying by power of two and subtracting/adding once, for example *x * 7 = x * 8 - x*; the latter may be faster as a multiplication by power of two (bit shift) and addition/subtraction may be faster than single multiplication, especially on some primitive platform without hardware multiplication. However this needs to be tested on the specific platform. Smart compilers perform these optimizations automatically, but not every compiler is high level and smart. - **Mental calculation tricks**, e.g. multiplying by one less or more than a power of two is equal to multiplying by power of two and subtracting/adding once, for example *x * 7 = x * 8 - x*; the latter may be faster as a multiplication by power of two (bit shift) and addition/subtraction may be faster than single multiplication, especially on some primitive platform without hardware multiplication. However this needs to be tested on the specific platform. Smart compilers perform these optimizations automatically, but not every compiler is high level and smart.
- **With more than two branches use switch instead of ifs** (if possible) -- it should be common knowledge but some newcomers may not know that switch is fundamentally different from if branches: switch statement generates a jump table that can branch into one of many case labels in constant time, as opposed to a series of if statements which keeps checking conditions one by one, however switch only supports conditions of exact comparison. So prefer using switch when you have many conditions to check (but know that switch can't always be used, e.g. for string comparisons). Switch also allows hacks such as label fall through which may help some optimizations. - **With more than two branches use switch instead of ifs** (if possible) -- it should be common knowledge but some newcomers may not know that switch is fundamentally different from if branches: switch statement generates a jump table that can branch into one of many case labels in constant time, as opposed to a series of if statements which keeps checking conditions one by one, however switch only supports conditions of exact comparison. So prefer using switch when you have many conditions to check (but know that switch can't always be used, e.g. for string comparisons). Switch also allows hacks such as label fall through which may help some optimizations.
@ -60,7 +60,8 @@ These are mainly for [C](c.md), but may be usable in other languages as well.
- **Optimizing [data](data.md)**: it's important to remember we can optimize both algorithm AND data, for example in a 3D game we may simplify our 3D models, remove parts of a level that will never be seen etc. - **Optimizing [data](data.md)**: it's important to remember we can optimize both algorithm AND data, for example in a 3D game we may simplify our 3D models, remove parts of a level that will never be seen etc.
- **Specialized hardware (e.g. a [GPU](gpu.md)) astronomically accelerates programs**, but as with the previous point, portablity and simplicity greatly suffers, your program becomes bloated and gains dependencies, always consider using specialized hardware and offer software fallbacks. - **Specialized hardware (e.g. a [GPU](gpu.md)) astronomically accelerates programs**, but as with the previous point, portablity and simplicity greatly suffers, your program becomes bloated and gains dependencies, always consider using specialized hardware and offer software fallbacks.
- **Smaller code may also be faster** as it allows to fit more instructions into [cache](cache.md). - **Smaller code may also be faster** as it allows to fit more instructions into [cache](cache.md).
- Do not optimize everything and for any cost: optimization often makes the code more cryptic, it may [bloat](bloat.md) it, bring in more bugs etc. Only optimize if it is worth the prize. { from *Game Programming Gurus* -drummyfish } - Do not optimize everything and for any cost: optimization often makes the code more cryptic, it may [bloat](bloat.md) it, bring in more bugs etc. Only optimize if it is worth the reward. { from *Game Programming Gurus* -drummyfish }
- ...
### When To Actually Optimize? ### When To Actually Optimize?

View file

@ -121,9 +121,9 @@ int main(void)
{ {
for (int i = 0; i < SCREEN_W * SCREEN_H; ++i) for (int i = 0; i < SCREEN_W * SCREEN_H; ++i)
screen[i] = 0; screen[i] = 0;
SDL_Init(0); SDL_Init(0);
window = SDL_CreateWindow("sdl",SDL_WINDOWPOS_UNDEFINED, window = SDL_CreateWindow("sdl",SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,SCREEN_W,SCREEN_H,SDL_WINDOW_SHOWN); SDL_WINDOWPOS_UNDEFINED,SCREEN_W,SCREEN_H,SDL_WINDOW_SHOWN);
@ -180,4 +180,4 @@ You'll get the SDL version.
A great example of this kind of portable design can be seen e.g. in well written **[compilers](compiler.md)** that separate their architecture into an frontend and backend -- imagine we are writing for example a [C](c.md) compiler. The parser of C syntax can be easily written in a portable way, we simply write functions that work with text, however we find difficulty in asking what [instruction set](isa.md) we will compile to. If we choose one, such as [x86](x86.md), then we will not only write an x86 specific code generator, but also e.g. an x86 specific [optimizer](optimization.md); the part of the compiler that may get so complex that it ends up being bigger than the rest of the code. What if then we also want to support another ISA such as [Arm](arm.md) or [RISC-V](risc_v.md), will we have to rewrite our painstakingly written optimizer for those architectures from scratch? The solution is the same as explained above in regards to I/O: we make an abstraction above the instruction set, here called an [intermediate representation](intermediate_representation.md), usually some [bytecode](bytecode.md), i.e. the compiler first translates C to the abstract bytecode, then we may perform all the complex optimizations on this bytecode, and only then, in the last moment, we relatively simply translate this bytecode to whatever specific instruction set. A great example of this kind of portable design can be seen e.g. in well written **[compilers](compiler.md)** that separate their architecture into an frontend and backend -- imagine we are writing for example a [C](c.md) compiler. The parser of C syntax can be easily written in a portable way, we simply write functions that work with text, however we find difficulty in asking what [instruction set](isa.md) we will compile to. If we choose one, such as [x86](x86.md), then we will not only write an x86 specific code generator, but also e.g. an x86 specific [optimizer](optimization.md); the part of the compiler that may get so complex that it ends up being bigger than the rest of the code. What if then we also want to support another ISA such as [Arm](arm.md) or [RISC-V](risc_v.md), will we have to rewrite our painstakingly written optimizer for those architectures from scratch? The solution is the same as explained above in regards to I/O: we make an abstraction above the instruction set, here called an [intermediate representation](intermediate_representation.md), usually some [bytecode](bytecode.md), i.e. the compiler first translates C to the abstract bytecode, then we may perform all the complex optimizations on this bytecode, and only then, in the last moment, we relatively simply translate this bytecode to whatever specific instruction set.
Programming languages, operating systems and other "platforms" also usually employ [self hosting](self_hosting.md) to greatly increase portability -- you will most often see a serious programming language written in itself and if not, then at very least e.g. its standard library will be written as such. See also [bootstrapping](bootstrapping.md). Programming languages, operating systems and other "platforms" also usually employ [self hosting](self_hosting.md) to greatly increase portability -- you will most often see a serious programming language written in itself and if not, then at very least e.g. its standard library will be written as such. See also [bootstrapping](bootstrapping.md).

View file

@ -105,20 +105,20 @@ int isPrime(int n)
{ {
if (n < 4) if (n < 4)
return n > 1; return n > 1;
if (n % 2 == 0 || n % 3 == 0) if (n % 2 == 0 || n % 3 == 0)
return 0; return 0;
int test = 6; int test = 6;
while (test <= n / 2) // replace n / 2 by sqrt(n) if available while (test <= n / 2) // replace n / 2 by sqrt(n) if available
{ {
if (n % (test + 1) == 0 || n % (test - 1) == 0) if (n % (test + 1) == 0 || n % (test - 1) == 0)
return 0; return 0;
test += 6; test += 6;
} }
return 1; return 1;
} }
``` ```

View file

@ -23,7 +23,7 @@ OK, now the key thing to becoming a programmer is learning a [programming langua
**Can you become a good programmer when you're old?** Well, as with everything to become a SERIOUSLY good programmer you should have probably started before the age of 20, the majority of the legend programmers started before 10, it's just like with sports or becoming an excellent musician. But with enough enthusiasm and endurance you can become a pretty good programmer at any age, just like you can learn to play an instrument or run marathon basically at any age, it will just take longer and a lot of energy. You don't even have to aim to become very good, becoming just average is enough to write simple gaymes and have a bit of fun in life :) Just don't try to learn programming because it seems cool, because you want to look like movie haxor, gain followers on youtube or because you need a job -- if you're not having genuine fun just thinking before sleep about how to swap two variables without using a temporary variable, programming is probably not for you. **Can you become a good programmer if you're black or [woman](woman.md)?** No. :D Ok, maybe you can, but all the above applies, don't do it for politics or money or followers -- if you become a seriously based programmer (from [LRS](lrs.md) point of view) of unlikely minority, we'll be more than happy to put an apology here, in ALL CAPS and bold letters :) Hopefully this will inspire someone... **Can you become a good programmer when you're old?** Well, as with everything to become a SERIOUSLY good programmer you should have probably started before the age of 20, the majority of the legend programmers started before 10, it's just like with sports or becoming an excellent musician. But with enough enthusiasm and endurance you can become a pretty good programmer at any age, just like you can learn to play an instrument or run marathon basically at any age, it will just take longer and a lot of energy. You don't even have to aim to become very good, becoming just average is enough to write simple gaymes and have a bit of fun in life :) Just don't try to learn programming because it seems cool, because you want to look like movie haxor, gain followers on youtube or because you need a job -- if you're not having genuine fun just thinking before sleep about how to swap two variables without using a temporary variable, programming is probably not for you. **Can you become a good programmer if you're black or [woman](woman.md)?** No. :D Ok, maybe you can, but all the above applies, don't do it for politics or money or followers -- if you become a seriously based programmer (from [LRS](lrs.md) point of view) of unlikely minority, we'll be more than happy to put an apology here, in ALL CAPS and bold letters :) Hopefully this will inspire someone...
**Which programming language to start with?** This is the big question. Though languages such as [Python](python.md) or [JavaScript](javascript.md) are objectively really REALLY bad, they are nowadays possibly the easiest way to get into programming, so you may want to just pick one of these two, knowing you'll abandon it later to learn a true language such as [C](c.md) (and knowing the bad language will still serve you in the future in some ways, it's not a wasted time). Can you start with C right away? It's probably not impossible for a genius but it will be VERY hard and you'll most likely end up failing, overwhelmed, frustrated and never returning to programming again. In *How To Become A Hacker* ESR actually recommends to learn C, Lisp or [Go](golang.md) as the first language, but that recommendation comes to aspiring hackers, i.e. the most talented and ambitious programmers, so think about whether you fit this category. Absolutely do NOT even consider [C#](c_sharp.md) (shit, unusable), [Java](java.md) (shit, slow, bloated, unusable), [C++](cpp.md) (like C but shit and more complicated), [Haskell](haskell.md) (non-traditional, hard), [Rust](rust.md) (shit, bad design, unusable), [Go](go.md) (prolly hard), [Lisp](lisp.md) (non-traditional), [Prolog](prolog.md) (lol) and similar languages -- you may explore these later. Whichever language you pick for the love of god **avoid [OOP](oop.md)** -- no matter what anyone tells you, when you see a tutorial that uses "classes"/"objects" just move on, learn normal [imperative](imperative.md) programming. OOP is a huge pile of shit meme that you will learn anyway later (because everyone writes it nowadays) so that you see why it's shit and why you shouldn't use it. **Which programming language to start with?** This is the big question. Though languages such as [Python](python.md) or [JavaScript](javascript.md) are objectively really REALLY bad, they are nowadays possibly the easiest way to get into programming -- at least the "mainstream" kind of -- so you may want to just pick one of these two, knowing you'll abandon it later to learn a true language such as [C](c.md) or [Forth](forth.md) (and knowing the bad language will still serve you in the [future](future.md) in some ways, it's not a wasted time). Can you start with C right away? It's probably not impossible for a prodigy but it will be VERY hard and you'll most likely end up failing, overwhelmed, frustrated and never returning to programming again. In *How To Become A Hacker* [ESR](esr.md) actually recommends to learn C, [Lisp](lisp.md) or [Go](golang.md) as the first language, but that recommendation comes to aspiring [hackers](hacking.md), i.e. the most talented and ambitious programmers, so think about whether you fit in this category. Absolutely do NOT even consider [C#](c_sharp.md) (shit, unusable), [Java](java.md) (shit, slow, bloated, unusable), [C++](cpp.md) (like C but shit and more complicated), [Haskell](haskell.md) (not bad but non-traditional, hard), [Rust](rust.md) (shit, bad design, unusable), [Prolog](prolog.md) (lol) and similar languages -- you may explore some of them later tho (the weird ones, not the bad ones). Whichever language you pick for the love of god **avoid [OOP](oop.md)** -- no matter what anyone tells you, when you see a tutorial that uses "classes"/"objects" just move on, learn normal [imperative](imperative.md) programming. OOP is a huge pile of shit meme that you will learn anyway later (because everyone writes it nowadays) so that you see why it's shit and why you shouldn't use it. Also don't let them sell you any kind of new shiny [paradigm](paradigm.md) that's currently trending on [TikTok](tiktok.md) -- learn IMPERATIVE PROGRAMMING and cover your ears when someone talks about anything else.
{ I really started programming in [Pascal](pascal.md) at school, it was actually a good language as it worked very similarly to C and the transition later wasn't that hard, but nowadays learning Pascal doesn't make much sense anymore. ~drummyfish } { I really started programming in [Pascal](pascal.md) at school, it was actually a good language as it worked very similarly to C and the transition later wasn't that hard, but nowadays learning Pascal doesn't make much sense anymore. ~drummyfish }

View file

@ -152,8 +152,8 @@ NOTES on the table above:
- performance data: the `speed`/`mem.` column says a benchmarked estimate running time/memory consumption of the best case (best compiler, best run, ...) relateive to C (i.e. "how many times the language is worse than C"). The data may come from various sources, for example the *[The Computer Language Benchmark Game](https://sschakraborty.github.io/benchmark/task-descriptions.html)* (G), own measurement (O) etc. - performance data: the `speed`/`mem.` column says a benchmarked estimate running time/memory consumption of the best case (best compiler, best run, ...) relateive to C (i.e. "how many times the language is worse than C"). The data may come from various sources, for example the *[The Computer Language Benchmark Game](https://sschakraborty.github.io/benchmark/task-descriptions.html)* (G), own measurement (O) etc.
- implementation size: this is just very rough estimate based on the smallest implementation found, sometimes guessed and rounded to some near value (for example finding a small implementation whose main goal isn't small size we may conclude it could be written yet a bit smaller). - implementation size: this is just very rough estimate based on the smallest implementation found, sometimes guessed and rounded to some near value (for example finding a small implementation whose main goal isn't small size we may conclude it could be written yet a bit smaller).
- DT LOC is the number of [lines of code](loc.md) of our standardized [divisor tree](divisor_tree.md) program at the time of writing this - DT LOC is the number of [lines of code](loc.md) of our standardized [divisor tree](divisor_tree.md) program at the time of writing this
TODO: Tcl, Rebol TODO: Tcl, Rebol
## Interesting Languages ## Interesting Languages

View file

@ -53,18 +53,18 @@ switch (myVariable)
case 0: case 0:
doSomething(); doSomething();
break; break;
case 1: case 1:
doSomethingElse(); doSomethingElse();
break; break;
case 2: case 2:
{ {
int a = x + y; int a = x + y;
doSomethingCool(a); doSomethingCool(a);
break; break;
} }
default: default:
break; break;
} }
@ -116,4 +116,4 @@ Here is a short example applying the above shown style:
``` ```
TODO (for now see LRS projects like Anarch, small3dlib, SAF etc.) TODO (for now see LRS projects like Anarch, small3dlib, SAF etc.)
``` ```

View file

@ -28,7 +28,5 @@ Also let it be said that everyone has to find his own way of doing projects, it'
- **Milestones and psychological mini rewards are nice to keep you going**. It's nice to split the project into some milestones so that you see your "progress", it's very good if each milestone adds something visible, something you can "touch" -- for example with a game just the moment when you become able to physically move through the level always feels very rewarding, even if you've done it many times before, it's always a bit surprising what joy a simple feature can bring. Exploit this to increase joy of making your art. - **Milestones and psychological mini rewards are nice to keep you going**. It's nice to split the project into some milestones so that you see your "progress", it's very good if each milestone adds something visible, something you can "touch" -- for example with a game just the moment when you become able to physically move through the level always feels very rewarding, even if you've done it many times before, it's always a bit surprising what joy a simple feature can bring. Exploit this to increase joy of making your art.
- **Don't expect or aim for any reward other than the finished project**, don't expect/chase [money](money.md), fame, gratitude, don't expect that anyone will notice or thank you for the project. You are making it only because you want something that doesn't yet exist to exist and that's the only reward you can and should ever expect. Firstly this makes your project [selfless](selflessness.md), secondly it makes it pure, non-corruptable, only dedicated to its goal and nothing else, thirdly it spares you suffering from failed expectations. - **Don't expect or aim for any reward other than the finished project**, don't expect/chase [money](money.md), fame, gratitude, don't expect that anyone will notice or thank you for the project. You are making it only because you want something that doesn't yet exist to exist and that's the only reward you can and should ever expect. Firstly this makes your project [selfless](selflessness.md), secondly it makes it pure, non-corruptable, only dedicated to its goal and nothing else, thirdly it spares you suffering from failed expectations.
- **When you're hard stuck, go away from it for a (possibly long) while.** As they say before making decisions: "sleep on it" (maybe even many times) -- there's something about letting your mind rest for a while that makes your subconsciousness solve things, or at least make you comprehend the issue better, see it from a different angle. Therefore when stuck, go do something else -- this is also why it's preferable to have several projects, but generally it's good to just take a break and do something meditative like going for a walk, making something out of wood, doing some sport, sleeping, listening to music and so on. Stop trying to solve the issue you had and just relax for a few days, maybe weeks. It is quite possible inspiration will come from somewhere, fresh air will help you think and maybe a solution will occur to you during this time [spontaneously](zen.md), but even if it doesn't, when you come back to the project you'll be very fresh, rested, your thoughts will be sorted, unimportant stuff filtered out, it's like you've got a different man on the task who will help the desperate past self. Sometimes you get back and immediately spot a simple and elegant solution. Really, this works like [magic](magic.md). - **When you're hard stuck, go away from it for a (possibly long) while.** As they say before making decisions: "sleep on it" (maybe even many times) -- there's something about letting your mind rest for a while that makes your subconsciousness solve things, or at least make you comprehend the issue better, see it from a different angle. Therefore when stuck, go do something else -- this is also why it's preferable to have several projects, but generally it's good to just take a break and do something meditative like going for a walk, making something out of wood, doing some sport, sleeping, listening to music and so on. Stop trying to solve the issue you had and just relax for a few days, maybe weeks. It is quite possible inspiration will come from somewhere, fresh air will help you think and maybe a solution will occur to you during this time [spontaneously](zen.md), but even if it doesn't, when you come back to the project you'll be very fresh, rested, your thoughts will be sorted, unimportant stuff filtered out, it's like you've got a different man on the task who will help the desperate past self. Sometimes you get back and immediately spot a simple and elegant solution. Really, this works like [magic](magic.md).
- ... - **Stop talking to everyone.** If you want to do something, you have to quit all social media, destroy your cellphone, uninstall all chatting programs etc. In times of breaks you may turn them on again, but if you're trying to do something while there are people around, you won't do anything, it's too much of a distraction. Basically put yourself in a situation when you're stranded on a desert island and there is nothing else to do save for your project, otherwise you'll keep constantly talking to people or at least checking what they're talking about and that's going to constantly interrupt your thinking.
- ...

View file

@ -40,7 +40,7 @@ def printDivisorTree(x):
if x % i == 0: if x % i == 0:
a = i a = i
b = int(x / i) b = int(x / i)
if a >= b: if a >= b:
break break
@ -52,15 +52,15 @@ def printDivisorTree(x):
printDivisorTree(b) printDivisorTree(b)
else: else:
print(x,end="") print(x,end="")
print(")",end="") print(")",end="")
while True: # main loop, read numbers while True: # main loop, read numbers
try: try:
x = int(input("enter a number: ")) x = int(input("enter a number: "))
except ValueError: except ValueError:
break break
printDivisorTree(x) printDivisorTree(x)
print("") print("")
``` ```

File diff suppressed because it is too large Load diff

View file

@ -63,7 +63,7 @@ The core element to implement is the code for casting rays, i.e. given the squar
**Note on distance calculation and distortion**: When computing the distance of ray hit from the camera, we usually DO NOT want to use the [Euclidean](euclidean.md) distance of that point from the camera position (as is tempting) -- that would create a so called fish eye effect, i.e. looking straight into a perpendicular wall would make the wall look warped/bowled (as the part of the wall in the middle of the screen is actually closer to the camera position than the wall sides off the center, so it would by perspective laws look bigger). For non-distorted rendering we have to compute a distance that's perpendicular to the camera projection plane -- we can see the camera plane as a "canvas" onto which we project the scene (it's actually the flat computer screen that determines that we shall use such a flat projection plane), in 2D "top-down view" it is a line segment (unlike in 3D where it really is a plane, a rectangle) at a certain distance from the camera (usually conveniently chosen to be e.g. 1) whose direction is perpendicular to the direction the camera is facing. The good news is that with a little trick this distance can be computed even more efficiently than Euclidean distance, as we don't need to compute a square root! Instead we can utilize the similarity of triangles. Consider the following situation: **Note on distance calculation and distortion**: When computing the distance of ray hit from the camera, we usually DO NOT want to use the [Euclidean](euclidean.md) distance of that point from the camera position (as is tempting) -- that would create a so called fish eye effect, i.e. looking straight into a perpendicular wall would make the wall look warped/bowled (as the part of the wall in the middle of the screen is actually closer to the camera position than the wall sides off the center, so it would by perspective laws look bigger). For non-distorted rendering we have to compute a distance that's perpendicular to the camera projection plane -- we can see the camera plane as a "canvas" onto which we project the scene (it's actually the flat computer screen that determines that we shall use such a flat projection plane), in 2D "top-down view" it is a line segment (unlike in 3D where it really is a plane, a rectangle) at a certain distance from the camera (usually conveniently chosen to be e.g. 1) whose direction is perpendicular to the direction the camera is facing. The good news is that with a little trick this distance can be computed even more efficiently than Euclidean distance, as we don't need to compute a square root! Instead we can utilize the similarity of triangles. Consider the following situation:
``` ```
I-_ I-_
/ '-X / '-X
/ r.'/| / r.'/|
@ -73,7 +73,7 @@ The core element to implement is the code for casting rays, i.e. given the squar
/' | / | /' | / |
V-._-A/-----B V-._-A/-----B
'J 'J
``` ```
In the above *V* is the position of the camera (viewer) which is facing towards the point *I*, *p* is the camera plane perpendicular to *VI* at the distance 1 from *V*. Ray *r* is cast from the camera and hits the point *X*. The length of the line *r* is the Euclidean distance, however we want to find out the distance *JX = VI*, which is perpendicular to *p*. There are two similar triangles: *VCA* and *VIB*; from this it follows that *1 / VA = VI / VB*, from which we derive that *JX = VB / VA*. We can therefore calculate the perpendicular distance just from the ratio of the distances along one principal axis (X or Y). However watch out for the case when *VA = VB = 0* to not divide by zero! In such case use the other principal axis (Y). In the above *V* is the position of the camera (viewer) which is facing towards the point *I*, *p* is the camera plane perpendicular to *VI* at the distance 1 from *V*. Ray *r* is cast from the camera and hits the point *X*. The length of the line *r* is the Euclidean distance, however we want to find out the distance *JX = VI*, which is perpendicular to *p*. There are two similar triangles: *VCA* and *VIB*; from this it follows that *1 / VA = VI / VB*, from which we derive that *JX = VB / VA*. We can therefore calculate the perpendicular distance just from the ratio of the distances along one principal axis (X or Y). However watch out for the case when *VA = VB = 0* to not divide by zero! In such case use the other principal axis (Y).
@ -206,7 +206,7 @@ int castRay(int rayX, int rayY, int rayDx, int rayDy, int *dir)
// get the perpend dist. to camera plane: // get the perpend dist. to camera plane:
return (px > py) ? ((px * U) / rayDx) : ((py * U) / rayDy); return (px > py) ? ((px * U) / rayDx) : ((py * U) / rayDy);
// the following would give the fish eye effect instead // the following would give the fish eye effect instead
// return sqrt(px * px + py * py); // return sqrt(px * px + py * py);
} }
@ -291,4 +291,4 @@ How to make this more advanced? Here are some hints and tips:
- **different level geometry**: In theory the level doesn't have to be a square grid but some kind of another representation, or we may keep it a square grid but allow placement of additional shapes in it such as cylinders etc. Here you simply have to figure out how to trace the rays so as to find the first thing it hits. - **different level geometry**: In theory the level doesn't have to be a square grid but some kind of another representation, or we may keep it a square grid but allow placement of additional shapes in it such as cylinders etc. Here you simply have to figure out how to trace the rays so as to find the first thing it hits.
- **adding [billboards](billboard.md) (sprites)**: TODO - **adding [billboards](billboard.md) (sprites)**: TODO
- **reflections**: We can make our 2D raycaster a 2D [raytracer](raytracing.md), i.e. when we cast a camera ray and it hits a reflective wall (a mirror), we cast another, secondary reflected ray and trace it to see which wall it hits, i.e. which wall will get reflected in the reflective wall. - **reflections**: We can make our 2D raycaster a 2D [raytracer](raytracing.md), i.e. when we cast a camera ray and it hits a reflective wall (a mirror), we cast another, secondary reflected ray and trace it to see which wall it hits, i.e. which wall will get reflected in the reflective wall.
- **partly transparent walls**: We can make some walls partially transparent, both with [alpha blending](alpha.md) or textures with transparent pixels. In both cases we'll have to look not just for the first hit of the ray, but also for the next. - **partly transparent walls**: We can make some walls partially transparent, both with [alpha blending](alpha.md) or textures with transparent pixels. In both cases we'll have to look not just for the first hit of the ray, but also for the next.

View file

@ -30,7 +30,7 @@ Another **cool view of real numbers** is this: imagine fractions (rational numbe
``` ```
...^ numerator ...^ numerator
6 |. . . . . . . __/ 2/3 = 4/6 = 8/12 = ... 6 |. . . . . . . __/ 2/3 = 4/6 = 8/12 = ...
5 |. . . . . .__/ 5 |. . . . . .__/
4 |. . . . __/ . 4 |. . . . __/ .
@ -46,4 +46,4 @@ us -> 0 +-------------> denominator
From our point of view we can see all number, not just the fractions (which only sit on the integer grid points) -- all numbers, including real numbers, project to our field of view. Here fractions represent all the GRID points we see, i.e. a very dense set of points, however there are still gaps shining through which represent the real numbers that aren't fractions -- for example [pi](pi.md); if we shoot a ray from our standpoint in the exact angle that represents pi, the ray will go on forever without ever hitting any grid point! Such line will nearly miss some points, such as 355/113, which represents a good approximation of pi, but it will never hit any point exactly. So real numbers here are represented by the WHOLE, CONTINUOUS field of view. From our point of view we can see all number, not just the fractions (which only sit on the integer grid points) -- all numbers, including real numbers, project to our field of view. Here fractions represent all the GRID points we see, i.e. a very dense set of points, however there are still gaps shining through which represent the real numbers that aren't fractions -- for example [pi](pi.md); if we shoot a ray from our standpoint in the exact angle that represents pi, the ray will go on forever without ever hitting any grid point! Such line will nearly miss some points, such as 355/113, which represents a good approximation of pi, but it will never hit any point exactly. So real numbers here are represented by the WHOLE, CONTINUOUS field of view.
**Are there bigger sets than those of real numbers?** Of course, a superset of real number is e.g. that of [complex numbers](complex_number.md) and [quaternions](quaternion.md), though they still have the same cardinality. But there are even sets that have bigger cardinality than reals, e.g. the set of all subsets of real numbers (so called [power set](power_set.md) of real numbers). In fact there are infinitely many such infinities of different cardinality. **Are there bigger sets than those of real numbers?** Of course, a superset of real number is e.g. that of [complex numbers](complex_number.md) and [quaternions](quaternion.md), though they still have the same cardinality. But there are even sets that have bigger cardinality than reals, e.g. the set of all subsets of real numbers (so called [power set](power_set.md) of real numbers). In fact there are infinitely many such infinities of different cardinality.

View file

@ -49,7 +49,7 @@ Note that even in computing we can use an infinite recursion sometimes. For exam
unsigned int factorial(unsigned int x) unsigned int factorial(unsigned int x)
{ {
unsigned int result = 1; unsigned int result = 1;
while (x > 1) while (x > 1)
{ {
result *= x; result *= x;
@ -68,7 +68,7 @@ Here is another example of elegant recursion: printing string backwards:
void readAndPrintBackwards(void) void readAndPrintBackwards(void)
{ {
int c = getchar(); int c = getchar();
if (c != EOF) if (c != EOF)
{ {
readAndPrintBackwards(); readAndPrintBackwards();
@ -93,7 +93,7 @@ readAndPrintBackwards:
<? ? <? ?
readAndPrintBackwards readAndPrintBackwards
. .
-> ->
. .
@ -106,4 +106,4 @@ How do the computers practically make recursion happen? Basically they use a [st
Another important type of recursion is **tail recursion** which happens when the recursive call in a function is the very last command. It is utilized in functional languages that use recursion instead of loops. This kind of recursion can be optimized by the compiler into basically the same code a loop would produce, so that e.g. stack won't grow tremendously. Another important type of recursion is **tail recursion** which happens when the recursive call in a function is the very last command. It is utilized in functional languages that use recursion instead of loops. This kind of recursion can be optimized by the compiler into basically the same code a loop would produce, so that e.g. stack won't grow tremendously.
Mathematical recursive functions find use in [computability](computability.md) theory where they help us (similarly to e.g. [Turing machines](turing_machine.md)) define [classes](class.md) of functions (such as primitive recursive and partial recursive) by how "computationally strong" of a computer we need to compute them. Mathematical recursive functions find use in [computability](computability.md) theory where they help us (similarly to e.g. [Turing machines](turing_machine.md)) define [classes](class.md) of functions (such as primitive recursive and partial recursive) by how "computationally strong" of a computer we need to compute them.

View file

@ -169,7 +169,7 @@ void updateAnts(void)
ants[i].chip = 1; ants[i].chip = 1;
} }
} }
ants[i].pos = newPos; ants[i].pos = newPos;
} }
} }
@ -186,7 +186,7 @@ int main(void)
ants[i].pos = rand() % (WORLD_SIZE * WORLD_SIZE); ants[i].pos = rand() % (WORLD_SIZE * WORLD_SIZE);
ants[i].chip = 0; ants[i].chip = 0;
} }
int i; int i;
while (1) while (1)
@ -204,4 +204,4 @@ int main(void)
printWorld(); printWorld();
return 0; return 0;
} }
``` ```

View file

@ -24,37 +24,37 @@ The rightmost column is where elementary cellular automata differ from each othe
The following is an output of 32 steps of rule 110 from an initial tape with one cell set to 1. Horizontal dimension represents the tape, vertical dimension represents steps/time (from top to bottom). The following is an output of 32 steps of rule 110 from an initial tape with one cell set to 1. Horizontal dimension represents the tape, vertical dimension represents steps/time (from top to bottom).
``` ```
# #
## ##
### ###
# ## # ##
##### #####
# ## # ##
## ### ## ###
### # ## ### # ##
# ####### # #######
### ## ### ##
# ## ### # ## ###
##### # ## ##### # ##
# ## ##### # ## #####
## ### # ## ## ### # ##
### # #### ### ### # #### ###
# ##### ## # ## # ##### ## # ##
### ## ######## ### ## ########
# ## #### ## # ## #### ##
##### # ## ### ##### # ## ###
# #### ### # ## # #### ### # ##
## # ### ## ##### ## # ### ## #####
### ## # ##### # ## ### ## # ##### # ##
# ######## ## ## ### # ######## ## ## ###
### ## ###### # ## ### ## ###### # ##
# ## ### # ####### # ## ### # #######
##### # #### # ## ##### # #### # ##
# ## ### ## ## ### # ## ### ## ## ###
## ### # ## ### ### # ## ## ### # ## ### ### # ##
### # ## ###### ### ## ##### ### # ## ###### ### ## #####
# ######## ### ##### # ## # ######## ### ##### # ##
### ## # ### #### ### ### ## # ### #### ###
# ## ### ### ## # ## # ## # ## ### ### ## # ## # ##
``` ```
@ -74,13 +74,13 @@ int main(void)
// init the tape: // init the tape:
for (int i = 0; i < TAPE_SIZE; ++i) for (int i = 0; i < TAPE_SIZE; ++i)
tape[i] = i == 0; tape[i] = i == 0;
// simulate: // simulate:
for (int i = 0; i < STEPS; ++i) for (int i = 0; i < STEPS; ++i)
{ {
for (int j = 0; j < TAPE_SIZE; ++j) for (int j = 0; j < TAPE_SIZE; ++j)
putchar(tape[j] ? '#' : ' '); putchar(tape[j] ? '#' : ' ');
putchar('\n'); putchar('\n');
unsigned char state = // three cell state unsigned char state = // three cell state
@ -105,4 +105,4 @@ Discovery of rule 110 is attributed to [Stephen Wolfram](wolfram.md) who introdu
- [Game Of Life](game_of_life.md) - [Game Of Life](game_of_life.md)
- [Langton's Ant](langtons_ant.md) - [Langton's Ant](langtons_ant.md)
- [interaction net](interaction_net.md) - [interaction net](interaction_net.md)

View file

@ -1,16 +1,17 @@
# Shader # Shader
Shader is a program running on the [graphics processing unit](gpu.md) (GPU), typically in many parallel instances as to utilize the GPU's highly parallel nature. As such they are simple to mid complexity programs. The word *shader* is also used more loosely to stand for any specific effect, material or look in 3D graphics (e.g. [games](games.md)), as shaders are usually the means of achieving such effects. Shader is a computer [program](program.md) running on the [graphics processing unit](gpu.md) (GPU), typically in many parallel instances so as to utilize the GPU's highly parallel nature and so achieve very high processing speed. As such shaders are simple to mid complexity programs. There are different types of shaders based on what kind of data they process -- most notable are probably fragment (also pixel) shaders that process [pixels](pixel.md) which then end up on the screen -- without explicitly mentioning what kind of shader we are talking about it is usually assumed we mean fragment shaders. The word *shader* is also used more loosely as a synonym for a special visual effect or material look in [3D graphics](3d_rendering.md) (e.g. [games](games.md)), because shaders are usually the means of achieving such effects.
Shaders are normally written in a special **shading language** such as [GLSL](glsl.md) in the [OpenGL](opengl.md) [API](api.md), [HLSL](hlsl.md) ([proprietary](proprietary.md)) in [Direct3D](d3d.md) API or the Metal shading language ([proprietary](proprietary.md)) in [Metal](metal.md) API. These languages are often similar to [C](c.md) with some additions (e.g. vector and matrix data types) and simplifications (e.g. no function [recursion](recursion.md)). High level [frameworks](framework.md) like [Blender](blender.md) many times offer [visual programming](visual_programming.md) (point-n-click) of shaders with graph/node editors. Shaders are normally written in a special **shading language** such as [GLSL](glsl.md) in the [OpenGL](opengl.md) [API](api.md), [HLSL](hlsl.md) ([proprietary](proprietary.md)) in [Direct3D](d3d.md) API or the Metal shading language ([proprietary](proprietary.md)) in [Metal](metal.md) API. These languages are often similar to [C](c.md) with some additions (e.g. vector and matrix data types) and simplifications (e.g. no function [recursion](recursion.md) or dynamic memory allocation). High level [frameworks](framework.md) like [Blender](blender.md) many times offer [visual programming](visual_programming.md) (point-n-click) of shaders with graph/node editors.
Initially (basically early 2000s) shaders were used only for graphics, i.e. to transform 3D vertices, draw triangles and compute pixel colors. Later on as GPUs became more general purpose ([GPGPU](gpgpu.md)), flexibility was added to shaders that allowed to solve more problems with the GPU and eventually general *compute* shaders appeared (OpenGL added them in version 3.3 in 2010). Initially (basically early 2000s) shaders were used only for graphics, i.e. to transform 3D vertices, draw triangles and compute pixel colors. Later on as GPUs became more general purpose ([GPGPU](gpgpu.md)), flexibility was added to shaders that allowed to solve more problems with the GPU and eventually general *compute* shaders appeared (OpenGL added them in version 3.3 in 2010).
To put shaders in the context, the flow of data is this: a [CPU](cpu.md) uploads some data (3D models, textures, ...) to the GPU and then issues a draw command -- this makes the GPU start its **[pipeline](pipeline.md)** consisting of different **stages**, e.g. the vertices of 3D models are transformed to screens space (the vertex stage), then triangles are generated and rasterized (the shading stage) and the data is output (on screen, to a buffer etc.). Some of these stages are programmable and so they have their own type of a shader. The details of the pipeline differ from API to API, but in general, depending on the type of data the shader processes (the stage), we talk about: To put shaders in the context, the flow of data is this: a [CPU](cpu.md) uploads some data (3D models, textures, ...) to the GPU and then issues a draw command -- this makes the GPU start its **[pipeline](pipeline.md)** consisting of different **stages**, e.g. the vertices of 3D models are transformed to screens space (the vertex stage), then triangles are generated and rasterized (the shading stage) and the data is output (on screen, to a buffer etc.). Some of these stages are programmable and so they have their own type of a shader. The details of the pipeline differ from API to API, but in general, depending on the type of data the shader processes (the stage), we talk about:
- **vertex shaders**: Perform per-vertex computations on 3D models, typically their transformation from their world position to the position in the camera and screen space. - **vertex shaders**: Perform per-vertex computations on 3D models, typically their transformation from their world position to the position in the camera and screen space.
- **fragment/pixel shaders**: Compute the final color of each pixel (sometimes called more generally *fragments*), i.e. work per-pixel. A typical use is to perform [texturing](texture.md) and amount of reflected light (lighting model). - **fragment/pixel shaders**: Compute the final color of each pixel (sometimes called more generally *fragments*), i.e. work per-pixel. A typical use is to perform [texturing](texture.md) and amount/color of reflected light (lighting model).
- **geometry shaders**: Advanced stage, serves to modify the geometry of 3D models (these shaders can, unlike vertex shaders, generate of discard vertices). - **geometry shaders**: Advanced stage, serves to modify the geometry of 3D models (these shaders can, unlike vertex shaders, generate of discard vertices).
- **tesselation shaders**: Advanced stage, serves for subdividing primitives to create smoother geometry. - **tesselation shaders**: Advanced stage, serves for subdividing primitives to create smoother geometry.
- **compute shaders**: Perform general computations, used e.g. for computing physics simulations, [AI](ai.md) etc. - **compute shaders**: Perform general computations, used e.g. for computing physics simulations, [AI](ai.md) etc.
- **[ray tracing](ray_tracing.md) shaders** and other specific types - **[ray tracing](ray_tracing.md) shaders** and other specific types
- ...

View file

@ -46,7 +46,7 @@ At the beginning the board is set up like this:
|. . . . . . . . .| d |. . . . . . . . .| d
|. . . . . . . . .| e |. . . . . . . . .| e
|. . . . . . . . .| f |. . . . . . . . .| f
|p p p p p p p p p| g ---------------------- |p p p p p p p p p| g ----------------------
|. b . . . . . r .| h sente promotion |. b . . . . . r .| h sente promotion
|l n s g k g s n l| i (black) zone |l n s g k g s n l| i (black) zone
""""""""""""""""" """""""""""""""""

View file

@ -33,7 +33,7 @@ Let's take a look at a simple example of how our shortcuts can be abused -- in r
After the initial step we end up with a convenient shortcut that simply states "we hate mass religion": After the initial step we end up with a convenient shortcut that simply states "we hate mass religion":
``` ```
we -. we -.
| |
| dislike | dislike
@ -49,7 +49,7 @@ We should remember that this shortcut in fact means we oppose the evil behind it
"DON'T THINK HERE" "DON'T THINK HERE"
"FOCUS ON HATING RELIGION!" "FOCUS ON HATING RELIGION!"
brainwashing barrier brainwashing barrier
| |
we -. | abuse of power we -. | abuse of power
| |_ and brainwashing | |_ and brainwashing
| | \_ ^ | | \_ ^
@ -68,4 +68,4 @@ This is how capitalism will be able to sustain itself no matter what -- even if
## See Also ## See Also
- [idiot fallacy](idiot_fallacy.md) - [idiot fallacy](idiot_fallacy.md)

22
sin.md
View file

@ -4,7 +4,7 @@ Sine, abbreviated *sin*, is a [trigonometric](trigonometry.md) [function](functi
The function is most commonly defined using a right triangle as follows. Consider the following triangle: The function is most commonly defined using a right triangle as follows. Consider the following triangle:
``` ```
/| /|
/ | / |
/ | / |
@ -26,8 +26,8 @@ The graph of the sine function is following:
1_|_ 1_|_
| .--'''--. | .--'''--.
-1/2 pi | _.'' ''._ 3/2 pi -1/2 pi | _.'' ''._ 3/2 pi
.________|________.'________|________'|________|________.' --> x .________|________.'________|________'|________|________.' --> x
'._ | _.'|0 | |'._ | _.'| '._ | _.'|0 | |'._ | _.'|
''--___--'' _|_ 1/2 pi pi ''--___--'' 2 pi ''--___--'' _|_ 1/2 pi pi ''--___--'' 2 pi
-1 | -1 |
``` ```
@ -86,7 +86,7 @@ unsigned char sin8(unsigned char x)
a -= 128; a -= 128;
flip = 1; flip = 1;
} }
if (a > 63) if (a > 63)
a = 128 - a; a = 128 - a;
@ -157,26 +157,26 @@ Furthermore there exist other nice approximations, such as the extremely accurat
/* Integer sine using Bhaskara's approx. Returns a number /* Integer sine using Bhaskara's approx. Returns a number
in <-UNIT, UNIT> interval. Argument is in radians * UNIT. */ in <-UNIT, UNIT> interval. Argument is in radians * UNIT. */
int sinInt(int x) int sinInt(int x)
{ {
int sign = 1; int sign = 1;
if (x < 0) // odd function if (x < 0) // odd function
{ {
x *= -1; x *= -1;
sign = -1; sign = -1;
} }
x %= 2 * PI; x %= 2 * PI;
if (x > PI) if (x > PI)
{ {
x -= PI; x -= PI;
sign *= -1; sign *= -1;
} }
x *= PI - x; x *= PI - x;
return sign * (16 * x) / ((5 * PI * PI - 4 * x) / UNIT); return sign * (16 * x) / ((5 * PI * PI - 4 * x) / UNIT);
} }
``` ```

View file

@ -42,7 +42,7 @@ The length of the sequence is *N = 5*, so *j* (the outer loop) will go from 0 to
``` ```
j = 0 j = 1 j = 2 j = 3 j = 0 j = 1 j = 2 j = 3
swapped swapped
i = 0 /\ /\ /\ /\ i = 0 /\ /\ /\ /\
37832 37328 33278 23378 <-- SORTED 37832 37328 33278 23378 <-- SORTED
@ -232,4 +232,4 @@ quick : AAABBCCDDEFFGHHHIIJJLLLLLMMMMNNNOOOPPPRRRSSTTTTTUUUUVVVWWWXXXYZZ, CP
## See Also ## See Also
- [searching](search.md) - [searching](search.md)
- [pathfinding](pathfinding.md) - [pathfinding](pathfinding.md)

View file

@ -40,14 +40,14 @@ Within desired precision square root can be relatively quickly computed iterativ
unsigned int sqrt(unsigned int x) unsigned int sqrt(unsigned int x)
{ {
unsigned int l = 0, r = x / 2, m; unsigned int l = 0, r = x / 2, m;
while (1) while (1)
{ {
if (r - l <= 1) if (r - l <= 1)
break; break;
m = (l + r) / 2; m = (l + r) / 2;
if (m * m > x) if (m * m > x)
r = m; r = m;
else else
@ -72,4 +72,4 @@ int32_t sqrtApprox(int32_t x)
(-1000000 / (x + 8000) + x / 512 + 142) : (-1000000 / (x + 8000) + x / 512 + 142) :
(-75000000 / (x + 160000) + x / 2048 + 565)); (-75000000 / (x + 160000) + x / 2048 + 565));
} }
``` ```

View file

@ -24,7 +24,7 @@ Tangram is a simple, yet greatly amusing old puzzle [game](game.md) in which the
Tangram usually comes as a box with the 7 pieces and a number of cards with shapes for the player to solve. Each card has on its back side a solution. Some shape are easy to solve, some are very difficult. Tangram usually comes as a box with the 7 pieces and a number of cards with shapes for the player to solve. Each card has on its back side a solution. Some shape are easy to solve, some are very difficult.
``` ```
_/| _/|
/ | _/|\_ / | _/|\_
|\_ | / | \_ |\_ | / | \_
| \| | | \_ | \| | | \_
@ -32,7 +32,7 @@ Tangram usually comes as a box with the 7 pieces and a number of cards with shap
|/ \_ ________ _/ \_ | _/ \_ |/ \_ ________ _/ \_ | _/ \_
/ \/ / _/ \|/ \ / \/ / _/ \|/ \
\_ _/_______/ _/ \_ _/ \_ _/_______/ _/ \_ _/
\_/| /_____________\_/ \_/| /_____________\_/
_/ | | _/ _/ | | _/
_/ | | _/ _/ | | _/
_/ | | _/ _/ | | _/
@ -43,7 +43,7 @@ Tangram usually comes as a box with the 7 pieces and a number of cards with shap
\_ | \_ | \_ | \_ |
_/\_ | |\| _/\_ | |\|
_/ \_ | | \_ _/ \_ | | \_
/________\| |____\ /________\| |____\
``` ```
*Two tangram shapes: bunny and stork (from 1917 book Amusements in Mathematics).* *Two tangram shapes: bunny and stork (from 1917 book Amusements in Mathematics).*
@ -68,4 +68,4 @@ TODO: some PD shapes, math, stats, ...
## See Also ## See Also
- [Soma cube](soma_cube.md) - [Soma cube](soma_cube.md)

View file

@ -17,7 +17,7 @@ Notable Temple OS features and programs are:
In his video blogs Terry talked about how technology became spoiled and that TempleOS is supposed to be [simple](minimalism.md) and [fun](fun.md). For this and other reasons the OS is limited in many way, for example: In his video blogs Terry talked about how technology became spoiled and that TempleOS is supposed to be [simple](minimalism.md) and [fun](fun.md). For this and other reasons the OS is limited in many way, for example:
- no networking - no networking
- Only runs on [x64](x64.md). - Only runs on [x86](x86.md).
- Only runs in 640x480 16 color display mode. - Only runs in 640x480 16 color display mode.
- single audio voice - single audio voice
- ring-0 only - ring-0 only

View file

@ -14,7 +14,7 @@ A basic division of transistors is following:
- **N channel**: Source and drain are made of N semiconductor put into a P semiconductor. They have a bit different properties from P channel FETs. - **N channel**: Source and drain are made of N semiconductor put into a P semiconductor. They have a bit different properties from P channel FETs.
Commonly used graphical symbols for transistor are (usually in a circle): Commonly used graphical symbols for transistor are (usually in a circle):
``` ```
E E D D E E D D
| | | | | | | |
@ -23,7 +23,7 @@ B___|.-' B___|.-' G |--' G |--'
| | | | | | | |
C C S S C C S S
BJT (NPN) BJT (PNP) FET (N) FET (P) BJT (NPN) BJT (PNP) FET (N) FET (P)
``` ```
First FET transistors were JFETs (junction-gate FET) but by today were mostly replaced by **MOSFETs** (metal-oxide-semiconductor FET), a transistor using a metal oxide layer for separating the gate terminal which gives it some nice properties over JFET. These transistors are used to implement [logic gates](logic_gate.md) e.g. using the **[CMOS](cmos.md)** fabrication process which uses complementary pairs of P and N channel FETs so that e.g. one is always off which decreases power consumption. First FET transistors were JFETs (junction-gate FET) but by today were mostly replaced by **MOSFETs** (metal-oxide-semiconductor FET), a transistor using a metal oxide layer for separating the gate terminal which gives it some nice properties over JFET. These transistors are used to implement [logic gates](logic_gate.md) e.g. using the **[CMOS](cmos.md)** fabrication process which uses complementary pairs of P and N channel FETs so that e.g. one is always off which decreases power consumption.

View file

@ -71,12 +71,12 @@ int pointIsInTriangle(int px, int py, int tp[6])
int w2 = (tp[i1 + 1] - py) * (tp[i2] - tp[i1]) - (tp[i1] - px) * (tp[i2 + 1] - tp[i1 + 1]); int w2 = (tp[i1 + 1] - py) * (tp[i2] - tp[i1]) - (tp[i1] - px) * (tp[i2 + 1] - tp[i1 + 1]);
int sign2 = w2 > 0 ? 1 : (w2 < 0 ? -1 : 0); int sign2 = w2 > 0 ? 1 : (w2 < 0 ? -1 : 0);
if (sign * sign2 == -1) // includes edges if (sign * sign2 == -1) // includes edges
//if (sign != sign2) // excludes edges //if (sign != sign2) // excludes edges
return 0; return 0;
} }
return 1; return 1;
} }
``` ```

View file

@ -23,7 +23,7 @@ A Turing machine is composed of:
- **a set of finitely many rules** in the format *[stateFrom, inputSymbol, stateTo, outputSymbol, headShift]*, where *stateFrom* is the current state, *inputSymbol* is symbol currently under the read/write head, *stateTo* is the state the machine will transition to, *outputSymbol* is the symbol that will be written to the memory cell under read/write head and *headShift* is the direction to shift the read/write head in (either *left*, *right* or *none*). There must not be conflicting rules (ones with the same combination of *stateFrom* and *inputSymbol*). - **a set of finitely many rules** in the format *[stateFrom, inputSymbol, stateTo, outputSymbol, headShift]*, where *stateFrom* is the current state, *inputSymbol* is symbol currently under the read/write head, *stateTo* is the state the machine will transition to, *outputSymbol* is the symbol that will be written to the memory cell under read/write head and *headShift* is the direction to shift the read/write head in (either *left*, *right* or *none*). There must not be conflicting rules (ones with the same combination of *stateFrom* and *inputSymbol*).
The machine halts either when it reaches the end state, when it tries to leave the tape (go left from memory cell 0) or when it encounters a situation for which it has no defined rule. The machine halts either when it reaches the end state, when it tries to leave the tape (go left from memory cell 0) or when it encounters a situation for which it has no defined rule.
The computation works like this: the input data we want to process (for example a [string](string.md) we want to reverse) are stored in the memory before we run the machine. Then we run the machine and wait until it finishes, then we take what's present in the memory as the machine's output (i.e. for example the reversed string). That is a Turing machine doesn't have a traditional [I/O](io.md) (such as a "[printf](printf.md)" function), it only works entirely on data in memory! The computation works like this: the input data we want to process (for example a [string](string.md) we want to reverse) are stored in the memory before we run the machine. Then we run the machine and wait until it finishes, then we take what's present in the memory as the machine's output (i.e. for example the reversed string). That is a Turing machine doesn't have a traditional [I/O](io.md) (such as a "[printf](printf.md)" function), it only works entirely on data in memory!
Let's see a simple **example**: we will program a Turing machine that takes a [binary](binary.md) number on its output and adds 1 to it (for simplicity we suppose a fixed number of bits so an [overflow](overflow.md) may happen). Let us therefore suppose symbols 0 and 1 as the tape alphabet. The control unit will have the following rules: Let's see a simple **example**: we will program a Turing machine that takes a [binary](binary.md) number on its output and adds 1 to it (for simplicity we suppose a fixed number of bits so an [overflow](overflow.md) may happen). Let us therefore suppose symbols 0 and 1 as the tape alphabet. The control unit will have the following rules:
@ -95,7 +95,7 @@ Indeed, we see the number we got at the output is 0110 (6 in decimal, i.e. 5 + 1
#define SHIFT_LEFT 1 #define SHIFT_LEFT 1
#define SHIFT_RIGHT 2 #define SHIFT_RIGHT 2
unsigned int state; // 0 = start state, 0xffff = end state unsigned int state; // 0 = start state, 0xffff = end state
unsigned int headPosition; unsigned int headPosition;
unsigned char tape[CELLS]; // memory tape unsigned char tape[CELLS]; // memory tape
@ -205,4 +205,4 @@ Turing machines can be used to define computable [formal languages](formal_langu
- [brainfuck](brainfuck.md) - [brainfuck](brainfuck.md)
- [busy beaver](busy_beaver.md) - [busy beaver](busy_beaver.md)
- [counter machine](counter_machine.md) - [counter machine](counter_machine.md)

2
uxn.md
View file

@ -2,7 +2,7 @@
{ WIP, researching this etcetc. ~drummyfish } { WIP, researching this etcetc. ~drummyfish }
Uxn is a [minimalist](minimalism.md) [self hosted](self_hosting.md) [stack](stack.md)-based [virtual machine](virtual_machine.md) 8bit/16bit [computer](computer.md) aiming for great [simplicity](simplicity.md) and [portability](portability.md). It is quite nice and impressive, having its own [instruction set](isa.md), [assembly](assembly.md) language, many implementations and many programs written for it already (e.g. [Left](left.md) text editor, Noodle drawing tool etc.); it was made by the author of [xxiivv](xxiivv.md) wiki (some weird [narcissist](egoism.md) self proclaimed artist that's sailing the seas or something). From the minimalist point of view uxn really seems to be going in the right direction, it is inspired by old computers such as [NES](nes.md) and [C64](c64.md), practicing real minimalism (not just [pseudominimalism](pseudominimalism.md) or just "lightweight minimalism") -- that's pretty awesome -- however its presentation is shit and while there are many [free as in freedom](free_software.md) implementations of uxn, official supplemental material to uxn (on the [xxiivv](xxiivv.md) wiki), such as its specification, is **[proprietary](proprietary.md)** ([NC](nc.md)) and therefore should be avoided and boycotted. Uxn is a [minimalist](minimalism.md) [self hosted](self_hosting.md) [stack](stack.md)-based [virtual machine](virtual_machine.md) 8bit/16bit [computer](computer.md) aiming for great [simplicity](simplicity.md) and [portability](portability.md). It is quite nice and impressive, having its own [instruction set](isa.md), [assembly](assembly.md) language, many implementations and many programs written for it already (e.g. [Left](left.md) text editor, Noodle drawing tool etc.); it was made by the author of [xxiivv](xxiivv.md) wiki (some weird [narcissist](egoism.md) self proclaimed artist that's sailing the seas or something). From the minimalist point of view uxn really seems to be going in the right direction, it is inspired by old computers such as [NES](nes.md) and [C64](c64.md), practicing real minimalism (not just [pseudominimalism](pseudominimalism.md) or just "lightweight minimalism") -- that's pretty awesome -- however its presentation is shit and while there are many [free as in freedom](free_software.md) implementations of uxn, official supplemental material to uxn (on the [xxiivv](xxiivv.md) wiki), such as its specification, is **[proprietary](proprietary.md)** ([NC](nc.md)).
Uxn is similar to other projects such as [IBNIZ](ibniz.md), and can be compared to some of [our](lrs.md) projects as well, for example [SAF](saf.md), but mainly [comun](comun.md) -- the goals of uxn and comun may be seen as significantly overlapping, aiming to create a minimalist, completely independent from-ground-up computing "stack", an extremely portable platform for minimalist programs, and they do so in a similar way (both are e.g. stack based, inspired by [Forth](forth.md)). **To quickly compare uxn and comun**: comun is more of a pure programming [language](language.md) focusing only on expressing algorithms without talking about [I/O](io.md) or instruction sets, uxn on the other hand really is a [computer](computer.md) (even if initially only virtual), one that comes with its own instruction set, language and protocols for communication with peripheral devices, though the computer is purposefully made so that it can be implemented as a virtual machine running on other computers. Comun is a low level language but higher level than assembly (having e.g. control structures and a concept of "native integer" type), usually compiling to [bytecode](bytecode.md), while uxn is programmed directly in assembly and tied to its virtual machine's architecture and specifications. Comun is trying to stay more abstract, hardware independent and be more close to [math](math.md) notation, it doesn't assume any native integer size or working memory size, it doesn't use any English keywords, it assumes as little as possible about its platform -- it is trying to be a "better, simpler [C](c.md)". Uxn is more of a "new NES", a "practically useful [fantasy console](fantasy_console.md)", an idealization and improvement of old computers, it has a hardcoded amount of memory, specified integer size (8 or 16 bit), uses assembly with English mnemonics just like the old computers etc. As for complexity, uxn is probably a bit simpler, or rather allowing smaller implementations than those of full comun, though simplified versions of comun (such as minicomun) may possibly be as simple or simpler than uxn and specification of full comun (a possible measure of complexity) is extremely small and will probably compare to or beat uxn. Uxn only has 32 instructions and its self hosted implementation is around 2000 bytes big, while current comun's bytecode has around 80 instructions and self hosted compiler will probably have a few thousand lines of code (as it really is a library, compiler, interpreter and simple optimizer, as opposed to mere assembler). Comun is a completely [selfless](selfless.md), absolutely [public domain](public_domain.md) [free software](free_software.md), while uxn has a selfish proprietary ([NC](nc.md)) specification. Uxn is similar to other projects such as [IBNIZ](ibniz.md), and can be compared to some of [our](lrs.md) projects as well, for example [SAF](saf.md), but mainly [comun](comun.md) -- the goals of uxn and comun may be seen as significantly overlapping, aiming to create a minimalist, completely independent from-ground-up computing "stack", an extremely portable platform for minimalist programs, and they do so in a similar way (both are e.g. stack based, inspired by [Forth](forth.md)). **To quickly compare uxn and comun**: comun is more of a pure programming [language](language.md) focusing only on expressing algorithms without talking about [I/O](io.md) or instruction sets, uxn on the other hand really is a [computer](computer.md) (even if initially only virtual), one that comes with its own instruction set, language and protocols for communication with peripheral devices, though the computer is purposefully made so that it can be implemented as a virtual machine running on other computers. Comun is a low level language but higher level than assembly (having e.g. control structures and a concept of "native integer" type), usually compiling to [bytecode](bytecode.md), while uxn is programmed directly in assembly and tied to its virtual machine's architecture and specifications. Comun is trying to stay more abstract, hardware independent and be more close to [math](math.md) notation, it doesn't assume any native integer size or working memory size, it doesn't use any English keywords, it assumes as little as possible about its platform -- it is trying to be a "better, simpler [C](c.md)". Uxn is more of a "new NES", a "practically useful [fantasy console](fantasy_console.md)", an idealization and improvement of old computers, it has a hardcoded amount of memory, specified integer size (8 or 16 bit), uses assembly with English mnemonics just like the old computers etc. As for complexity, uxn is probably a bit simpler, or rather allowing smaller implementations than those of full comun, though simplified versions of comun (such as minicomun) may possibly be as simple or simpler than uxn and specification of full comun (a possible measure of complexity) is extremely small and will probably compare to or beat uxn. Uxn only has 32 instructions and its self hosted implementation is around 2000 bytes big, while current comun's bytecode has around 80 instructions and self hosted compiler will probably have a few thousand lines of code (as it really is a library, compiler, interpreter and simple optimizer, as opposed to mere assembler). Comun is a completely [selfless](selfless.md), absolutely [public domain](public_domain.md) [free software](free_software.md), while uxn has a selfish proprietary ([NC](nc.md)) specification.

View file

@ -29,7 +29,7 @@ ___1_|/._._._._._._._
-2 | \ -2 | \
-3 | _\| -3 | _\|
-4 | "" v -4 | "" v
-5 | -5 |
``` ```
NOTE: while for normal (scalar) variables we use letters such as *x*, *y* and *z*, for vector variables we usually use letters *u*, *v* and *w* and also put a small arrow above them as: NOTE: while for normal (scalar) variables we use letters such as *x*, *y* and *z*, for vector variables we usually use letters *u*, *v* and *w* and also put a small arrow above them as:
@ -70,7 +70,7 @@ Some of said **operations** with vectors include:
- **addition** (vector + vector = vector): Just like with numbers we can add vectors, i.e. for example if there are two forces acting on an object and we represent them by vectors, we can get the total force as a vector we get by adding the individual vectors. Addition is pretty straightforward, we simply add each component of both vectors, e.g. *u + v = [7 + 2, 6 - 3.5] = [9,2.5]*. Geometrically addition can be seen as drawing one vector from the other vector's endpoint (note that the [order doesn't matter](commutativity.md), i.e. *u + v = v + u*): - **addition** (vector + vector = vector): Just like with numbers we can add vectors, i.e. for example if there are two forces acting on an object and we represent them by vectors, we can get the total force as a vector we get by adding the individual vectors. Addition is pretty straightforward, we simply add each component of both vectors, e.g. *u + v = [7 + 2, 6 - 3.5] = [9,2.5]*. Geometrically addition can be seen as drawing one vector from the other vector's endpoint (note that the [order doesn't matter](commutativity.md), i.e. *u + v = v + u*):
``` ```
7 | 7 |
6 | _, 6 | _,
5 | __/|\u 5 | __/|\u
@ -82,7 +82,7 @@ ___1_|/_...--''____/____
-2 | \ __/ -2 | \ __/
-3 | _\|/ -3 | _\|/
-4 | "" v -4 | "" v
-5 | -5 |
``` ```

File diff suppressed because one or more lines are too long

View file

@ -3,9 +3,9 @@
This is an autogenerated article holding stats about this wiki. This is an autogenerated article holding stats about this wiki.
- number of articles: 591 - number of articles: 591
- number of commits: 871 - number of commits: 872
- total size of all texts in bytes: 4266817 - total size of all texts in bytes: 4273180
- total number of lines of article texts: 32537 - total number of lines of article texts: 32556
- number of script lines: 291 - number of script lines: 291
- occurrences of the word "person": 7 - occurrences of the word "person": 7
- occurrences of the word "nigger": 91 - occurrences of the word "nigger": 91
@ -28,51 +28,51 @@ longest articles:
- [internet](internet.md): 36K - [internet](internet.md): 36K
- [woman](woman.md): 32K - [woman](woman.md): 32K
- [history](history.md): 32K - [history](history.md): 32K
- [main](main.md): 32K
- [random_page](random_page.md): 32K - [random_page](random_page.md): 32K
- [game](game.md): 32K - [game](game.md): 32K
- [main](main.md): 32K
- [pseudorandomness](pseudorandomness.md): 32K - [pseudorandomness](pseudorandomness.md): 32K
top 50 5+ letter words: top 50 5+ letter words:
- which (2408) - which (2413)
- there (1847) - there (1848)
- people (1642) - people (1648)
- example (1433) - example (1435)
- other (1310) - other (1313)
- number (1230) - number (1230)
- about (1148) - about (1151)
- software (1144) - software (1143)
- program (971) - program (971)
- because (896) - because (898)
- their (885) - their (887)
- would (881) - would (883)
- called (824) - called (826)
- language (820) - language (821)
- being (806) - being (807)
- things (802) - things (804)
- something (802) - something (803)
- numbers (796) - numbers (796)
- simple (765) - simple (765)
- computer (751) - computer (751)
- without (714) - without (717)
- programming (710) - programming (710)
- function (701) - function (701)
- these (683) - these (683)
- different (672) - different (672)
- however (663) - however (663)
- system (639) - system (644)
- world (620) - world (622)
- doesn (615) - doesn (615)
- should (612) - should (612)
- while (591) - while (592)
- point (587) - point (587)
- society (579) - society (579)
- games (578) - games (578)
- drummyfish (557)
- simply (556) - simply (556)
- drummyfish (555)
- using (549) - using (549)
- though (547) - though (548)
- still (543) - still (543)
- possible (536) - possible (536)
- memory (522) - memory (522)
@ -80,15 +80,42 @@ top 50 5+ letter words:
- https (510) - https (510)
- course (504) - course (504)
- value (503) - value (503)
- technology (496) - technology (497)
- always (488) - always (490)
- basically (482) - basically (484)
- really (475) - really (475)
- first (468) - first (469)
latest changes: latest changes:
``` ```
Date: Thu Aug 29 16:19:22 2024 +0200
4chan.md
ancap.md
copyright.md
democracy.md
diogenes.md
doom.md
dramatica.md
hero_culture.md
information.md
interesting.md
iq.md
lgbt.md
lmao.md
main.md
modern.md
often_confused.md
pedophilia.md
people.md
random_page.md
reddit.md
rms.md
soyence.md
ted_kaczynski.md
wiki_pages.md
wiki_stats.md
woman.md
Date: Tue Aug 27 22:53:54 2024 +0200 Date: Tue Aug 27 22:53:54 2024 +0200
acronym.md acronym.md
attribution.md attribution.md
@ -100,37 +127,6 @@ Date: Tue Aug 27 22:53:54 2024 +0200
chess.md chess.md
computer.md computer.md
diogenes.md diogenes.md
doom.md
exercises.md
fail_ab.md
float.md
game.md
gay.md
git.md
hacking.md
how_to.md
infinity.md
internet.md
interpolation.md
leading_the_pig_to_the_slaughterhouse.md
left_right.md
lmao.md
monad.md
noise.md
people.md
prime.md
programming_language.md
random_page.md
raylib.md
reactionary_software.md
reddit.md
regex.md
ronja.md
soyence.md
stereotype.md
sw_rendering.md
terry_davis.md
update_culture.md
``` ```
most wanted pages: most wanted pages:
@ -159,39 +155,39 @@ most wanted pages:
most popular and lonely pages: most popular and lonely pages:
- [lrs](lrs.md) (296) - [lrs](lrs.md) (296)
- [capitalism](capitalism.md) (242) - [capitalism](capitalism.md) (244)
- [c](c.md) (221) - [c](c.md) (221)
- [bloat](bloat.md) (214) - [bloat](bloat.md) (214)
- [free_software](free_software.md) (177) - [free_software](free_software.md) (177)
- [game](game.md) (142) - [game](game.md) (142)
- [suckless](suckless.md) (140) - [suckless](suckless.md) (140)
- [proprietary](proprietary.md) (125) - [proprietary](proprietary.md) (125)
- [minimalism](minimalism.md) (99) - [minimalism](minimalism.md) (100)
- [computer](computer.md) (98) - [computer](computer.md) (98)
- [kiss](kiss.md) (97) - [kiss](kiss.md) (97)
- [modern](modern.md) (95) - [modern](modern.md) (95)
- [linux](linux.md) (92) - [linux](linux.md) (92)
- [gnu](gnu.md) (91) - [gnu](gnu.md) (91)
- [programming](programming.md) (88) - [fun](fun.md) (91)
- [fun](fun.md) (88) - [programming](programming.md) (89)
- [censorship](censorship.md) (87) - [censorship](censorship.md) (87)
- [math](math.md) (84) - [math](math.md) (85)
- [free_culture](free_culture.md) (82) - [free_culture](free_culture.md) (82)
- [fight_culture](fight_culture.md) (82)
- [less_retarded_society](less_retarded_society.md) (81) - [less_retarded_society](less_retarded_society.md) (81)
- [fight_culture](fight_culture.md) (81)
- [bullshit](bullshit.md) (81) - [bullshit](bullshit.md) (81)
- [shit](shit.md) (80)
- [hacking](hacking.md) (80) - [hacking](hacking.md) (80)
- [art](art.md) (78) - [art](art.md) (78)
- [shit](shit.md) (77)
- [public_domain](public_domain.md) (76) - [public_domain](public_domain.md) (76)
- [corporation](corporation.md) (76)
- [programming_language](programming_language.md) (75) - [programming_language](programming_language.md) (75)
- [foss](foss.md) (75) - [foss](foss.md) (75)
- [corporation](corporation.md) (74) - [internet](internet.md) (72)
- [chess](chess.md) (72)
- ... - ...
- [atan](atan.md) (5)
- [anal_bead](anal_bead.md) (5) - [anal_bead](anal_bead.md) (5)
- [adam_smith](adam_smith.md) (5) - [adam_smith](adam_smith.md) (5)
- [aaron_swartz](aaron_swartz.md) (5)
- [zuckerberg](zuckerberg.md) (4) - [zuckerberg](zuckerberg.md) (4)
- [wiki_pages](wiki_pages.md) (4) - [wiki_pages](wiki_pages.md) (4)
- [trump](trump.md) (4) - [trump](trump.md) (4)

View file

@ -49,4 +49,8 @@ Some people still decide to use it.
TODO TODO
All are shit. All are shit.
## See Also
- [botnet](botnet.md)

View file

@ -65,7 +65,7 @@ Note: It is guaranteed that [soyentific](soyence.md) BIGBRAINS will start screec
|life span: avg. (EU)| 75 years | 81 years | | |life span: avg. (EU)| 75 years | 81 years | |
| life span: greatest| 116 y. (Kimura) | 122 y. (Calment) |top 10 oldest people ever are all W | | life span: greatest| 116 y. (Kimura) | 122 y. (Calment) |top 10 oldest people ever are all W |
| suicides / 100K | 11.15 | 2.86 |M die by suicide nearly 4x as often | | suicides / 100K | 11.15 | 2.86 |M die by suicide nearly 4x as often |
|average IQ (US 1993)| 101.8 | 98.8 |in some areas M score even 11 higher | |average IQ (US 1993)| 101.8 | 98.8 |in some areas M score even 11 higher |
|Fields medals (2022)| 62 | 2 |W had 0 until 2014 | |Fields medals (2022)| 62 | 2 |W had 0 until 2014 |
|car property damage | 3.7 / million | 4.2 / million |(Massie et al. 1997) | |car property damage | 3.7 / million | 4.2 / million |(Massie et al. 1997) |
| 200m outdoor WR | 19.90s (Bolt) |21.34s (G-Joyner) |best W ranks lower than #5769 among M| | 200m outdoor WR | 19.90s (Bolt) |21.34s (G-Joyner) |best W ranks lower than #5769 among M|
@ -75,7 +75,7 @@ Note: It is guaranteed that [soyentific](soyence.md) BIGBRAINS will start screec
| 100m swim WR |46.8s (Popovici) |51.7s (Sjostrom) |best W ranks lower than #602 among M | | 100m swim WR |46.8s (Popovici) |51.7s (Sjostrom) |best W ranks lower than #602 among M |
| chess best Elo |2882 (Carlsen) |2735 (Polgar) |best W win 8%, lose 48%, draw 44% | | chess best Elo |2882 (Carlsen) |2735 (Polgar) |best W win 8%, lose 48%, draw 44% |
| go best Elo |3862 (Jinseo) |3424 (Choi Jeong) |best W ranks #68, M win prob.: 92% | | go best Elo |3862 (Jinseo) |3424 (Choi Jeong) |best W ranks #68, M win prob.: 92% |
| speedcubing WR |3.47s (Du) |4.44 (Sebastien) |best W ranks #16 among M | | speedcubing WR |3.47s (Du) |4.44 (Sebastien) |best W ranks #16 among M |
|Starcr. 2 best Elo |3556 (Serral) |2679 (Scarlett) |best M has ~80% win chance against W | |Starcr. 2 best Elo |3556 (Serral) |2679 (Scarlett) |best M has ~80% win chance against W |
|holding breath WR |24:37 (Sobat) |18:32m (Meyer) |Ms have ~35% greater lung capacity | |holding breath WR |24:37 (Sobat) |18:32m (Meyer) |Ms have ~35% greater lung capacity |
@ -151,4 +151,4 @@ I also realized babushkas and old grandmas in general are often based, they just
- [waifu](waifu.md) - [waifu](waifu.md)
- [penetration testing](penetration_testing.md) - [penetration testing](penetration_testing.md)
- Encyclopedia Dramatica's take on the topic: https://encyclopediadramatica.gay/Woman - Encyclopedia Dramatica's take on the topic: https://encyclopediadramatica.gay/Woman
- [dogpill](dogpill.md) - [dogpill](dogpill.md)

View file

@ -6,11 +6,11 @@ XXIIVV is a [proprietary](proprietary.md) [soynet](soynet.md) snob website and p
{ Holy shit his webring is toxic AF, do not research it. Basically a one huge gay nazi wannabe "artist" circlejerk, it's like a small village worth of the kind of [furry](furry.md) psychopaths who like to draw cute cartoon animals while also advocating slow torture and castration of people who dislike them. ~drummyfish } { Holy shit his webring is toxic AF, do not research it. Basically a one huge gay nazi wannabe "artist" circlejerk, it's like a small village worth of the kind of [furry](furry.md) psychopaths who like to draw cute cartoon animals while also advocating slow torture and castration of people who dislike them. ~drummyfish }
Firstly let's see about the letdowns: the site is [proprietary](proprietary.md) and **he licenses his "art" and some of his code under the proprietary [CC-BY-NC-SA](cc_by_nc_sa.md)**, big RETARD ALERT. This means he's a [capitalist](capitalist.md) [open soars](open_source.md) fanboy trying to monopolize art by keeping exclusive "commercial intellectual property rights" (as if his amateur stick figure level "art" had any commercial value lol). At least some of his code is [MIT](mit.md), but he also makes fucking **[PROPRIETARY](proprietary.md) PAID software** (e.g. Verreciel), then he somehow tries to brainwash the readers to believe he is "against capitalism" or what? :'D (Or is he not? I dunno. Definitely seems to be riding the [eco](eco.md) wave.) The guy also seems **[egoistic](egoism.md) as fuck**, invents weird hipster names and "personal pronouns", has some ugly "body modifications", wears cringe rabbit costumes and tries to write in a super cringe pompous/cryptic/poetic tryhard style probably in an attempt to appear smart while just making a fool of himself and, in addition, making it shithard to make any sense of his texts -- truly his tech writings are literal torture to read. The only thing he's missing is a fedora. Firstly let's see about the letdowns: the site is [proprietary](proprietary.md) and **he licenses his "art" and some of his code under the proprietary [CC-BY-NC-SA](cc_by_nc_sa.md)**, big RETARD ALERT. This means he's a [capitalist](capitalism.md) [open soars](open_source.md) fanboy trying to monopolize art by keeping exclusive "commercial intellectual property rights" (as if his amateur stick figure level "art" had any commercial value lol). At least some of his code is [MIT](mit.md), but he also makes fucking **[PROPRIETARY](proprietary.md) PAID software** (e.g. Verreciel), then he somehow tries to brainwash the readers to believe he is "against capitalism" or what? :'D (Or is he not? I dunno. Definitely seems to be riding the [eco](eco.md) wave.) The guy also seems **[egoistic](egoism.md) as fuck**, invents weird hipster names and "personal pronouns", has some ugly "body modifications", wears cringe rabbit costumes and tries to write in a super cringe pompous/cryptic/poetic tryhard style probably in an attempt to appear smart while just making a fool of himself and, in addition, making it shithard to make any sense of his texts -- truly his tech writings are literal torture to read. The only thing he's missing is a fedora.
There are also nice things though, a few of them being: There are also nice things though, a few of them being:
- The guy is creating extremely minimalist, small tech from-scratch technology that's worthy of attention. Some of it includes: - The guy is creating extremely minimalist, small from-scratch technology that's worthy of attention. Some of it includes:
- [uxn](uxn.md): Simple (~100 [LOC](loc.md) of [C](c.md)) [virtual machine](virtual_machine.md), similar to a "[fantasy console](fantasy_console.md)" but intended more for [portability](portability.md). This also comes with an assembly language called [tal](tal.md). - [uxn](uxn.md): Simple (~100 [LOC](loc.md) of [C](c.md)) [virtual machine](virtual_machine.md), similar to a "[fantasy console](fantasy_console.md)" but intended more for [portability](portability.md). This also comes with an assembly language called [tal](tal.md).
- [lietal](lietal.md): Simple [artificial language](conlang.md). - [lietal](lietal.md): Simple [artificial language](conlang.md).
- The wiki writes on pretty [interesting](interesting.md) topics, many of which overlap with [our](lrs.md) topics of interest. For example [pen and paper computing](pen_and_paper.md) that includes [games](game.md). - The wiki writes on pretty [interesting](interesting.md) topics, many of which overlap with [our](lrs.md) topics of interest. For example [pen and paper computing](pen_and_paper.md) that includes [games](game.md).