人文科学の目(および手)を介したプログラミング。 個人的な経験。 少しの哲学

たぶん、誰もが、日常の実務に加えて、時には毎日のパンだけを持ち込むことに加えて、ITで何らかの好みのトピックを持っています。 暇なときに誰かが漫画を作ったり、ある種のゲームに取り組んだり、ある種のソーシャルプロジェクトの開発に参加したり、特定の実用的な必要性なしに何か新しいことを学んだりします。それから、いわば魂のために。



私のささやかなプログラミングの経験から、この種のアクティビティはそれ自体で価値があり、特定の実用的な目標はないという考えに至りました。 確かに、プログラミングは創造的な満足をもたらし、おそらく、誰かに独特の美的喜びをもたらします。 最終的に、どの分野でも、人々は自分の調和を見たいと思っています。 むかしむかし、プログラミングにほとんど精通しておらず、コードの記述に関連する単語関数の意味をあまり理解していないとき、プログラミングは芸術だと言って冗談を言いました。 それは友好的なお茶のテーブルで放棄されたフレーズでした。 誰かが私と一緒に遊んで、どうやってそれを証明できるのかと尋ねました。 私は、「ドナルド・クヌースが自分のアンソロジーをプログラミングの芸術と呼んだのは何の理由もない」と答えました。 しかし、彼はこれについて多くを知っています。



当時、私はプログラミングを言語学と数学の混合物であると考えると、私にとって理解しにくいドライサイエンスと見なしていました。 もちろん、それから私はすでにHTMLについてのアイデアを持っていましたが、プログラムコードは遠くからしか見なかったので、これらすべてから離れることを好みました。 コンピューターはタイプライター、百科事典、翻訳者、時にはおもちゃです。10〜15年前のコンピューターは人文科学にとってはそういうものです。 もちろん、ここでもメールでの作業を含めることができますが、さらに2、3のことがありますが、人文科学のコンピューターの主な目的はタイプライターになることです。



ただし、サイトを作成する必要がある場合はすべてが変わります。 情報技術の分野で何人の人文科学が働いており、そのうち何人がプログラミングに携わっているのかわかりませんが、私たちの兄弟がコードを書くのはWEBであると確信しています。 少なくともそれはごく最近のことです。 私は最近、 dapf.ruフォーラムシベリアの若い哲学者-phpプログラマーに会いました。 もっと深く掘り下げると、 Perl言語の作成者であるLarry Wall( 9月27日が誕生日である)がトレーニングによって言語学者であることを思い出すことができます。 しかし、芸術の話題に戻りましょう。



純粋に投機的にコードの記述とチェスのプレイ(またはチェスの問題の解決)の類似点、およびアクションの主題にもたらす効果を描くことを試みた後、私はこの記事で何度も言及したアクティビティに態度を変えました。



私の意見では、多くの共通点があります。 プログラミングを、トリックと心理学の場所があり、魔法のこの領域にのみ固有の一種のゲームとして扱うことはかなり可能です。 おそらく経験豊富なプログラマーは、維持するのがほとんど不可能なコードをどのように継承したかについて話しているときに、この魔法の例について話しているかもしれませんが、奇跡によって動作しますか?!



私の意見では、ゲームとしてのプログラミングに対する態度は、コード作成を特別な大学の卒業生や学生の運命であると考える人々にとって、多くの心理的障壁を克服するのに役立つでしょう。 しかし、新世代は、おそらく20年前に両親が間違ったキーの組み合わせをもう一度押すことを恐れていた方法をすでに理解できていません。 今では多くのものが利用できますが、自宅の固定型PCを損傷する恐れは特にありません。 つまり、ためらうことなくプログラミングできます...



プログラミングの開発の重要な段階が過ぎ去ったので、私は常にこの分野を少し見たいと思っていました-一部は歴史的および科学的興味のためで、一部は好奇心から-私は自由時間を使ってデニスリッチー海の小さな教科書を読み、何かをエンコードし、何かをテストし、何かを何かと比較して、それをもっと楽しくします。 オリジナルではないことを許してください。標準Cライブラリを使用して、前に書いたのと同じ置換アルゴリズムを再現することにしました。



自分でもっと多くの機能を実装しようとしたので、コードは非常に面倒でした。 実際、このコードを書くことは私にとって一種のゲームであり、いわば心にとっての喜びでした。



「人道主義のコード」でHabrコミュニティを悩ませることはありませんでしたが、コードやアルゴリズムの言及なしでこの記事を投稿しただけでした。 Linuxシステムでコンパイルした後、非常にスマートであることが判明しました。 古いリンクをクロールして、他の言語で最速の実装を見つけました。



このリンクの下部には、著者が最速としてマークした再帰的なawk置換アルゴリズムがあります。



私は、ケーススタディと速度を比較することにしました。率直に言って、結果は私を驚かせました。 n = 10の場合、awkは次の結果を生成しました: リアルタイム1m16.770s念のため、マシン:AMD Phenom T1100 6x)



その結果、テーブルに2時間立ってアイスティーを完成させ、Enterキーを押したので、新しくコンパイルしたコードを実行しました。

ターミナルは私にくれました: リアルタイム0m13.411s



C、アミーゴ-素晴らしい!



Cコード。 辞書順ですべての順列を生成するための完全な非再帰アルゴリズム(右から左に読む場合:))。
#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); } }
      
      







更新:

コードは修正されており、i-1との比較で配列の範囲外になることはなくなりました。



また、この実装は、同じCの再帰アルゴリズムと同等の時間(許容できる、または小さいnの場合は高速)で機能することを知っていると便利です。

比較は、次のリンクのコードを使用して実行されました



再帰アルゴリズムは、n = 11のランタイムを生成しました。

実2m9.213s

ユーザー0m2.920s

sys 0m26.290s

n = 11に対して生成されたこのノートのアルゴリズム:

実2m15.510s

ユーザー0m19.750s

sys 0m34.300s



n = 10の場合

再帰的:

実際の0m11.919s

ユーザー0m0.340s

sys 0m2.390s



このメモから:

実数0m12.128s

ユーザー0m1.490s

sys 0m3.040s



All Articles