24 KiB
Exercises
THIS IS CURRENTLY HIGHLY WORK IN PROGRESS
Here there should be a set of exercise problems for those wishing to pursue LRS in any way.
{ Hmmm, it's hard to figure out exactly what to put here. ~drummyfish }
Programming Projects
See also needed projects.
Here you will find suggestions for programming projects, roughly sorted by their difficulty (in each level projects will be sorted roughly by difficulty too). You can use this to practice what you've learned in c tutorial, try to follow the LRS principles. We are kind of assuming you'll be programming these projects in C -- that's how we judge the difficulty etc. -- but of course no one is stopping you to make the project in another language if you so desire :)
LRS programming challenge! If you want you can treat this as a game, kind of achievements you can collect. You can even make a git repo for your solutions so others can see and admire them { I'll be glad if you send me a link. ~drummyfish } Here are the rules:
- Award yourself points like this:
- 1 point for a completed project in level 0.
- 4 points for a completed project in level 1.
- 16 points for a completed project in level 2.
- 64 points for a completed project in level 3.
- If you complete all projects in level N, you can automatically consider all projects of all lower levels completed as well, i.e. if you complete level 2, count yourself whole level 1 and 0 as well.
- A project is considered completed only if you really complete all the requirements! It is not enough to say "mmm, I could do this if I wanted" -- no, you have to REALLY DO IT to count. If the requirement is to make a complete game, a buggy demo doesn't count. Also if you just use some cheat, use 100 libraries to do everything for you, you know you didn't really complete it :) Just be honest with yourself.
- You CANNOT award yourself partial points, i.e. if you meet 90% of requirements for some project, you CANNOT give yourself 90% points for it, not even one point. Complete it 100%, then get 100% points. Again, it doesn't count to say "mmm, I could finish this if I wanted" -- no, until you finish it, it's not finished. This is part of the challenge and insisting on it also makes you potentially make a nice, tidy program that will increase good in the world ;)
- You may reuse your own code without it counting as third party library, i.e. if you write 3D renderer in one project, you can use it in writing 3D game as another project, with it counting as if you wrote everything from scratch just for that project.
- Don't cheat, you're only cheating yourself :)
Level 0: Trivial, Piece Of Cake
- hello: Make a program that outputs
hello
. - counting: Make a program that outputs numbers from 1 up to 100.
- guess a number: Make a game in which the computer secretly thinks a number from 0 to 9 and the player guesses the number. The computer then says if the player won and what the secret number what.
- password generator: Make a program which when run outputs randomly generated password (the password must be different each time you run the program of course). The password must be at least 10 characters long, contain at least one decimal digit and one special character.
- average: Make a program that reads two numbers (you can assume only non-negative integers will be input) and writes out their average (it can be rounded, even to just integer, e.g. 3 and 8 can give 5).
Level 1: Easy, I'm Too Young To Die
- fizzbuzz: Write the classic fizzbuzz program.
- anagram checker: Make a program that reads one line of text from the user and checks if it's an anagram (i.e. if it's spelled the same forward and backwards) or not -- you can just output yes or no.
- number encyclopedia: Make a program that writes number from 0 to 1000 (including both) and about each of which it writes some facts. These facts have to include at least the number's square, square root, sum of its decimal digits, its binary representation, prime factorization and whether the number is prime, perfect number and Fibonacci number.
- brainfuck interpreter: Make a program that interprets brainfuck. You may choose to read the input program either from standard input or from a file (the file may have some hardcoded name, e.g. your program will just look for a file
program.bf
in the same directory). If the brainfuck program is invalid or runtime error occurs in it, you may just write outerror
and halt your interpreter. Thumbs up for making the interpreter nicer, e.g. allowing to pass input file name as a CLI argument, reporting more details about errors (e.g. its position in source code) and so on. - game of life: Make a program that simulates game of life on a finite N * N grid, with wrapping (i.e. a cell on the very left of the grid is considered a neighbor of the cell on the very right in the same row, same thing with top and bottom). Make N configurable at least as a compile time option, draw the world as ASCII art to terminal, make the user step forward by pressing some key. You can initialize the grid values randomly, but thumbs up for allowing setting the initial world state (e.g. reading it from a file or something).
- text adventure: Make an interactive CLI text adventure that will take an average player at least 10 minutes to finish. Part of game mechanics must involve inventory, i.e. picking up items, carrying them around and using them.
- calculator: Make an interactive calculator -- it can be a purely command line program into which user types expressions and your program evaluates them. The functionality must be at least on the level of the most plain physical calculators, i.e. it doesn't have to parse whole complex expressions, but it should be able to add, subtract, multiply, divide and find square roots. Results can be approximate, showing just 3 fractional decimal digits. Thumbs up for more features like handling expressions with brackets, converting between bases and so on.
- bytebeat: Make at least two cool sounding bytebeat songs.
Level 2: Mid, Hurt Me Plenty
- chess without AI: Make a program that allows two human players to play chess, AI is not required. It can be just a CLI program that draw the chessboard to terminal and reads moves by having players type the squares. Of course the program mustn't allow illegal moves, it must know if the game ended, who won (or if it's a draw) and so on. Implement all rules correctly, i.e. don't forget en passant, castling rights and so on. Time controls are not required at all. Thumbs up for some basic recording of games, undos, showing playable squares or even having some kind of stupid AI (can just make random moves).
- 2D game: Make a complete 2D game in which you control a character, with at least 5 levels. Genre is up to you, recommended is e.g. platformer or top-down shooter. Sounds are not required but thumbs up if you have them. If you want, you can try SAF for this.
- gopher browser: Write interactive gopher browser -- it can be a purely command line browser. It has to be able to follow links and go back at least one page. The program must include some basic help and ability to save files to disk.
- simple text compression: Write a program that can compress and decompress plain ASCII text files using some very simple technique like run length encoding (RLE) or dictionary methods (you can even use a fixed dictionary, e.g. have a list of common English words that you will represent by some shorter symbols). You can assume input characters will only have 7bit ASCII codes, so you can compress the text also by dropping the 8th unused bit. You don't have to achieve great compression ratio (you can even enlarge some files), but you must pass the following test: take the program's source code, this article's plain text and Wikipedia main page plain text, your program must compress at least two of these to a smaller size (and of course successfully decompress them into identical files). The program must work as a filter, i.e. it mustn't load the whole file into memory, it has to use approximately same amount of RAM for input of any size.
- stupid chatbot: Make an entertaining chatbot that can react to basic sentences like "how are you?", "are you a robot?" and so on. It must give a human-like answer to at least 20 different sentences. It has to deal with typos and text variability a little bit and has to have some kind of memory (for example it can remember the name of its chatting partner). Test the bot by having it chat with itself.
- arbitrary size numbers: Make a library that allows working with arbitrary size fixed point numbers, i.e. you will provide a data type in which it is possible to store a binary number with any number of bits before and after the radix point -- size of the number will only be limited by amount of RAM your program can use. Each number will dynamically allocate as much memory as it needs. Additionally implement these operations with the numbers: converting to/from the language's native numbers (with rounding), printing and/or converting the number to string, addition, subtraction, multiplication and dividing.
- image to ASCII art: Make a program that takes an RGB bitmap image and renders it with ASCII characters (i.e. prints it out to console). You can support loading the image from just one file format of your choice, possibly something simple like PPM, BMP or Farbfeld. The program must support resizing the image and it must allow to just set one dimension with keeping the aspect ratio.
- educational sorting visualization: Make a program for visualizing sorting algorithms -- it may draw real graphics (either directly to the screen or by outputting animation file) or just render ASCII art graphics, but it has to clearly show what the sorting algorithm is doing, i.e. which elements are being compared, which are swapped and if it makes good sense to highlight something else (like the pivot or already sorted part of the array), you should do it. Implement at least bubble sort, insertion sort, selection sort and quick sort. Also offer benchmark mode in which all algorithms race in sorting the same array (this can be without advanced visualization, just show e.g. number of steps for each).
- 3D model of fractal: Make a program that outputs 3D model of either Sieprinski triangle or Koch snowflake fractal. The output shall be some simple 3D format like obj or Collada. The model can be primitive, i.e. it can be just flat shape made of triangles which don't have to really be connected, but the program must allow specifying the number of iterations of the fractal (during invocation, e.g. as a CLI flag). Check that the model is correct by opening it in some 3D editor such as Blender.
Level 3: Hard, Ultra Violence
- non-trivial programming language: Design language L and make an interpreter for it. L must be Turing complete and you have to provide mathematical proof of it. L must allow recursive function calls. It must not support native OOP. L must be usable for programming very basic things -- show it is so by writing bubble sort in it. Write quine in it.
- radiation hardened quine: Without looking it up, write radiation hardened quine in some language. Quine is a program that outputs its own source code (don't cheat, you can't read it from the source file), radiation hardened quine is a quine that remains a quine if you remove any single character from the program.
- 3D game: Make a complete game with 3D graphics from 1st or 3rd man perspective that will have at least half an hour worth of gameplay time -- the gameplay can really be 2D (e.g. like wolf3D) but the graphics must be judged as 3D by average guy who sees the game. If your platform allows it at all, it must have basic sounds (no need for music, but e.g. shooting should at least make beeps and so on). The genre is up to you, it can be a shooter, platformer, RPG or anything where you control a character moving through 3D world. For the 3D graphics you can either use a 3D library, in which case you HAVE TO implement textured graphics (the textures may be procedural if you want), or you can write your own renderer. If you write custom renderer, then if it's a "true 3D", it can have just flat, untextured graphics; if it's a "pseudo 3D" (like raycasting or BSP, ...), it must have at least some texturing (e.g. walls).
- textured 3D software renderer: Make 3D software renderer that rasterizes triangles (just like for example OpenGL), with texturing. Affine texture mapping (i.e. the easier, incorrect texturing by linear interpolation of texturing coordinates in screen space) will pass, but thumbs up for perspective correct texture mapping. Implement some basic shading like, e.g. Goraud with ambient and diffuse light. You have to handle visibility even of non-convex shapes, e.g. with z-buffer or at least approximately by sorting triangles. It's enough if you can display some textured model with setting camera position and rotation somehow. You don't have to handle any 3D formats, 3D models can just be passed as arrays of numbers. It is enough if you output static images e.g. to a file, but thumbs up for being able to handle real-time rendering, animation and having extra features like transparency, scene graph and so on. Extra thumbs up for not using float.
- regular expression library: Make a library for working with regular expressions. Implement at least the following operations: search of regular expression, substitution of regular expressions WITH capture groups and generating random strings by regular expression.
- chess AI: Use any sane approach to write a chess engine of reasonable strength. No, you can't just fork stockfish, write it from scratch. It has to support xboard or UCI interface, the strength must be such that it beats smolchess, Maia 1500, GNU chess, Dreamer, Stockfish or similar engine in a 10 game match with both engines having equivalent settings (search depth, time for move etc.); alternatively it can pass by getting stable rating over 1600 on lichess or by beating someone with FIDE rating over 1500 in a 10 game match. You get the idea.
- bitmap image editor: GIMP is bloated! You have to save us by writing a GUI image editor that's at least a bit more advanced than the original MS paint. It has to be able to save and load images (supporting just one format is enough), draw basic shapes (at least a line, rectangle and circle), copy/paste parts of the image (with rectangle select), resize the image as a whole (with scaling it), have fill bucket and adjust brightness and contrast of the whole image. It should be reasonably user friendly, i.e. upon quitting it should ask if you want to save the work etc. Thumbs up for extra features like filters (blur, invert, edge detect, ...), layers and so on.
- 64K intro: Make an impressive demoscene-style 3D intro with music that's at least 1 minute long and fits into 64 KB. It has to be good enough so that an average demoscener would approve it as not completely laughable.
- 3D path tracer without floating point: Write a path tracer (NOT a mere ray tracer) without using floating point. It can only produce static images that may just be saved to a file in some simple format (no need to draw real time animation to the screen). It must be possible to position and rotate the camera arbitrarily and to set its field of view. It has to support several shapes of objects in the scene: at least a sphere, plane and cylinder, and it must support transparent objects. Thumbs up for supporting polygonal models, depth of field and loading scene description from a file.
- gopher fulltext search engine: Create a whole search engine (with crawler, index creator, user frontend, ...) for the gopher network. It can store its database just to flat files (no need to use SQL or something like that). It has to allow at least very basic fulltext search, i.e. about each gopher site you'll have to remember which words it contains (and possibly their count), so that if the user searched e.g. for
cats dogs
, you'll give him sites that contain both of these words somewhere in their text. Besides this you can make simplifications (ignore case, don't support Unicode, special characters etc.). Thumbs up for additional features like creating a graphical map of the crawled gopherspace along the way.
Level 4: God Tier, !Nightmare!
- 3D physics engine without floating point: Warm up for the god tier by making a 3D physics engine without using floating point, usable in real time. It must support complex shapes, i.e. not just plain spheres ;) The engine can use rigid body or soft body physics, or both. It doesn't have to be physically accurate but should produce results that an average observer will judge realistic enough for a game.
- operating system: Make a whole self hosted operating system with your own custom kernel, with basic GUI and tools such as a text editor, file browser and programming language compiler. Throw in some games because without them your OS will be boring. Run the OS on real hardware. It doesn't have to support networking, sound, USB and similar bloat, but thumbs up if you manage even that.
- MMORPG: Make both client and server for an MMORPG game. The game has to support 3D graphics (but can also have 2D frontends) and have some basic lore that makes sense. Remember, it is MASSIVELY multiplayer game, so you have to be able to handle at least 1000 players connected at the same time on some kind of affordable computer. There must be chat, PvP and PvE combat. Thumbs up for releasing it all under CC0.
- Python: Implement the Python programming language, INCLUDING its whole standard library. Bonus points for finishing before the version you are implementing stops being supported.
- ruin bitcoin: Make a program that can mine one bitcoin by running for at most one minute on some consumer laptop released before year 2010. Warning: this is probably unsolvable, but if you solve it you may help save the planet :P
TODO: text editor, tetris, voice synth?, snake, JPG like compression, quadratic equation, fractals, 2D raycasting, fourier transform, primes, image library, web browser, diff, MD parser, sudoku solver/generator, bytebeat, markov chain, syntax beautifier, grep, some kinda server, function plotter, raytracer, pi digits, 2D physics engine, encryption?, procedural MIDI, machine translation?, maze gen., genetic prog., language recognizer, search engine, AI?, chat ...
Quiz/Questions/Problems
Here are some questions to test your LRS related knowledge :D
- What's the difference between free software and open source?
- Name at least 10 different programming languages.
- Why is text written on a piece of paper flipped horizontally when viewed in a mirror -- why is it not flipped vertically?
- Say we want to generate a random number from 0 to 999 (including both) with uniform probability distribution (i.e. every number is equally likely). In C we often do it using the modulo operator like this:
int num = rand() % 1000
. However there is a problem with this -- describe what the problem is and how its negative effect can be reduced. Hint: it's called modulo bias. - What's the difference between data and information?
- Bob has written a program and died. The program is now unmaintained. Bob's program uses 10 libraries. The probability that the API of one such library will be updated and changed in any given year is 5%. If this happens, Bob's program will stop working. During the next 5 years what is the probability of his program breaking?
- What will the following C (C99) snippet print out?
int x = 2; putchar('a' + ((1 == 3 > 2) + ++x));
- Order the following software by the date of the release of their 1.0 version from oldest to newest: TempleOS, MS DOS, original Unix, Linux, Windows. Also point out which one stands out from others and why.
- If you're running in a race and overtake the guy who's currently in third place, what place will you be in?
- We have two gears, each of same size and same number of teeth. Gear A is fixed in place, it can't move or rotate, gear B runs around gear A so that it keeps touching it (and therefore rotates along the way) until it gets to the place where it started. How many revolutions around its own axis (from your stationary point of view) has gear B made?
- What's the worst socioeconomic system in the world? You don't even have to say why because that would take too long.
- Manually convert the binary numeral 10110000000010110101 to hexadecimal.
Answers
- Though legally similar (but not identical), free software is a movement based on ethics and pursuing freedom for the software user, open source is evil business movement that avoids talking about ethics, it was forked from free software and is solely focused on exploiting free software licenses for making profit.
- C, C++, Java, JavaScrip, Python, Lisp, Forth, Brainfuck, Fortran, Pascal, Haskell, Prolog, Smalltalk, comun, ...
- The mirror doesn't flip the text, you flipped it by pointing it at the mirror -- you most likely flipped it horizontally so that's how you see it in the mirror, but you could as well have flipped it vertically; then the text would be flipped vertically in the mirror.
- Modulo bias happens when the random number generator's range is non-divisible by our desired range that we enforce with modulo operator -- with shown approach some numbers then have higher probability of being generated than others. For example if rand() here return numbers from 0 to 1023, there is only one way to get 999 (999 % 1000) but two ways to get 0 (0 % 1000 and 1000 % 1000), i.e. 0 is more likely to be generated. Common approach to reducing this effect is to repeatedly generate numbers until we get one falling into the "fair" range (this is not guaranteed to end so we should limit the maximum number of attempts).
- The relationship is commonly described like this: information is interpreted data. I.e. data is just a sequence of symbols, information is the knowledge we extract from it.
- The probability of program breaking is 1 minus probability of it not breaking. For a program to NOT break during one year, all libraries have to stay unchanged (probability 0.95 for each one): that's 0.95 * 0.95 * 0.95 * ... = 0.95^10. Similarly the probability of it not breaking during 5 years is (0.95^10)^5, so the probability of the program breaking in 5 years is around 92%.
e
- Original Unix (around 1970), MS DOS (1981), Windows (1985), Linux (1998), TempleOS (2007). Linux stands out because it's not an operating system, it's a kernel.
- third
- two (try it, see coin rotation paradox)
- capitalism
- B00B5