Update
[less_retarded_wiki.git] / algorithm.md
blob0d2da1257b305667baf5035efb2d60ef70ed827e
1 # Algorithm
3 Algorithm (from the name of Persian mathematician Muhammad ibn Musa al-Khwarizmi) is an exact step-by-step description of how to solve some type of a problem. Algorithms are basically what [programming](programming.md) is all about: we tell [computers](computer.md), in very exact ways (with [programming languages](programming_language.md)), how to solve problems -- we write algorithms. But algorithms don't have to be just computer programs, they are simply exact instruction for solving problems. Although maybe not as obvious, [mathematics](math.md) is also a lot about creating algorithms because it strives to give us exact instructions for solving problems -- a mathematical formula usually tells us what we have to do to compute something, so in a way it is an algorithm too.
5 Cooking recipes are commonly given as an example of a non-computer algorithm, though they rarely contain branching ("if condition holds then do...") and loops ("while a condition holds do ..."), the key features of algorithms. The so called wall-follower is a simple algorithm to get out of any [maze](maze.md) which doesn't have any disconnected walls: you just pick either a left-hand or right-hand wall and then keep following it. Long division of numbers which students are taught at school is also an algorithm. You may write a crazy algorithm basically for any kind of problem, e.g. for how to clean a room or how to get a [girl](woman.md) to bed, but it has to be **precise** so that anyone can execute the algorithm just by blindly following the steps; if there is any ambiguity, it is not considered an algorithm; a vague, imprecise "hint" on how to find a solution (e.g. "the airport is somewhere in this general direction.") we rather call a [heuristic](heuristic.md). Heuristics are useful too and they may be utilized by an algorithm, e.g. to find a precise solution faster, but from programmer's point of view algorithms, the PRECISE ways of finding solutions, are the basics of everything.
7 Interesting fact: contrary to intuition there are problems that are mathematically proven to be unsolvable by any algorithm, see [undecidability](undecidability.md), but for most practically encountered problems we can write an algorithm (though for some problems even our best algorithms can be unusably [slow](time_complexity.md)).
9 Algorithms are mostly (possibly [not always](declarative.md), depending on exact definition of the term) written as a **series of steps** (or "instructions"); these steps may be specific actions (such as adding two numbers or drawing a pixel to the screen) or **conditional jumps** to other steps ("if condition X holds then jump to step N, otherwise continue"). At the lowest level ([machine code](machine_code.md), [assembly](assembly.md)) computers cannot do anything more complex than that: execute simple instructions (expressed as [1s and 0s](binary.md)) and perform conditional jumps -- in this computers are quite dumb (their strength comes from being able to execute many instruction with extreme speed). These jumps can be used to create **[branches](branch.md)** (in programming known as *if-then-else*) and **[loops](loop.md)**. Branches and loops are together known as [control structures](control_structure.md) -- they don't express a direct action but control which steps in the algorithm will follow. All in all, **any algorithm can be built just using these three basic constructs**:
11 - **sequence**: A series of steps, one after another. E.g. "write prompt, read number from input, multiply it by two, store it to memory".
12 - **selection** (branches, *if-then-else*): Two branches (blocks of instructions) preceded by a condition; the first branch is executed only if the condition holds, the second ("else") branch is executed only if the condition doesn't hold (e.g. "If user password is correct, log the user in, otherwise print out an error."). The second branch is optional (it may remain empty).
13 - **iteration** (loops, repetition): Sequence of steps that's repeated as long as certain condition holds (e.g. "As long as end of file is not reached, read and print out the next character from the file.").
15 Note: in a wider sense algorithms may be expressed in other (mathematically equivalent) ways than sequences of steps (non-[imperative](imperative.md) ways, see [declarative languages](declarative.md)), even mathematical equations are often called algorithms because they *imply* the steps towards solving a problem. But we'll stick to the common narrow meaning of algorithm given above.
17 Additional constructs can be introduced to make programming more comfortable, e.g. [subroutines/functions](function.md) (kind of small subprograms that the main program uses for solving the problem), [macros](macro.md) (shorthand commands that represent multiple commands) or [switch](switch.md) statements (selection but with more than two branches). Loops are also commonly divided into several types such as: counted loops, loops with condition and the beginning, loops with condition at the end and infinite loops (`for`, `while`, `do while` and `while (1)` in [C](c.md), respectively) -- in theory there can only be one generic type of loop but for convenience programming languages normally offer different "templates" for commonly used loops. Similarly to mathematical equations, algorithms make use of [variables](variable.md), i.e. values which can change and which have a specific name (such as *x* or *myVariable*).
19 Practical programming is based on expressing algorithms via [text](text.md), but visual programming is also possible: [flowcharts](flowchart.md) are a way of visually expressing algorithms, you have probably seen some. [Decision trees](decision_tree.md) are special cases of algorithms that have no loops, you have probably seen some too. Even though some languages (mostly educational such as [Snap](snap.md)) are visual and similar to flow charts, it is not practical to create big algorithms in this way -- serious programs are written as a text in [programming languages](programming_language.md).
21 ## Example
23 Let's write a simple algorithm that counts the number of divisors of given number *x* and checks if the number is [prime](prime.md) along the way. (Note that we'll do it in a [naive](naive.md), educational way -- it can be done better). Let's start by writing the steps in plain [English](english.md) (sometimes called [pseudocode](pseudocode.md)):
25 1. Read the number *x* from the input.
26 2. Set the *divisor counter* to 0.
27 3. Set *currently checked number* to 1.
28 4. While *currently checked number* is lower or equal than *x*:
29   - a: If *currently checked number* divides *x*, increase *divisor counter* by 1.
30   - b: Increase *currently checked number*.
31 5. Write out the *divisor counter*.
32 6. If *divisor counter* is equal to 2, write out the number is a prime.
34 Notice that *x*, *divisor counter* and *currently checked number* are [variables](variable.md). Step 4 is a loop (iteration) and steps *a* and 6 are branches (selection). The flowchart of this algorithm is:
36 ```
37                START
38                  |
39                  V
40                read x
41                  |
42                  V
43        set divisor count to 0
44                  |
45                  V
46        set checked number to 1
47                  |
48     .----------->|
49     |            |
50     |            V                no
51     |    checked number <= x ? ------.
52     |            |                   |
53     |            | yes               |
54     |            V                   |
55     |     checked number    no       |
56     |       divides x ? -------.     |
57     |            |             |     |
58     |            | yes         |     |
59     |            V             |     |
60     |     increase divisor     |     |
61     |       count by 1         |     |
62     |            |             |     |
63     |            |             |     |
64     |            |<------------'     |
65     |            |                   |
66     |            V                   |
67     |     increase checked           V
68     |       number by 1     print divisor count
69     |            |                   |
70     '------------'                   |
71                                      V             no
72                              divisor count = 2 ? -----.
73                                      |                |
74                                      | yes            |
75                                      V                |
76                            print "number is prime"    |
77                                      |                |
78                                      |<---------------'
79                                      V
80                                     END
82 ```
84 This algorithm would be written in [Python](python.md) as:
86 ```
87 x = int(input("enter a number: "))
89 divisors = 0
91 for i in range(1,x + 1):
92   if x % i == 0: # i divides x?
93     divisors = divisors + 1
95 print("divisors: " + str(divisors))
97 if divisors == 2:
98   print("It is a prime!")
99 ```
101 in [JavaScript](javascript.md) as:
104 function main()
106   let x = parseInt(prompt("enter a number:"));
107   let divisorCount = 0;
109   for (let i = 1; i <= x; ++i)
110     if (x % i == 0) // i divides x?
111       divisorCount++;
113   console.log("divisors: " + divisorCount);
115   if (divisorCount == 2)
116     console.log("It is a prime!");
120 in [C](c.md) as:
123 #include <stdio.h>
125 int main(void)
127   int x, divisors = 0;
129   printf("enter a number: ");
130   scanf("%d",&x); // read a number
132   for (int i = 1; i <= x; ++i)
133     if (x % i == 0) // i divides x?
134       divisors = divisors + 1;
136   printf("number of divisors: %d\n",divisors);
138   if (divisors == 2)
139     puts("It is a prime!");
141   return 0;
145 in [Forth](forth.md) as:
148 variable x
149 variable divisorCount 
151 : main
152   ." enter a number: "
153   0     \ number to read
155   begin \ read the number by digits
156     key
158     dup dup 48 >= swap 57 <= and
159     while
161     48 - swap 10 * +
162   repeat
163   drop
165   dup . cr
166   x !
167   0 divisorCount !
169   x @ 1+ 1 do
170     x @ i mod 0 = if \ i divides x?
171       1 divisorCount +!
172     then
173   loop
175   ." number of divisors: " divisorCount @ . cr
177   divisorCount @ 2 = if
178     ." It is a prime!" cr
179   then
182 main
186 in [comun](comun.md) as:
190 @@ # read X and convert to number
191   <-
192   $0 $0 "0" < >< "9" > | ? !@ .
193   "0" - >< 10 * +
197 0 # divisor count
198 1 # checked number
201   $0 $3 > ?     # checked num. > x ?
202     !@
203   .
205   $2 $1 % 0 = ? # checked num. divides x ?
206     $1 ++ $:2   # increase divisor count
207   .
209   ++ # increase checked number
212 0 "divisors: " --> # write divisor count
214 $1 10 >= ?
215   $1 10 / "0" + ->
218 $1 10 % "0" + -> 10 ->
220 $1 2 = ?
221   0 "It is a prime" --> 10 ->
225 in Scheme [Lisp](lisp.md) as (here notice the difference in [paradigm](paradigm.md) -- loop is replaced with [recursion](recursion.md), as it's done in [functional](functional.md) programming):
228 (define (countDivisors x countFrom currentCount) ; recursive function
229   (if (> countFrom x)
230     (begin
231       (display "divisor count: ")
232       (display currentCount)
233       (newline)
234       (if (= currentCount 2)
235         (display "It is a prime!\n")))
236     (countDivisors x (1+ countFrom)
237       (+ currentCount (if (zero? (remainder x countFrom)) 1 0)))))
239 (display "enter a number: ")
240 (countDivisors (read) 1 0)
243 and also for [fun](fun.md) in [Brainfuck](brainfuck.md) (a bit simplified version, made with our [Macrofucker](macrofucker.md) language):
246 [-]>[-]++++++++++++++++++++++++++++++++++++++++++++++++>,>[-]>[-]<<<[->>+>+<<<]
247 >>>[-<<<+>>>]<[-<->]<>[-]<[->+<]<[->+<]>>[-<<+>>]<[-]++++++++++++++++++++++++++
248 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>[-]>
249 [-]<<<[->>+>+<<<]>>>[-<<<+>>>]<>[-]>[-]<<<[->>+>+<<<]>>>[-<<<+>>>]<>[-]<<-[->>>
250 [-]>[-]<<<[->>+>+<<<]>>>[-<<<+>>>]<[-<+>]<<<]>>[-<<<+>>>]<<<>[-]+++++++++++++++
251 +++++++++++++++++++++++++++++++++>,>[-]>[-]<<<[->>+>+<<<]>>>[-<<<+>>>]<[-<->]<>
252 [-]<[->+<]<[->+<]>>[-<<+>>]<[-]++++++++++>[-]>[-]<<<[->>+>+<<<]>>>[-<<<+>>>]<>[
253 -]>[-]<<<[->>+>+<<<]>>>[-<<<+>>>]<>[-]<<-[->>>[-]>[-]<<<[->>+>+<<<]>>>[-<<<+>>>
254 ]<[-<+>]<<<]>>[-<<<+>>>]<<<>[-]<[->+<]<[->+<]>>[-<<+>>]<<>[-]>[-]<<<[->>+>+<<<]
255 >>>[-<<<+>>>]<[-<+>]<>[-]++++++++++++++++++++++++++++++++++++++++++++++++>,>[-]
256 >[-]<<<[->>+>+<<<]>>>[-<<<+>>>]<[-<->]<>[-]<[->+<]<[->+<]>>[-<<+>>]<<>[-]>[-]<<
257 <[->>+>+<<<]>>>[-<<<+>>>]<[-<+>]<>[-]<[->+<]<<<[->>>+<<<]>>>>[-<<<<+>>>>]<<<<>[
258 -]>[-]<<[->+>+<<]>>[-<<+>>]<[>[-]>[-]<<<[->>+>+<<<]>>>[-<<<+>>>]<>[-]>[-]<<<[->
259 >+>+<<<]>>>[-<<<+>>>]<>[-]>[-]<<<[->>+>+<<<]>>>[-<<<+>>>]<<<[-]>>>[-]>[-]>[-]<<
260 <<[->>>+>+<<<<]>>>>[-<<<<+>>>>]<>[-]>[-]<<<<[->>>+>+<<<<]>>>>[-<<<<+>>>>]<+<[->
261 ->[-]>[-]<<[->+>+<<]>>[-<<+>>]<>[-]+<[[-]>-<]>[<+>[-]]<[<<<+>>>[-]]<<]<>[-]+<[[
262 -]>-<]>[<+>[-]]<[<<<+>>>[-]>[-]<<<[->>+>+<<<]>>>[-<<<+>>>]<[-<->]<>[-]>[-]>[-]<
263 <<<[->>>+>+<<<<]>>>>[-<<<<+>>>>]<>[-]>[-]<<<<[->>>+>+<<<<]>>>>[-<<<<+>>>>]<+<[-
264 >->[-]>[-]<<[->+>+<<]>>[-<<+>>]<>[-]+<[[-]>-<]>[<+>[-]]<[<<<+>>>[-]]<<]<>[-]+<[
265 [-]>-<]>[<+>[-]]<]<>[-]<[->+<]<[->+<]>>[-<<+>>]<<>[-]+<[[-]>-<]>[<+>[-]]<[<<<<+
266 >>>>[-]]<<-]<<>[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
267 +++++++++++++++++++++++++++++++++++++++>[-]>[-]<<<[->>+>+<<<]>>>[-<<<+>>>]<>[-]
268 >[-]<<<[->>+>+<<<]>>>[-<<<+>>>]<>[-]>[-]<<<[->>+>+<<<]>>>[-<<<+>>>]<<<[-]>>>[-]
269 >[-]>[-]<<<<[->>>+>+<<<<]>>>>[-<<<<+>>>>]<>[-]>[-]<<<<[->>>+>+<<<<]>>>>[-<<<<+>
270 >>>]<+<[->->[-]>[-]<<[->+>+<<]>>[-<<+>>]<>[-]+<[[-]>-<]>[<+>[-]]<[<<<+>>>[-]]<<
271 ]<>[-]+<[[-]>-<]>[<+>[-]]<[<<<+>>>[-]>[-]<<<[->>+>+<<<]>>>[-<<<+>>>]<[-<->]<>[-
272 ]>[-]>[-]<<<<[->>>+>+<<<<]>>>>[-<<<<+>>>>]<>[-]>[-]<<<<[->>>+>+<<<<]>>>>[-<<<<+
273 >>>>]<+<[->->[-]>[-]<<[->+>+<<]>>[-<<+>>]<>[-]+<[[-]>-<]>[<+>[-]]<[<<<+>>>[-]]<
274 <]<>[-]+<[[-]>-<]>[<+>[-]]<]<>[-]<[->+<]<[->+<]>>[-<<+>>]<<>[-]<[->+<]<[->+<]>>
275 [-<<+>>]<>[-]++++++++++++++++++++++++++++++++++++++++++++++++>[-]>[-]<<<[->>+>+
276 <<<]>>>[-<<<+>>>]<[-<+>]<.<<<[-]++++++++++>>[-]>[-]<<<[->>+>+<<<]>>>[-<<<+>>>]<
277 >[-]>[-]<<<[->>+>+<<<]>>>[-<<<+>>>]<<<[-]>>>[-]>[-]>[-]<<<<[->>>+>+<<<<]>>>>[-<
278 <<<+>>>>]<>[-]>[-]<<<<[->>>+>+<<<<]>>>>[-<<<<+>>>>]<+<[->->[-]>[-]<<[->+>+<<]>>
279 [-<<+>>]<>[-]+<[[-]>-<]>[<+>[-]]<[<<<+>>>[-]]<<]<>[-]+<[[-]>-<]>[<+>[-]]<[<<<+>
280 >>[-]>[-]<<<[->>+>+<<<]>>>[-<<<+>>>]<[-<->]<>[-]>[-]>[-]<<<<[->>>+>+<<<<]>>>>[-
281 <<<<+>>>>]<>[-]>[-]<<<<[->>>+>+<<<<]>>>>[-<<<<+>>>>]<+<[->->[-]>[-]<<[->+>+<<]>
282 >[-<<+>>]<>[-]+<[[-]>-<]>[<+>[-]]<[<<<+>>>[-]]<<]<>[-]+<[[-]>-<]>[<+>[-]]<]<>[-
283 ]<[->+<]<[->+<]>>[-<<+>>]<<>[-]<[->+<]<[->+<]>>[-<<+>>]<>[-]+++++++++++++++++++
284 +++++++++++++++++++++++++++++>[-]>[-]<<<[->>+>+<<<]>>>[-<<<+>>>]<[-<+>]<.<>[-]<
285 [->+<]<[->+<]>>[-<<+>>]<>[-]++++++++++++++++++++++++++++++++++++++++++++++++>[-
286 ]>[-]<<<[->>+>+<<<]>>>[-<<<+>>>]<[-<+>]<.<<<<>[-]++++++++++.[-]++>[-]>[-]<<<[->
287 >+>+<<<]>>>[-<<<+>>>]<>[-]>[-]<<<[->>+>+<<<]>>>[-<<<+>>>]<[-<->]<>[-]+<[[-]>-<]
288 >[<+>[-]]<[[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
289 +++++++++++++++++++++++++++++++++++++++++++++++.[-]++++++++++++++++++++++++++++
290 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
291 +++++++.[-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
292 +++++++++++++++++++++++++++++++++++++.[-]++++++++++++++++++++++++++++++++++++++
293 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.[-]++++
294 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
295 ++++++++++++++++++.[-]++++++++++.[-]]
298 TODO: assembly, haskell, unix shell, ...
300 This algorithm is however not very efficient and could be **[optimized](optimization.md)** -- for example not only we wouldn't have to check if a number is divisible by 1 and itself (as every number is), but there is also no need to check divisors higher than the [square root](sqrt.md) of the checked value (mathematically above square root there only remain divisors that are paired with the ones already found below the square root) so we could lower the number of the loop iterations and so make the algorithm finish faster. You may try to improve the algorithm this way as an exercise :-)
302 ## Study of Algorithms
304 Algorithms are the core topic of [computer science](compsci.md), there's a lot of theory and knowledge about them.
306 [Turing machine](turing_machine.md), a kind of mathematical bare-minimum computer, created by [Alan Turing](turing.md), is the traditional formal tool for studying algorithms, though many other [models of computation](model_of_computation.md) exist -- for example [lambda calculus](lambda_calculus.md) that's a basis of [functional programming](functional.md) under which we already see algorithms in a bit different light: not as a series of steps but rather as evaluating mathematical functions. From theoretical computer science we know not all problems are [computable](computability.md), i.e. there are problems unsolvable by any algorithm (e.g. the [halting problem](halting_problem.md)). [Computational complexity](computational_complexity.md) is a theoretical study of resource consumption by algorithms, i.e. how fast and memory efficient algorithms are (see e.g. [P vs NP](p_vs_np.md)). [Mathematical programming](mathematical_programming.md) is concerned, besides others, with optimizing algorithms so that their time and/or space complexity is as low as possible which gives rise to algorithm design methods such as [dynamic programming](dynamic_programming.md) (practical [optimization](optimization.md) is a more pragmatic approach to making algorithms more efficient). [Formal verification](formal_verification.md) is a field that tries to mathematically (and sometimes automatically) prove correctness of algorithms (this is needed for critical software, e.g. in planes or medicine). [Genetic programming](generic_programming.md) and some other methods of [artificial intelligence](ai.md) try to automatically create algorithms (*algorithms that create algorithms*). [Quantum computing](quantum.md) is concerned with creating new kinds of algorithms for quantum computers (a new type of still-in-research computers). [Programming language](programming_language.md) design is the art and science of creating languages that express computer algorithms well. Etcetc.
308 ## Specific Algorithms
310 Following are some well known algorithms.
312 - [graphics](graphics.md)
313   - [DDA](dda.md): line drawing algorithm
314   - [discrete Fourier transform](fourier_transform.md): extremely important algorithm expressing signals in terms of frequencies
315   - [Bresenham's algorithm](bresenham.md): another line drawing algorithm
316   - [Midpoint algorithm](midpoint_algorithm.md): circle drawing algorithm
317   - [flood fill](flood_fille.md): algorithm for coloring continuous areas
318   - [FXAA](fxaa.md)
319   - [Hough transform](hough_transform.md): finds shapes in pictures
320   - [painter's algorithm](painters_algorithm.md)
321   - [path tracing](path_tracing.md)
322   - [ray tracing](ray_tracing.md)
323   - ...
324 - [math](math.md)
325   - [Boot'h algorithm](booths_algorithm.md): algorithm for multiplication
326   - [Dijkstra's algorithm](dijkstras_algorithm.md)
327   - [Euclidean algorithm](euclidean_algorithm.md): computes greatest common divisor
328   - [numerical algorithms](numerical.md): approximate mathematical functions
329   - [sieve of Eratosthenes](sieve_of_eratosthenes.md): computes [prime numbers](prime.md)
330   - ...
331 - [sorting](sorting.md)
332   - [bogosort](bogosort.md) (stupid sort)
333   - [bubble sort](bubble_sort.md): simple, kind of slow but still usable sorting algorithm
334   - [heap sort](heap_sort.md)
335   - [insertion sort](insertion_sort.md)
336   - [merge sort](merge_sort.md)
337   - [shaker sort](shaker_sort.md)
338   - [selection sort](selection_sort.md)
339   - [slow sort](slow_sort.md)
340   - [quick sort](quick_sort.md): one of the fastest sorting algorithms
341   - ...
342 - [searching](searching.md)
343   - [binary search](binary_search.md)
344   - [linear search](linear_search.md)
345   - ...
346 - [other](other.md)
347   - [A*](a_start.md): path searching algorithm, used by [AI](ai.md) in many [games](game.md)
348   - [backpropagation](backpropagation.md): training of [neural networks](neural_net.md)
349   - [fizzbuzz](fizzbuzz.md): problem/simple algorithm given in job interviews to filter out complete [noobs](noob.md)
350   - [FFT](fft.md): quickly converts signal (audio, image, ...) to its representation in frequencies, one of the most famous and important algorithms
351   - [Huffman coding](huffman_code.md): [compression](compression.md) algorithm
352   - [Kalman filter](kalman_filter.md)
353   - [k-means](k_means.md): [clustering](clustering.md) algorithm
354   - [MD5](md5.md): [hash](hash.md) function
355   - [backtracking](backtracking.md)
356   - [minimax](minimax.md) plus [alpha-beta pruning](alpha_beta.md): used by many [AI](ai.md)s that play turn based games
357   - [proof of work](proof_of_work.md) algorithms: used by some [cryptocurrencies](crypto.md)
358   - [RSA](rsa.md)
359   - [Shor's algorithm](shors_algorithm.md): [quantum](quantum.md) factorization algorithm
360   - [YouTube](youtube.md) algorithm: secret algorithm YouTube uses to suggest videos to viewers, a lot of people hate it :)
361   - ...
363 ## See Also
365 - [programming](programming.md)
366 - [design pattern](design_pattern.md)
367 - [recursion](recursion.md)