Everyone, probably, has some favorite topic in IT, besides the daily practical work, bringing sometimes only daily bread. Maybe someone in his spare time does cartoons or works on some game, maybe participates in the development of some social project or simply studies something new without special practical need, in one word - does something then for yourself, so to speak, for the soul.
My modest programming experience led me to believe that this kind of activity can be valuable in itself and not have specific practical goals. Certainly programming can bring creative satisfaction and, perhaps, a kind of aesthetic pleasure to someone; after all, in any sphere, people are eager to see their own harmony. Once upon a time, when I was still barely familiar with programming and even poorly understood the meaning of the word function in relation to writing code, I joked, saying that programming is an art. It was just an abandoned phrase at a friendly tea table. Someone played along to me by asking how I can prove it. I answered something like: “it’s not for nothing that Donald Knut called his anthology the art of programming”. But he knows a lot about it.
At that time, I was concerned with programming, as a dry science, difficult for me to understand, considering it a mixture of linguistics and mathematics. Of course, I already had an idea about HTML, but I only saw the program codes from afar and preferred to stay away from it all. A computer is a typewriter, an encyclopedia, a translator, sometimes a toy is what a computer for the humanities is, 10-15 years ago. Of course, you can still include work with mail, maybe a couple of things, but the main purpose of the computer for the humanities is to be a typewriter.
However, everything changes when there is a need to make a website. I don’t know how many humanitarians work in the field of information technologies and how many of them are engaged in programming, but I’m sure that our brother leads to writing code through the WEB. At least it was still quite recently. I recently met one young philologist-php-programmer from Siberia on the forum
dapf.ru, and he is probably not the only one. If you dig deeper, you can remember that the creator of the
Perl language, Larry Wall, who has a birthday on September 27, is a linguist by education. But back to the topic of art.
')
I changed my attitude to the already mentioned activity in this article many times after I tried to draw parallels between writing code and playing chess (or solving chess problems), as well as the effects they bring to the subject of the action.
In my opinion, a lot in common. It is quite possible to treat programming as a kind of game in which there is a place for tricks, psychology, and inherent magic only in this area. Perhaps, experienced programmers speak of examples of this magic when they talk about how they inherited code that is almost impossible to maintain, but does it work by some miracle ?!
In my opinion, the attitude to programming as a game can probably help to overcome a number of psychological barriers for people who consider writing code as a lot of graduates and students of special schools. The new generation, however, probably no longer understands how our parents were afraid about pressing the wrong key combination 20 years ago. Now much is available, there are no particular fears of damaging a home stationary PC, because someone else has a laptop, maybe two, in stock, and a tablet is hidden under the pillow. In a word - you can not hesitate to program ...
Since the essential stages of programming development have passed me by, and I always wanted to look a little into this area - partly out of curiosity, partly due to some historical and scientific interests - I decided, using my free time, to read a little textbook on the language
C by Dennis Ritchie and encode something, test something and compare something with something to make it more fun. Sorry to not be original, since I decided to reproduce - using standard C libraries - the same permutation algorithm I wrote about earlier.
The code was very cumbersome, since I tried to implement more functions on my own. Actually, writing this code was for me a kind of game, so to speak, a pleasure for the mind.
I must add that I would not alarm the Habr community with my “humanitarian code”, but simply publish this note without a code and mention any algorithms at all if there was one interesting point: my long code with enough functions and cycles after compiling on a Linux system, it turned out to be extremely quick. I even used the old links to find the fastest implementations in other languages.
At
this link , at the very bottom, the recursive algorithm of permutations on awk, which is marked by the author as the fastest.
I decided to compare the speed with my training example and, frankly, the results surprised me. For n = 10, awk produced the following result:
real time 1m16.770s (just in case the machine: AMD Phenom T1100 6x)
In summary: I finished my cold tea, which I stood on the table for 2 hours and pressed Enter, so I launched my newly compiled code.
The terminal gave me:
real time 0m13.411sC, amigo, - this is fantastic!C code. A complete non-recursive algorithm for generating all permutations in the lexicographical order (if read from right to left :)).#include <stdio.h> #include <string.h> #include <stdlib.h> //This reverse x. char revstring(char * x) { int i = strlen(x); int k=0; char c; while( i > k ) { i--; c=x[k]; x[k]=x[i]; x[i]=c; k++; } } //This cut x char subb (char * x, int i) { x[i]='\0'; } //This cut y char subb2 (char * y, int i) { int k = 0; while (k != strlen(y)+1) { y[k]=y[i]; i++; k++; } } //It gets an argumet like 1234 or abcd. All symbols must be uniqe int main (int argc, char *argv[]) { if (argc < 2) { printf("Enter an argument. Example 1234"); return 0; } char b[strlen(argv[1])]; char a[strlen(argv[1])]; int ij=0; while (ij!=strlen(argv[1])) { a[ij]=argv[1][ij]; b[ij]=argv[1][ij]; ij++; } a[ij]='\0'; b[ij]='\0'; revstring(a); printf("%s\n", a); int i; int j; char c; while (strcmp (a, b) !=0 ) { i=1; while(a[i] > a[i-1]) { i++; } j=0; while(a[j] < a[i]) { j++; } c=a[j]; a[j]=a[i]; a[i]=c; char x[strlen(a)+1]; char y[strlen(a)+1]; strcpy(x,a); strcpy(y,a); subb(x, i); revstring(x); subb2(y, i); sprintf(a, "%s%s", x,y); printf("%s\n", a); } }
Update:The code is fixed, the comparison with i-1 no longer leads to going beyond the array.
It is also nice to know that this implementation works in time comparable (acceptable, and maybe faster for small n) with a recursive algorithm on the same C.
The comparison was carried out with the code
on the following link.The recursive algorithm gave the running time for n = 11:
real 2m9.213s
user 0m2.920s
sys 0m26.290s
The algorithm from this note issued for n = 11:
real 2m15.510s
user 0m19.750s
sys 0m34.300s
For n = 10Recursive:
real 0m11.919s
user 0m0.340s
sys 0m2.390s
From this note:
real 0m12.128s
user 0m1.490s
sys 0m3.040s