This commit is contained in:
Miloslav Ciz 2022-09-28 21:42:32 +02:00
parent 633f66f409
commit 10794c61d6
10 changed files with 148 additions and 5 deletions

View file

@ -4,6 +4,6 @@ William "Bill" Gates (28.10.1955 -- hopefully soon) is a [mass murderer and rapi
He is really dumb, only speaks one language and didn't even finish university. He also has no moral values, but that goes without saying for any rich businessman. He was owned pretty hard in [chess](chess.md) by Magnus Carlsen on some shitty TV show.
Bill was mentally retarded as a child and as such had to attend a private school. In adolescence he raped little children. He never really understood programming but with a below average intelligence he had a good chance to succeed in [business](capitalism.md). Thanks to his family connections he got to Harvard where he met [Steve Ballmer](steve_ballmer.md) -- later he dropped out of the school due to his low intelligence.
Bill was mentally [retarded](retard.md) as a child and as such had to attend a private school. He never really understood programming but with a below average intelligence he had a good shot at succeeding in [business](capitalism.md). Thanks to his family connections he got to Harvard where he met [Steve Ballmer](steve_ballmer.md) -- later he dropped out of the school due to his low intelligence.
In 1975 he founded [Micro$oft](microsoft.md), a [malware](malware.md) company named after his dick. By a sequence of extremely lucky events combined with a few dick moves by Bill the company then became successful: when around the year 1980 [IBM](ibm.md) was creating the [IBM PC](ibm_pc.md), they came to Bill because they needed an [operating system](os.md). He lied to them that he had one and sold them a license even though at the time he didn't have any OS (lol). After that he went to a programmer named Tim Paterson and basically stole (bought for some penny) his OS named QDOS and gave it to IBM, while still keeping ownership of the OS (he only sold IBM a license to use it, not exclusive rights for it). He basically fucked everyone for money and got away with it, the American way. For this he is admired by Americans.
In 1975 he founded [Micro$oft](microsoft.md), a [malware](malware.md) company named after his dick. By a sequence of extremely lucky events combined with a few dick moves by Bill the company then became successful: when around the year 1980 [IBM](ibm.md) was creating the [IBM PC](ibm_pc.md), they came to Bill because they needed an [operating system](os.md). He lied to them that he had one and sold them a license even though at the time he didn't have any OS (lol). After that he went to a programmer named Tim Paterson and basically stole (bought for some penny) his OS named QDOS and gave it to IBM, while still keeping ownership of the OS (he only sold IBM a license to use it, not exclusive rights for it). He basically fucked everyone for money and got away with it, the [American](usa.md) way. For this he is admired by Americans.

19
downto.md Normal file
View file

@ -0,0 +1,19 @@
# Downto Operator
In [C](c.md) the so called "downto" operator is a [joke](jokes.md) played on nubs. It goes like this: Did you know C has a hidden downto operator `-->`? Try it:
```
#include <stdio.h>
int main(void)
{
int n = 20;
while (n --> 10) // n goes down to 10
printf("%d\n",n);
return 0;
}
```
Indeed this compiles and works. In fact `-->` is just `--` and `>` operators.

21
fizzbuzz.md Normal file
View file

@ -0,0 +1,21 @@
# FizzBuzz
TODO
```
#include <stdio.h>
int main(void)
{
for (int i = 1; i <= 100; ++i)
switch ((i % 3 == 0) + (i % 5 == 0) * 2)
{
case 1: printf("Fizz\n"); break;
case 2: printf("Buzz\n"); break;
case 3: printf("FizzBuzz\n"); break;
default: printf("%d\n",i); break;
}
return 0;
}
```

1
lrs.md
View file

@ -53,6 +53,7 @@ The "official" LRS programs and libraries have so far been solely developed by [
- **[small3dlib](small3dlib.md)**: Simple software rasterizer for 3D rendering.
- **[smallchesslib](smallchesslib.md)**: Simple [chess](chess.md) library and engine ([AI](ai.md)).
- **[microtd](utd.md)**: Simple [tower defense](tower_defense.md) game written with [SAF](saf.md).
- **[tinyphysicsengine](tinyphysicsengine.md)**: Very simple 3D [physics engine](physics_engine.md).
Apart from this software a lot of other software developed by other people and groups can be considered LRS, at least to a high degree (there is usually some minor inferiority e.g. in licensing). Especially [suckless](suckless.md) software mostly fits the LRS criteria. The following programs and libraries can be considered LRS at least to some degree:

View file

@ -32,6 +32,13 @@ Well, we're trying to figure this out on this wiki, but it is greatly related to
Are you a noob but see our ideas as appealing and would like to join us? Say no more and head over to a [how to](how_to.md)!
## Did You Know
- That [capitalism](capitalism.md) is probably the most [retarded](retard.md) and dangerous idea in [history](history.md)?
- You can mathematically [prove you don't know some information](no_knowledge_proof.md)?
- That a complement of a [formal language](formal_language.md) can be computationally simpler than the original -- for example that a [pushdown automaton](pushdown_automaton.md) cannot tell which strings are of form a^(n)b^(n)c^(n), but it can tell exactly which ones are not?
- That [LGBT](lgbt.md), [feminism](feminism.md) and similar movements are not truly leftist but rather [pseudoleftist](pseudoleft.md) and therefore [fascist](fascism.md)?
## Some Interesting Topics
If you don't know where to start, here are some suggestions. If you're new, the essential topics are:
@ -74,6 +81,7 @@ And if you just want something more obscure and [fun](fun.md), check out these:
- [steganography](steganography.md)
- [lmao](lmao.md)
- [shit](shit.md)
- [C downto operator](downto.md)
- [demoscene](demoscene.md)
- [gaymes](game.md)
- [Circumlunar](circumlunar.md)

17
no_knowledge_proof.md Normal file
View file

@ -0,0 +1,17 @@
# No Knowledge Proof
{ I found the idea here https://suricrasia.online/no-knowledge.html, the page claims it comes from a Twitter user @chordowl. ~drummyfish }
In the context of [cryptography](cryptography.md) *no knowledge proof* (NOT to be confused with [zero knowledge proof](zero_knowledge_proof.md)) is a mathematical [proof](proof.md) of not knowing certain information. At the moment it seems to be kind of a [fun](fun.md) idea and curiosity without much use, but in math many fun ideas have found a serious use later on, so who knows. { If anyone knows of a legit use, let me know. ~drummyfish }
The principle is this: supposed we have a one way (practically irrevesible) [hash](hash.md) function *H* (such as [SHA-256](sha_256.md)). Also suppose we have all agreed on a special value *y* that's non-zero and has been constructed so that it most likely doesn't have any malicious properties, i.e. it is a so called *nothing up my sleeve* value and can be for example some sentence converted to ASCII -- more detail on this will follow later, now simply suppose we have some value *y*. Now by providing someone with a number *x* we prove we don't know a value *z* such that *h(z) = h(x) xor y*.
How can this work? Well, imagine we knew *z* and we wanted to prove we didn't know it. We can compute *h(x)*, (un)xor it with *y*, but now to compute *x* we'd have to reverse the hash *h*, i.e. compute *x = h^(-1)(h(z) xor y)*. And from the definition of the hash we can't do this.
Another possible intuitive explanation: basically we have a system here that creates pairs of numbers -- for any two numbers *x* and *z* the system defines whether they're linked or not (via the equation *h(z) = h(x) xor y*). The point is that given one of these numbers it is practically impossible to derive the other one due to the difficulty of reversing the hash function, so if we show we know one number (*x*) we are really showing we don't know the other number (*z*) because we simply can't have both.
So the point of the [joke](jokes.md) is that we can't choose the information we want to prove we don't know, but that's kind of logical as if we could, we would know it. We simply pick a number *x* and so prove we don't know some random number *z* with some properties related to *x* and *y*.
A small vulnerability lies in the value *y* which is why it needs to be established carefully. We can't just accept someone else's *x* as a proof if it comes with a randomly looking *y* because then the proof may have been forged. How? Well, suppose there's been no *y* established; now again suppose we know some number *z* and want to prove we don't know it. We compute *h(z)*, then we randomly choose some number *x*, compute *h(x)* and now we simply derive *y* as *h(z) xor h(x)*. Now if someone accepts our *y* as valid, we have a forged fake proof as we know both the number *x*, i.e. a "proof" of not knowing *z*, but we also know *z*. So we have to make sure the one who is handing the proof (number *x*) did not pregenerate *y* this way. This opens up a possibility of attacking this proof by [brute forcing](brute_force.md) various *y* values, then taking those that somehow look "innocent" (e.g. by resembling some string or simple number sequence) and then trying to establish those as a legit *nothing up my sleeve* value.
When thinking about it, it's not really that curious we can construct a no knowledge proof, in math we prove that we can't know something all the time (e.g. [undecidable](decidability.md) problems).

View file

@ -1,10 +1,12 @@
# Physics Engine
{ [LRS](lrs.md) now has a very small 3D physics engine called [tinyphysicsengine](tinyphysicsengine.md). ~drummyfish }
Physics engine is a [software](software.md) (usually a [library](library.md)) whose purpose is to simulate physics laws of mechanics, i.e. things such as forces, [rigid](rigid_body.md) and [soft](soft_body.md) body collisions, [particle](particle.md) motion, fluid dynamics etc.
{ When it comes to classic 3D rigid body physics engines, they're extremely hard to make, much harder than for example an advanced 3D rendering engine, especially when you want to make them [LRS](lrs.md) (without floating point, ...) and/or general and somewhat physically correct (being able to simulate e.g. the Dzhanibekov effect, satisfying all the conservation laws, continuous collision detection etc.). Good knowledge of mechanics and things like [quaternions](quaternion.md) and 3D rotations is just the beginning, difficulties arise in every aspect of the engine, and of those there are many. As I've found, 32 bit fixed point is not enough for a general engine (even though it is enough for a rendering engine), you'll run into precision problems as you need to represent both relatively high and low energies. You'll also run into stability issues such as stable contacts, situations with multiple objects stacked on top of each other starting to bounce on their own etc. Even things such as deciding in what order to resolve collisions are very difficult, they can lead to many bugs such as a car not being able to drive on a straight road made of several segments. Collision detection alone for all combinations of basic shapes (sphere, cuboid, cylinder, capsule, ... let alone general triangle mesh) are hard as you want to detect general cases (not only e.g. surface collisions) and you want to extract all the parameters of the collisions (collision location, depth, normal etc.) AND you want to make it fast. And of course you'll want to add acceleration structures and many other thing on top. So think twice before deciding to write your own physics engine.
A sane approach may be to write a simplified engine specifically for your program, for example a Minecraft-like game may just need non-rotating capsules in a voxel environment, that's not that hard. You may perhaps get away with a bit of cheating, e.g. simulating rigid bodies as really stiff soft bodies, it may not be as efficient and precise but it's simpler to program. It may be [good enough](good_enough.md). ~drummyfish }
A sane approach may be to write a simplified engine specifically for your program, for example a Minetest-like game may just need non-rotating capsules in a voxel environment, that's not that hard. You can also get away with a bit of cheating and faking, e.g. simulating rigid bodies as really stiff soft bodies, it may not be as efficient and precise but it's simpler to program. It may be [good enough](good_enough.md). Well, that's basically what [tinyphysicsengine](tinyphysicsengine.md) does anyway. ~drummyfish }
Physics engine is a wide term even though one usually imagines the traditional 3D rigid body engine used in games such as [GTA](gta.md). These engines may nevertheless have different purposes, features and even basic paradigms, some may e.g. be specialized just for computing precise ballistic trajectories for the army, some may serve for simulating weather etc. Some common classifications and possible characteristics of physics engines follow:
@ -13,6 +15,7 @@ Physics engine is a wide term even though one usually imagines the traditional 3
- **[rigid body](rigid_body.md) vs [soft body](soft_body.md)**: Rigid body engines don't allow bodies to deform while soft body ones do -- in real life all bodies are soft, but neglecting this detail and considering shapes rigid can have benefits (such as being able to consider the body as a whole and not having to simulate all its individual points). Of course, a complex engine may implement both rigid and soft body physics.
- **paradigm**: The basic approach to implementing the simulation, e.g. being [impulse](impulse.md)-based (applying impulses to correct errors), constraint-based (solving equations to satisfy imposed constraints), penalty-based (trying to find equilibriums of forces) etc.
- **[discrete](discrete.md) vs [continuous](continuous.md) collision detection**: Discrete collision detection only detects collisions at single points in time (at each engine tick) and are simple than those implementing continuous collision detection. Discrete engine are less accurate, consider e.g. that a very fast moving object can pass through a wall because at one instant it is in front of it while at the next tick it is behind it. Continuous collisions won't allow this to happen, but are more difficult to program, may be slower etc. For games discrete collisions are usually [good enough](good_enough.md).
- **purpose and accuracy**: The basic categories are precise, scientific and often special-purpose engines, and engines meant for entertainment and less accurate visualizations such as games and movies.
- **features: fluid, cloth, particles, [ragdoll](ragdoll.md), [inverse kinematics](inverse_kinematics.md), [GPU](gpu.md) acceleration, [determinism](determinism.md), [voxels](voxel.md), [acceleration](acceleration.md) [data structures](data_structure.md) ...**: These are a number of additional features the engine can have such as the ability to simulate fluids (which itself is a huge field of its own) or cloths, some go as far as e.g. integrating motion-captured animations of humans with physics to create smooth realistic animations e.g. of running over walking pedestrians with a car and so on.
A typical physics engine will work something like this: we create a so called **physics world**, a [data structure](data_structure.md) that represents the space in which the simulation takes place (it is similar to a [scene](scene.md) in rendering engines). We then populate this world with physics elements such as rigid bodies (which can have attributes such as mass, elasticity etc.). These bodies are normally basic geometric shapes such as spheres, cylinders, boxes or capsules, or objects composed of several such basic shapes. This is unlike with rendering engines in which we normally have triangle meshes -- in physics engines triangle meshes are extremely slow to process, so for the sake of a physics engine we approximate this mesh with some of the above basic shapes (for example a creature in a game that's rendered as a hi-poly 3D model may in the physics engine be represented just as a simple sphere). Furthermore the bodies can be **[static](static.md)** (cannot move, this is sometimes done by setting their mass to infinity) or **[dynamic](dynamic.md)** (can move); static bodies normally represent the environment (e.g. the game level), dynamic ones the entities in it (player, NPCs, projectiles, ...). Making a body static has performance benefits as its movement doesn't have to be calculated and the engine can also precalculate some things for it that will make e.g. collision detections faster. We then simulate the physics of the world in so called *ticks* (similar to [frames](frame.md) in rendering); in simple cases one tick can be equivalent to one rendering frame, but properly it shouldn't be so (physics shouldn't be affected by the rendering speed, and also for the physics simulation we can usually get away with smaller "[FPS](fps.md)" than for rendering, saving some performance). Usually one tick has set some constant time length (e.g. 1/60th of a second). In each tick the engine performs a **[collision detection](collision.md)**, i.e. it finds out which bodies are touching or penetrating other bodies (this is accelerated with things such as [bounding spheres](bounding_volume.md)). Then it performs so called **collision resolution**, i.e. updating the positions, velocities and forces so that the bodies no longer collide and react to these collisions as they would in the real world (e.g. a ball will bounce after hitting the floor). There can be many more things, for example **constraints**: we may e.g. say that one body must never get further away from another body than 10 meters (imagine it's tied to it by a rope) and the engine will try to make it so that this always holds. The engine will also offer a number of other functions such as casting rays and calculating where it hits (obviously useful for shooter games).

View file

@ -1,6 +1,6 @@
# SIGBOVIK
SIGBOVIK ([special interest group](sig.md) on Harry Q. Bovik) is a [computer science conference](compsci.md) running since 2007 that focuses on researching and presenting [fun](fun.md) ideas in fun ways, scientifically but in a lighthearted [hacker](hacking.md) spirit similar to e.g. [esoteric programming languages](esolang.md) research or the [IOCCC](ioccc.md). SIGBOVIK has their own proceedings just like other scientific conferences, the contributors are usually professional researchers and experts in computer science. The name seems to be a reference to the "serious" conferences such as [SIGGRAPH](siggraph.md) (SIGBOVIK is organized by the *Association for Computational Heresy* while SIGGRAPH is run by *Asscoiation for Computing Machinery*).
SIGBOVIK ([special interest group](sig.md) on Harry Q. Bovik) is a [computer science conference](compsci.md) running since 2007 that focuses on researching and presenting [fun](fun.md) ideas in fun ways, scientifically but in a lighthearted [hacker](hacking.md) spirit similar to e.g. [esoteric programming languages](esolang.md) research or the [IOCCC](ioccc.md). SIGBOVIK has their own proceedings just like other scientific conferences, the contributors are usually professional researchers and experts in computer science. The name seems to be a reference to the "serious" conferences such as [SIGGRAPH](siggraph.md), SIGMOD etc. (SIGBOVIK is organized by the *Association for Computational Heresy* while the "serious" SIGs are run by *Asscoiation for Computing Machinery*, ACM).
A famous contributor to the conference is e.g. Tom7, a [PhD](phd.md) who makes absolutely lovely [youtube](youtube.md) videos about his fun research (e.g. this one is excellent https://www.youtube.com/watch?v=DpXy041BIlA).

74
sudoku.md Normal file
View file

@ -0,0 +1,74 @@
# Sudoku
Sudoku is a puzzle that's based on filling a grid with numbers that is hugely popular even among [normies](normie.md) such as grandmas and grandpas who find this stuff in magazines for elderly people. The goal is to fill in all squares of a 9x9 grid, prefilled with a few clue digits, with digits 1 to 9 so that no digit repeats in any column, row and 3x3 subgrid. It is like a crosswords puzzle for people who lack general knowledge, but it's also pretty [suckless](suckless.md), pure logic-based puzzle whose generation and solving can be relatively easily automatized (unlike generating crosswords which requires some big databases). The puzzle is a pretty [fun](fun.md) singleplayer [game](game.md), posing opportunities for nice [mathematical](math.md) research and analysis as well as a comfy [programming](programming.md) exercise. Sudokus are a bit similar to [magic squares](magic_square.md).
Curiously sudoku has its origins in agricultural designs in which people wanted to lay out fields of different plants in more or less uniform distributions (or something like that, there are some papers about this from 1950s). The puzzle itself became popular in Japan in about 1980s and experienced a boom of popularity in the western world some time after 2000.
The following is an example of a sudoku puzzle with only the initial clues given:
```
_________________
| 3 1| 5 7| 6 |
| |9 8| 4 |
|4_7_8|6_ _2|1_ _5|
|7 5| 6 |4 |
| 6| 8 1|7 2 |
| _ _ |7_ _3|6_5_ |
|5 6 | 9 | 2|
| |1 5|9 6|
| _ _3|8_2_6| _ _4|
```
The solution to the above is:
```
_________________
|9 3 1|4 5 7|2 6 8|
|6 5 2|9 1 8|3 4 7|
|4_7_8|6_3_2|1_9_5|
|7 1 5|2 6 9|4 8 3|
|3 4 6|5 8 1|7 2 9|
|2_8_9|7_4_3|6_5_1|
|5 6 7|3 9 4|8 1 2|
|8 2 4|1 7 5|9 3 6|
|1_9_3|8_2_6|5_7_4|
```
We can see neither digit in the solution repeats in any column, row and any of the 9 marked 3x3 subgrids or, in other words, the digits 1 to 9 appear in each column, row and subgrid exactly once. These are basically the whole rules.
**We generally want a sudoku puzzle to have initial clues such that there is exactly one possible (unique) solution.** For this sudoku has to have at least 17 clues (this was proven by a computer). Why do we want this? Probably because in the puzzle world it is simply nice to have a unique solution so that human solvers can check whether they got it right at the back page of the magazine. This constraint is also mathematically more interesting.
**How many possible sudokus are there?** Well, this depends on how we view the problem: let's call one sudoku one grid completely filled according to the rules of sudoku. Now if we consider all possible such grids, there are 6670903752021072936960 of them. However some of these grids are "basically the same" because we can e.g. swap all 3s and 5s in any grid and we get basically the same thing as digits are nothing more than symbols here. We can also e.g. flip the grid horizontally and it's basically the same. If we take such things into account, there remain "only" 5472730538 essentially different sudokus.
Sudoku puzzles are sometimes assigned a difficulty rating that is based e.g. on the techniques required for its solving.
Of course there exist variants of sudoku, e.g. with different grid sizes, extended to 3D, different constraints on placing the numbers etc.
## Solving Sudoku
There are two topics to address: solving sudoku by people and solving sudoku by computers.
Humans almost exclusively use logical reasoning techniques to solve sudoku, which include:
- **scanning**: We take a look at some frequently appearing number in the grid and see which columns and rows they intersect which implies they cannot be placed in those columns and rows, possibly revealing the only possible location to place such number.
- **single remaining candidate**: When there is only one number left to fill in any column, row or subgrid, it is always clear which one it is and can be safely placed.
- **candidate sets**: An advanced technique in which we create sets of possible candidate numbers for each square on the grid e.g. by writing tiny numbers in the top corners of the squares. We then apply various reasoning to reduce those sets, i.e. remove candidate numbers, until a single candidate remains for a certain square in which case we can fill in that number with certainty. This will further help us reason about candidates in other squares.
For computers the traditional 9x9 sudoku is nowadays pretty easy to solve, however solving an NxN sudoku is an [NP complete](np_complete.md) problem, i.e. there most likely doesn't exist a "fast" algorithm for solving a generalized NxN sudoku, even though the common 9x9 variant can still be solved pretty quickly with today's computers by using some kind of "smart" [brute force](brute_force.md), for example [backtracking](backtracking.md) (or another state tree search) which [recursively](recursion.md) tries all possibilities and at any violation of the rules gets one step back to change the previous number. Besides this a computer can of course use all the reasoning techniques that humans use such as creating sets of possible values for each square and reducing those sets until only one possibility stays. The approach of reasoning and brute forcing may also be combined: first apply the former and when stuck fall back to the latter.
## Generating Sudoku
{ I haven't personally tested these methods yet, I'm just writing what I've read on some web pages and ideas that come to my mind. ~drummyfish }
Generating sudoku puzzles is non-trivial. There are potentially many different [algorithms](algorithm.md) to do it, here we just foreshadow some common simple approaches.
Firstly we need to have implemented basic code for checking the validity of a grid and also some automatic solver, e.g. based on [backtracking](backtracking.md).
For generating a sudoku we usually start with a completely filled grid and keep removing numbers to leave only a few ones that become the initial clues. For this we have to know how to generate the solved grids. Dumb [brute force](brute_force.md) (i.e. generating completely random grids and testing their validity) won't work here as the probability of finding a valid grid this way is astronomically low (seems around 10^(-56)). What may work is to randomly fill a few squares so that they don't break the rules and then apply our solver to fill in the rest of the squares. Yet a simpler way may be to have a database of a few hand-made grids, then we pick on of them and apply some transformations that keep the validity of the grid which include swapping any two columns, swapping any two rows, [tansposing](transposition.md), flipping the grid, rotating it 90 degrees or swapping any two digits (e.g. swap all 7s with all 9s).
With having a completely filled grid generating a non-unique (more than one solution) sudoku puzzle is trivial -- just take some completely filled grid and remove a few numbers. But as stated, we usually don't want non-unique sudokus.
For a unique solution sudoku we have to check there still exists exactly one solution after removing any numbers from the grid, for which we can again use our solver. Of course we should [optimize](optimization.md) this process by quitting the check after finding more than one solution, we don't need to know the exact count of the solutions, only whether it differs from one.
The matter of generating sudokus is further complicated by taking into account the difficulty rating of the puzzle.

View file

@ -1,5 +1,5 @@
# YouTube
YouTube (also JewTube), is a huge video propaganda website, since 2006 owned by [Google](google.md). It has become the monopoly "video platform", everyone uploads their videos there and so every one of us is forced to use the site from time to time. YouTube is based on video content consumerism and financed from aggressive ads and surveillance of its users.
YouTube (also JewTube) is a huge, [censored](censorship.md) [proprietary](proprietary.md) [capitalist](capitalism.md) video [consumerism](consumerism.md) website, since 2006 seized by the [Google](google.md) terrorist organization. It has become the monopoly "video content platform", everyone uploads their videos there and so everyone is forced to use that shitty site from time to time to view some tutorial or whatnot. YouTube is based on content consumerism, [copyright trolling](copyright_troll.md), propaganda and abuse of users -- it is financed from surveillance of its users and aggressive ads as well as sponsored content inserted into videos. Alternatives to YouTube, such as [bitchute](bitchute.md), the "rightist" YouTube, never really caught on very much -- YouTube is sadly synonymous with online videos just as Google is synonymous with searching the web.
A [FOSS](foss.md) alternative to YouTube is e.g. [PeerTube](peertube.md), a federated video platform, however for intended use it requres [JavaScript](javascript.md). There also exist alternative YouTube [frontends](frontend.md) (normally also FOSS), e.g. HookTube, Invidious or FreeTube -- these let you access YouTube's videos via less [bloated](bloat.md) and more privacy-friendly interface. More hardcore people use [CLI](cli.md) tools such as [youtube-dl](youtube_dl.md) to directy download the videos and watch them in native players.