• Programming -- Stackoverflow

  • Như chúng ta đã biết, để viết 1 hàm tính giai thừa rất đơn giản, có thể dùng vòng lặp for hay đệ quy...
    Nhưng vấn đề đặt ra ở đây là trong những cách trên ta đều phải dùng 1 biến để lưu kết quả, mà 1 biến như vậy chắc chắn sẽ bị hạn chế.Vì sao ???
    Kiểu dữ liệu rất lớn như long long cũng chỉ biểu diễn được -9 223 372 036 854 775 808 tới 9 223 372 036 854 775 807
    Nếu ta dùng unsigned long long thì được từ 0 đến 18 446 744 073 709 551 615
    Như vậy lớn nhất thì cũng chỉ biểu diễn được các số có khoảng 19 chữ số, vậy lớn hơn thì sao ??? , ta phải lưu kết quả vào biến nào.
    20!=2432902008176640000, OK,  19 chữ số vẫn được
    Vậy 21!=20! . 21 >  20! . 10 ---> kết quả ít nhất cũng có 20 chữ số, mà chính xác là 21!=51090942171709440000
    Vậy từ 21 trở đi, làm sao để tính giai thừa ,100!=???, 1000!=???,             tính đươc không? Được.


    Nếu dùng 1 biến lưu kết quả không được, vậy tại sao ta không dùng mảng, một mảng thì có thể khai báo chứa mấy chục nghìn phần tử hoặc hơn nữa, mỗi phần tử ta biểu diễn 1 chữ số của kết quả, như vậy ta có thể biểu diễn được số có tới mấy chục nghìn chữ số, như vậy là OK hơn rất nhiều so với 19 chữ số như cách thông thường.


    Vậy làm sao để lưu các chữ số vào 1 phần tử của mảng đây ???

    Chúng ta có thể nghiên cứu thuật toán sau:
    n!=1.2.3...(n-1).n

    Ý tưởng ta sẽ làm như sau:

    Ban đầu ta nhân 1.2 trước, được bao nhiêu thì lưu vào mảng.
    1.2=2, vì 2 chỉ có 1 chữ số nên ta chỉ cần dùng 1 phần tử,   lưu 2 vào A[0].
    KQ     2: A[0]
                     2
    Tiếp tục nhân tiếp với 3, A[0].3=6 cũng chỉ có 1 chữ số, ta lưu 6 vào A[0], như vậy A[0] bây giờ bằng 6 chứ ko phải bằng 2 nữa.
    KQ      6: A[0]
                      6
    Tiếp tục nhân tiếp với 4, A[0].4=24, nên nhớ một phần tử ta chỉ lưu 1 chữ số của kết qủa, vậy ta lưu A[0] bằng 4, còn 2 ??? , ta sẽ lưu 2 vào A[1] ( khi này mảng có 2 phần tử )
    KQ    24: A[1] A[0]
                      2      4
    Tiếp tục, nhân tiếp cho 5
                                         24
                                      x   5
                                       120
    lấy 4 nhân 5 được 20, viết 0, nhớ 2,
    2 nhân 5 được 10, nhớ 2 ở hàng đơn vị nữa là 12, vậy kết quả là 120.
    Hoàn toàn tương tự, bây giờ A[0]=4 đóng vai trò là hàng đơn vị, A[1]=2 đóng vai trò là hàng chục
    A[0].5=20, vì mỗi phần tử của mảng chỉ lưu một chữ số  nên  A[0]=0, nhớ 2 vào hàng chục, vậy ta sẽ dùng 1 biến r để lưu giá trị nhớ này, r=2; lấy A[1].5=2.5=10, cộng với r=2 nữa( dư ở hàng đơn vị ) là được 12, mà 12 thì có 2 chữ số, một mình A[1] không thể lưu  , vậy ta lưu A[1]=2, còn chữ số 1 lưu vào A[2].
    kết qủa 120 tương ứng A[2] A[1] A[0]
                                            1       2       0
    Tiếp tục, nhân tiếp cho 6
                                           120                        A[2] A[1] A[0]
                                          x   6                     x                     6
                                           720                          7       2      0

    0 nhân 6 được 0; viết 0
    2 nhân 6 được 12, viết 2 nhớ 1
    1 nhân 6 được 6, nhớ 1 nữa là 7, vậy kết quả là 720

    Hoàn toàn tương tự
    A[0].6=0.6=0, suy ra A[0]=0, số dư để cộng vào khi nhân A[1] là r=0;
    A[1].6=2.6=12, cộng với r=0, vẫn là 12, suy ra A[1]=2, nhớ 1 vào biến r, gán r=1
    A[2].6=6, cộng r=1 nữa là 7, vậy A[2]=7

    kết qủa 720 tương ứng A[2] A[1] A[0]
                                            7       2       0


    Tiếp tục nhân cho 7
                                           720                        A[2] A[1] A[0]
                                          x   7                     x                     7
                                         5040                        50       4      0


    A[0].7=0.7=0, suy ra A[0]=0; r=0;
    A[1].7=2.4=14, cộng r=0 vẫn là 14, suy ra A[1]=4, r=1;
    A[2].7=7.7=49, cộng r=1 nữa là 50, suy ra A[2]=0, lâý thêm A[3]=5
    Kết quả 5040 tương ứng A[3] A[2] A[1] A[0]
                                               5       0       4      0
    ( bây giờ mảng có 4 phần tử chứa 4 chữ số của kết quả )


    Hoàn toàn tương tự, tiếp tục nhân cho 8, rồi nhân cho 9, .... , nhân cho n thì sẽ được kết quả

    Vậy quy luật của nó là gì ???

    Bước đầu ta sẽ khởi tạo 1 mảng có 1 phần tử, A[0]=1
    Ta sẽ lấy mảng này nhân cho 2, kết quả như thế nào thì lưu lại vào mảng
    Tiếp tục lấy mảng kết quả trên nhân cho 3, kết quả như thế nào thì lưu lại vào mảng
    Tiếp tục như vậy khi nhân tới n thì mảng cuối cùng sẽ cho ta kết quả của n!
    Việc còn lại chỉ là in mảng đó ra là xong
    Để chạy vòng lặp này, rất đơn giản, ta chỉ cần for(i=2;i<=n;i++){  thực hiện nhân và lưu kết quả lại vào mảng }

    Bây giờ xét: "thực hiện nhân và lưu kết quả lại vào mảng"
    Xét trong 1 quá trình mảng nhân với i ( 2<=i <=n ), khi này mảng có m phần tử
    Ta sẽ lấy từng phần tử của mảng nhân với i, từ A[0] đến A[m]
    Xét 1 phần tử bất kì A[j], có r là số dư khi nhân i với phần tử A[j-1];
    Gán s=A[j]*i+r; ( A[j] của mảng trước khi nhân )
    Vì A[j] chỉ lưu được 1 chữ số nên ta lưu A[j]=s%10 ( A[j] của mảng sau khi nhân )
    còn số dư r=s/10;
    Cứ tiếp tục như vậy đến A[m-1]- phần tử cuối cùng của mảng, nếu khi đó r=0 thì coi như xong, ta được một mảng mới.
    Vậy r>0 thì sao???
    Ta sẽ lấy thêm 1 phần tử để lưu vào mảng, A[m]=r; khi này mảng có m+1 phần tử
    Nhưng nếu r>=10 thì sao ???, ta không thể lưu A[m]=r ( vì mỗi phần tử chỉ lưu 1 chữ số )
    Vậy ta lưu A[m]=r%10; tăng số phần tử của mảng lên 1 đơn vị và r=r/10;
    Nếu r>0 thì tiếp tục lưu A[m+1]=r%10, tăng số phần tử của mảng lên 1 đơn vị nữa;
    Cứ tiếp tục như vậy cho đến khi số dư r bằng 0 thì sẽ không cần phải tìm một phần tử nữa của mảng để lưu kết quả và mảng mới coi như đã hoàn thành

    Vậy code của việc " thực hiện nhân và lưu kết quả lại vào mảng" là:

    for(j=0;j<m;j++){
                    s=A[j]*i+r;
                    A[j]=s%10;
                    r=s/10; }
    while(r>0){
                     A[m]=r%10;
                     m++;
                     r/=10;  }

    Khi ban đầu khởi tạo, m( số phần tử của mảng) =1; còn r=0 ( vì mới lúc đầu nhân thì ta chưa có số dư nào cả ), nên khởi tạo mảng có số phần tử tối đa lơn môtj tí  cho chắc

                           
    Ta cũng có thể không dùng biến s
    ta sẽ lưu r=q; r=(A[j]*i+r)/10; A[j]=(A[j]*i+r)%10;

    Cách này chắc chắn không tối ưu, nhưng không sao, số ta tính được giai thừa cũng khá lớn rồi, lớn hơn rất nhiều so với số 20 của cách thông thường

    Vậy chương trinh có thể viết như sau:


    #include<stdio.h>

    void giaithua(int n );

    int main(){

    int n;
    printf("Nhap so can tinh giai thua: "); scanf("%d",&n);
    printf("Ket qua la: ");
    giaithua(n);
    }

    void giaithua(int n){

    int A[500000],i,j,m=1;
    long long r=0,q;
    A[0]=1;
    for(i=2;i<=n;i++){
    for(j=0;j<m;j++){
    q=r;
    r=(A[j]*i+r)/10;
    A[j]=(A[j]*i+q)%10;
    }
    while(r>0){
    A[m]=r%10;
            m++;
            r=r/10;
    }
    }
    for(i=m-1;i>=0;i--)  printf("%d",A[i]);
    }


    Demo:





    Mở rộng:


    Ta dùng một phần tử của mảng để lưu 1 chữ số của kết quả, vậy tại sao ta không dùng một phần tử của mảng để lưu 2, 3 hay 4 chữ số của kết quả. Như vậy được không ???
    Cái khó ở cách này là nếu mỗi phần tử mảng lưu i chữ số của kết quả mà khi tính được chỉ có j<i chữ số thì ta phải tự động thêm vào i-j chữ số 0 phía trước khi in kết quả( ví dụ mỗi mảng lưu 4 chữ số, A[3]=23 thì phải chuyển A[3]=0023), cái này chắc phải dùng thêm 1 hàm xuất vậy,  mà nếu  vậy thì lại tốn thêm thời gian gọi hàm xuất, chưa chắc chương trình chay nhanh hơn.
    Việc thực hiện lưu như vậy cũng dễ gây hiện tượng tràn biến q, r  hơn so với lưu 1 chữ số ( tại sao ??? - bởi A[j] càng lớn thì A[j]*i+r sẽ càng lớn )

    Có thể thuật toán này chưa tối ưu nhất, nhưng nó cũng tính được giai thừa của số khoảng 40000, lớn hơn rất nhiều so với số 20 của cách thông thường


    Giai thừa của số lớn -C/C++

    Posted at  6:35 AM  |  in    |  Read More»

    Như chúng ta đã biết, để viết 1 hàm tính giai thừa rất đơn giản, có thể dùng vòng lặp for hay đệ quy...
    Nhưng vấn đề đặt ra ở đây là trong những cách trên ta đều phải dùng 1 biến để lưu kết quả, mà 1 biến như vậy chắc chắn sẽ bị hạn chế.Vì sao ???
    Kiểu dữ liệu rất lớn như long long cũng chỉ biểu diễn được -9 223 372 036 854 775 808 tới 9 223 372 036 854 775 807
    Nếu ta dùng unsigned long long thì được từ 0 đến 18 446 744 073 709 551 615
    Như vậy lớn nhất thì cũng chỉ biểu diễn được các số có khoảng 19 chữ số, vậy lớn hơn thì sao ??? , ta phải lưu kết quả vào biến nào.
    20!=2432902008176640000, OK,  19 chữ số vẫn được
    Vậy 21!=20! . 21 >  20! . 10 ---> kết quả ít nhất cũng có 20 chữ số, mà chính xác là 21!=51090942171709440000
    Vậy từ 21 trở đi, làm sao để tính giai thừa ,100!=???, 1000!=???,             tính đươc không? Được.


    Nếu dùng 1 biến lưu kết quả không được, vậy tại sao ta không dùng mảng, một mảng thì có thể khai báo chứa mấy chục nghìn phần tử hoặc hơn nữa, mỗi phần tử ta biểu diễn 1 chữ số của kết quả, như vậy ta có thể biểu diễn được số có tới mấy chục nghìn chữ số, như vậy là OK hơn rất nhiều so với 19 chữ số như cách thông thường.


    Vậy làm sao để lưu các chữ số vào 1 phần tử của mảng đây ???

    Chúng ta có thể nghiên cứu thuật toán sau:
    n!=1.2.3...(n-1).n

    Ý tưởng ta sẽ làm như sau:

    Ban đầu ta nhân 1.2 trước, được bao nhiêu thì lưu vào mảng.
    1.2=2, vì 2 chỉ có 1 chữ số nên ta chỉ cần dùng 1 phần tử,   lưu 2 vào A[0].
    KQ     2: A[0]
                     2
    Tiếp tục nhân tiếp với 3, A[0].3=6 cũng chỉ có 1 chữ số, ta lưu 6 vào A[0], như vậy A[0] bây giờ bằng 6 chứ ko phải bằng 2 nữa.
    KQ      6: A[0]
                      6
    Tiếp tục nhân tiếp với 4, A[0].4=24, nên nhớ một phần tử ta chỉ lưu 1 chữ số của kết qủa, vậy ta lưu A[0] bằng 4, còn 2 ??? , ta sẽ lưu 2 vào A[1] ( khi này mảng có 2 phần tử )
    KQ    24: A[1] A[0]
                      2      4
    Tiếp tục, nhân tiếp cho 5
                                         24
                                      x   5
                                       120
    lấy 4 nhân 5 được 20, viết 0, nhớ 2,
    2 nhân 5 được 10, nhớ 2 ở hàng đơn vị nữa là 12, vậy kết quả là 120.
    Hoàn toàn tương tự, bây giờ A[0]=4 đóng vai trò là hàng đơn vị, A[1]=2 đóng vai trò là hàng chục
    A[0].5=20, vì mỗi phần tử của mảng chỉ lưu một chữ số  nên  A[0]=0, nhớ 2 vào hàng chục, vậy ta sẽ dùng 1 biến r để lưu giá trị nhớ này, r=2; lấy A[1].5=2.5=10, cộng với r=2 nữa( dư ở hàng đơn vị ) là được 12, mà 12 thì có 2 chữ số, một mình A[1] không thể lưu  , vậy ta lưu A[1]=2, còn chữ số 1 lưu vào A[2].
    kết qủa 120 tương ứng A[2] A[1] A[0]
                                            1       2       0
    Tiếp tục, nhân tiếp cho 6
                                           120                        A[2] A[1] A[0]
                                          x   6                     x                     6
                                           720                          7       2      0

    0 nhân 6 được 0; viết 0
    2 nhân 6 được 12, viết 2 nhớ 1
    1 nhân 6 được 6, nhớ 1 nữa là 7, vậy kết quả là 720

    Hoàn toàn tương tự
    A[0].6=0.6=0, suy ra A[0]=0, số dư để cộng vào khi nhân A[1] là r=0;
    A[1].6=2.6=12, cộng với r=0, vẫn là 12, suy ra A[1]=2, nhớ 1 vào biến r, gán r=1
    A[2].6=6, cộng r=1 nữa là 7, vậy A[2]=7

    kết qủa 720 tương ứng A[2] A[1] A[0]
                                            7       2       0


    Tiếp tục nhân cho 7
                                           720                        A[2] A[1] A[0]
                                          x   7                     x                     7
                                         5040                        50       4      0


    A[0].7=0.7=0, suy ra A[0]=0; r=0;
    A[1].7=2.4=14, cộng r=0 vẫn là 14, suy ra A[1]=4, r=1;
    A[2].7=7.7=49, cộng r=1 nữa là 50, suy ra A[2]=0, lâý thêm A[3]=5
    Kết quả 5040 tương ứng A[3] A[2] A[1] A[0]
                                               5       0       4      0
    ( bây giờ mảng có 4 phần tử chứa 4 chữ số của kết quả )


    Hoàn toàn tương tự, tiếp tục nhân cho 8, rồi nhân cho 9, .... , nhân cho n thì sẽ được kết quả

    Vậy quy luật của nó là gì ???

    Bước đầu ta sẽ khởi tạo 1 mảng có 1 phần tử, A[0]=1
    Ta sẽ lấy mảng này nhân cho 2, kết quả như thế nào thì lưu lại vào mảng
    Tiếp tục lấy mảng kết quả trên nhân cho 3, kết quả như thế nào thì lưu lại vào mảng
    Tiếp tục như vậy khi nhân tới n thì mảng cuối cùng sẽ cho ta kết quả của n!
    Việc còn lại chỉ là in mảng đó ra là xong
    Để chạy vòng lặp này, rất đơn giản, ta chỉ cần for(i=2;i<=n;i++){  thực hiện nhân và lưu kết quả lại vào mảng }

    Bây giờ xét: "thực hiện nhân và lưu kết quả lại vào mảng"
    Xét trong 1 quá trình mảng nhân với i ( 2<=i <=n ), khi này mảng có m phần tử
    Ta sẽ lấy từng phần tử của mảng nhân với i, từ A[0] đến A[m]
    Xét 1 phần tử bất kì A[j], có r là số dư khi nhân i với phần tử A[j-1];
    Gán s=A[j]*i+r; ( A[j] của mảng trước khi nhân )
    Vì A[j] chỉ lưu được 1 chữ số nên ta lưu A[j]=s%10 ( A[j] của mảng sau khi nhân )
    còn số dư r=s/10;
    Cứ tiếp tục như vậy đến A[m-1]- phần tử cuối cùng của mảng, nếu khi đó r=0 thì coi như xong, ta được một mảng mới.
    Vậy r>0 thì sao???
    Ta sẽ lấy thêm 1 phần tử để lưu vào mảng, A[m]=r; khi này mảng có m+1 phần tử
    Nhưng nếu r>=10 thì sao ???, ta không thể lưu A[m]=r ( vì mỗi phần tử chỉ lưu 1 chữ số )
    Vậy ta lưu A[m]=r%10; tăng số phần tử của mảng lên 1 đơn vị và r=r/10;
    Nếu r>0 thì tiếp tục lưu A[m+1]=r%10, tăng số phần tử của mảng lên 1 đơn vị nữa;
    Cứ tiếp tục như vậy cho đến khi số dư r bằng 0 thì sẽ không cần phải tìm một phần tử nữa của mảng để lưu kết quả và mảng mới coi như đã hoàn thành

    Vậy code của việc " thực hiện nhân và lưu kết quả lại vào mảng" là:

    for(j=0;j<m;j++){
                    s=A[j]*i+r;
                    A[j]=s%10;
                    r=s/10; }
    while(r>0){
                     A[m]=r%10;
                     m++;
                     r/=10;  }

    Khi ban đầu khởi tạo, m( số phần tử của mảng) =1; còn r=0 ( vì mới lúc đầu nhân thì ta chưa có số dư nào cả ), nên khởi tạo mảng có số phần tử tối đa lơn môtj tí  cho chắc

                           
    Ta cũng có thể không dùng biến s
    ta sẽ lưu r=q; r=(A[j]*i+r)/10; A[j]=(A[j]*i+r)%10;

    Cách này chắc chắn không tối ưu, nhưng không sao, số ta tính được giai thừa cũng khá lớn rồi, lớn hơn rất nhiều so với số 20 của cách thông thường

    Vậy chương trinh có thể viết như sau:


    #include<stdio.h>

    void giaithua(int n );

    int main(){

    int n;
    printf("Nhap so can tinh giai thua: "); scanf("%d",&n);
    printf("Ket qua la: ");
    giaithua(n);
    }

    void giaithua(int n){

    int A[500000],i,j,m=1;
    long long r=0,q;
    A[0]=1;
    for(i=2;i<=n;i++){
    for(j=0;j<m;j++){
    q=r;
    r=(A[j]*i+r)/10;
    A[j]=(A[j]*i+q)%10;
    }
    while(r>0){
    A[m]=r%10;
            m++;
            r=r/10;
    }
    }
    for(i=m-1;i>=0;i--)  printf("%d",A[i]);
    }


    Demo:





    Mở rộng:


    Ta dùng một phần tử của mảng để lưu 1 chữ số của kết quả, vậy tại sao ta không dùng một phần tử của mảng để lưu 2, 3 hay 4 chữ số của kết quả. Như vậy được không ???
    Cái khó ở cách này là nếu mỗi phần tử mảng lưu i chữ số của kết quả mà khi tính được chỉ có j<i chữ số thì ta phải tự động thêm vào i-j chữ số 0 phía trước khi in kết quả( ví dụ mỗi mảng lưu 4 chữ số, A[3]=23 thì phải chuyển A[3]=0023), cái này chắc phải dùng thêm 1 hàm xuất vậy,  mà nếu  vậy thì lại tốn thêm thời gian gọi hàm xuất, chưa chắc chương trình chay nhanh hơn.
    Việc thực hiện lưu như vậy cũng dễ gây hiện tượng tràn biến q, r  hơn so với lưu 1 chữ số ( tại sao ??? - bởi A[j] càng lớn thì A[j]*i+r sẽ càng lớn )

    Có thể thuật toán này chưa tối ưu nhất, nhưng nó cũng tính được giai thừa của số khoảng 40000, lớn hơn rất nhiều so với số 20 của cách thông thường


    Một tác phẩm khá hay và thú vị - Đạo lập trình ( được biên dịch từ  The Tao Of Programming )

    Phần 1 :  Khoảng trống tĩnh lặng

    Lập trình sư truyền dạy rằng: 

    “Khi ngươi học được cách lấy mã lỗi từ trong đoạn code bắt lỗi, ngươi có thể xuống núi”

    1.1

    Hình thành một cách thần bí, sinh ra từ hư vô. Đơn độc và bất động nhưng không ngừng vận động. Là nguồn gốc của mọi chương trình. Ta không biết tên nó là gì nên ta gọi nó là Đạo.
    Đạo mà hay thì hệ điều hành sẽ hay. Hệ điều hành mà hay thì trình biên dịch sẽ hay. Trình biên dịch mà hay thì chương trình ắt sẽ hay. Chương trình hay thì bá tính an cư lạc nghiệp, vũ trụ thuận hòa.
    Đạo bao trùm vạn vật, lan toả thiên hà. Tựa như cơn gió mát giữa mùa viêm nhiệt, như cơn mưa rào giữa tiết hanh khô.

    1.2

    Đạo sinh máy ngữ, máy ngữ sinh hợp ngữ, hợp ngữ sinh trình dịch, trình dịch sinh ngôn ngữ ngôn ngữ biến hóa vô cùng .
    Nay vạn ngữ đã hình thành. Một ngữ dù thấp kém đến đâu vẫn có mục đích của nó. Mỗi ngữ đều thể hiện tính âm dương của phần mềm. Mỗi ngữ đều có một vị trí trong Đạo.
    Tuy nhiên nếu được lựa chọn, các ngươi không nên chọn ngữ COBOL để lập trình.

     1.3

    Khởi thủy từ Đạo. Đạo sinh thời gian và tài nguyên. Nên thời gian và tài nguyên chính là khía cạnh âm dương của Đạo vậy.
    Người lĩnh hội được Đạo luôn có đủ thời gian và tài nguyên để đạt được mục đích của mình. Kẻ không lĩnh hội được Đạo thì luôn thiếu. Không thể khác được.

     1.4

    Kẻ khôn ngoan khi nghe về Đạo thì làm theo. Kẻ bình thường khi nghe về Đạo thì nghiên cứu. Kẻ ngu dốt khi nghe về Đạo thì cười nhạo.
    Nếu không có kẻ cười nhạo chắc hẳn đã không thành Đạo.


    --------------------------------------------------------------------------------------------------------------------------

    BOOK 1: The Silent Void


    Thus spake the Master Programmer:

    "When you have learned to snatch the error code from the trap frame, it will be time for you to leave."

    1.1

    Something mysterious is formed, born in the silent void. waiting alone and unmoving, it is at once still and yet in constant motion. It is the source of all programs. I do not know its name, so I will call it the Tao of Programming.
    If the Tao is great, then the operating system is great.
    If the operating system is great, then the compiler is great.
    If the compiler is great, then the application is great.
    The user is pleased, and there is harmony in the world.
    The Tao of Programming flows far away and returns on the wind of morning.

    1.2

    The Tao gave birth to machine language. Machine language gave birth to the assembler.
    The assembler gave birth to the compiler. Now there are ten thousand languages.
    Each language has its purpose, however humble. Each language expresses the Yin and Yang of software. Each language has its place within the Tao.
    But do not program in COBOL if you can avoid it.

    1.3

    In the beginning was the Tao. The Tao gave birth to Space and Time.
    Therefore Space and Time are the Yin and Yang of programming.
    Programmers that do not comprehend the Tao are always running out of time and space for their programs. Programmers that comprehend the Tao always have enough time and space to accomplish their goals.
    How could it be otherwise?

    1.4


    The wise programmer is told about Tao and follows it. The average programmer is told about Tao and searches for it. The foolish programmer is told about Tao and laughs at it.

    If it were not for laughter, there would be no Tao.

    The highest sounds are hardest to hear. Going forward is a way to retreat. Great talent shows itself late in life. Even a perfect program still has bugs.

                                                           TO BE CONTINUTED .....


    Đạo lập trình / The Tao of Programming

    Posted at  5:07 AM  |  in    |  Read More»

    Một tác phẩm khá hay và thú vị - Đạo lập trình ( được biên dịch từ  The Tao Of Programming )

    Phần 1 :  Khoảng trống tĩnh lặng

    Lập trình sư truyền dạy rằng: 

    “Khi ngươi học được cách lấy mã lỗi từ trong đoạn code bắt lỗi, ngươi có thể xuống núi”

    1.1

    Hình thành một cách thần bí, sinh ra từ hư vô. Đơn độc và bất động nhưng không ngừng vận động. Là nguồn gốc của mọi chương trình. Ta không biết tên nó là gì nên ta gọi nó là Đạo.
    Đạo mà hay thì hệ điều hành sẽ hay. Hệ điều hành mà hay thì trình biên dịch sẽ hay. Trình biên dịch mà hay thì chương trình ắt sẽ hay. Chương trình hay thì bá tính an cư lạc nghiệp, vũ trụ thuận hòa.
    Đạo bao trùm vạn vật, lan toả thiên hà. Tựa như cơn gió mát giữa mùa viêm nhiệt, như cơn mưa rào giữa tiết hanh khô.

    1.2

    Đạo sinh máy ngữ, máy ngữ sinh hợp ngữ, hợp ngữ sinh trình dịch, trình dịch sinh ngôn ngữ ngôn ngữ biến hóa vô cùng .
    Nay vạn ngữ đã hình thành. Một ngữ dù thấp kém đến đâu vẫn có mục đích của nó. Mỗi ngữ đều thể hiện tính âm dương của phần mềm. Mỗi ngữ đều có một vị trí trong Đạo.
    Tuy nhiên nếu được lựa chọn, các ngươi không nên chọn ngữ COBOL để lập trình.

     1.3

    Khởi thủy từ Đạo. Đạo sinh thời gian và tài nguyên. Nên thời gian và tài nguyên chính là khía cạnh âm dương của Đạo vậy.
    Người lĩnh hội được Đạo luôn có đủ thời gian và tài nguyên để đạt được mục đích của mình. Kẻ không lĩnh hội được Đạo thì luôn thiếu. Không thể khác được.

     1.4

    Kẻ khôn ngoan khi nghe về Đạo thì làm theo. Kẻ bình thường khi nghe về Đạo thì nghiên cứu. Kẻ ngu dốt khi nghe về Đạo thì cười nhạo.
    Nếu không có kẻ cười nhạo chắc hẳn đã không thành Đạo.


    --------------------------------------------------------------------------------------------------------------------------

    BOOK 1: The Silent Void


    Thus spake the Master Programmer:

    "When you have learned to snatch the error code from the trap frame, it will be time for you to leave."

    1.1

    Something mysterious is formed, born in the silent void. waiting alone and unmoving, it is at once still and yet in constant motion. It is the source of all programs. I do not know its name, so I will call it the Tao of Programming.
    If the Tao is great, then the operating system is great.
    If the operating system is great, then the compiler is great.
    If the compiler is great, then the application is great.
    The user is pleased, and there is harmony in the world.
    The Tao of Programming flows far away and returns on the wind of morning.

    1.2

    The Tao gave birth to machine language. Machine language gave birth to the assembler.
    The assembler gave birth to the compiler. Now there are ten thousand languages.
    Each language has its purpose, however humble. Each language expresses the Yin and Yang of software. Each language has its place within the Tao.
    But do not program in COBOL if you can avoid it.

    1.3

    In the beginning was the Tao. The Tao gave birth to Space and Time.
    Therefore Space and Time are the Yin and Yang of programming.
    Programmers that do not comprehend the Tao are always running out of time and space for their programs. Programmers that comprehend the Tao always have enough time and space to accomplish their goals.
    How could it be otherwise?

    1.4


    The wise programmer is told about Tao and follows it. The average programmer is told about Tao and searches for it. The foolish programmer is told about Tao and laughs at it.

    If it were not for laughter, there would be no Tao.

    The highest sounds are hardest to hear. Going forward is a way to retreat. Great talent shows itself late in life. Even a perfect program still has bugs.

                                                           TO BE CONTINUTED .....


    Home
    PROGRAMMING.
    .
    back to top