Tôi yêu lập trình. Chẳng có gì tuyệt hơn lập trình trong cuộc đời và phương châm là:
Bạn có thể lập trình mọi thứ, kể cả cuộc đời!
- Mark -
Nhưng lập trình để làm quái gì, và bản thân "lập trình" có ý nghĩa gì? Lập trình có nghĩa là bạn biến một loạt thao tác thành một chương trình (program) nên việc lập trình gọi là programming, tiếng Nhật gọi là プログラミング đọc là pừ-rô-gừ-ra-min-gự hay đại loại thế. Nếu đọc "programming" họ lại chẳng hiểu. Để lập trình bạn thường dùng
ngôn ngữ lập trình gọi là programming language ví dụ Java, C, Ruby, Visual Basic vv. Lập trình hơi khác với "coding", coding chỉ là viết mã (code) tức là viết mã nguồn (source) chương trình bằng ngôn ngữ lập trình nào đó.
Còn lập trình nói chung thì liên quan tới cái gọi là THUẬT TOÁN (algorithm, アルゴリズム), nói nôm na là phương thức giải quyết để đưa ra lời giải đúng, đôi khi gọi là "giải thuật" (cách giải).
Giải thích đơn giản về lập trình và thuật toán
Ví dụ "tit for tat": Ăn miếng trả miếng. Có ai chơi bạn bạn chơi lại liền.
Hoặc "tit for 2 tat": Ăn hai miếng trả một miếng. Có ai chơi bạn hai lần, bạn chơi lại một lần.
Hoặc "2 tit for 1 tat": Ăn một miếng trả hai miếng.
"Tiên hạ thủ vi cường": Đánh phủ đầu.
Mục đích là để lập trình khiến mọi người TÔN TRỌNG bạn. Còn các chiến lược trên là thuật toán. Bạn có thể áp dụng nhiều thuật toán khác nhau với nhiều người khác nhau.
Lập trình lịch nghỉ lễ Việt Nhật
Kết quả là như thế này:
Vì sao phải lập trình mà không làm thành bảng luôn cho nhanh? Vì như thế mỗi năm bạn phải làm một bản mới. Nếu chỉ làm một lần và chỉ cần thay năm vào nó tự tạo ra lịch (calendar) thì tuyệt nhỉ? Đây gọi là LẬP TRÌNH. Bạn sẽ chỉ làm một lần rồi cho chạy chương trình nhiều lần.
Ví dụ bạn cần tính công thức toán, bạn chỉ lập trình ra rồi lần sau nhập đầu vào (input) là sẽ tự động có kết quả đầu ra (output), ví dụ
JLPT Score Calculation Tool 2018.
Vậy lập trình như thế nào?
Trước hết là chúng ta xác định LÝ TƯỞNG về lịch nghỉ lễ: Chỉ cần nhập ngày đầu năm và năm đó (ví dụ 2018) là chương trình tự động tính ra ngày cả năm. Tháng 1 thì dễ rồi:
Ngày sau = Ngày trước + 1
Vấn đề là ngày 1 tháng 2 sẽ bắt đầu vào thứ mấy? Chúng ta phải tính được VỀ MẶT TOÁN HỌC, chứ không phải về mặt thị giác. Ví dụ ngày 1 tháng 1 bắt đầu là thứ Hai, thì ngày 31/1 là thứ Tư, do đó, ngày 1 tháng 2 là thứ Năm. Nghe có vẻ dễ hiểu nhưng khi vào lập trình thì không dễ như thế, vì chúng ta phải viết toán học.
Thế này nhé, cứ sau 7 ngày hết 1 tuần là lại về thứ cũ, tháng 1 có 31 ngày nên dư ra 3 ngày, nên sẽ là thứ cũ + 3. Ví dụ ngày 1 tháng 1 là thứ Hai, thì ngày 1 tháng 2 sẽ thêm 3 là thứ Năm.
Nhưng chúng ta sẽ không chắc ngày 1/1 có rơi vào thứ 2 không, nên chúng ta sẽ lấy biến số là Ngày của chủ nhật tuần đầu tiên để tính, vì ngày này chắc chắn tồn tại nhỉ? Nhỡ đâu ngày 1 rơi đúng chủ nhật thì từ thứ hai tới thứ bảy sẽ trống.
Thứ của ngày 1 = (7 - Ngày của chủ nhật MOD 7 + 1) MOD 7
Bạn phải dùng toán học mà tính ra công thức này. X MOD Y là số dư của X khi chia cho Y, ví dụ 4 MOD 7 = 4, 10 MOD 7 = 3, đôi khi viết là X % Y.
Ví dụ, ngày 1 rơi vào thứ Tư thì chủ nhật là ngày 5. Nên:
Thứ của ngày 1 = (7 - 5 MOD 7 + 1) MOD 7 = 3 MOD 7 = 3, ngày thứ 3 trong tuần, tức là thứ Tư vì thứ Hai = ngày thứ 1, thứ Ba = ngày thứ 2, vv.
Do đó, chúng ta tính được Thứ của ngày 1 tháng 1. Giờ là thứ của ngày 1 tháng 2:
Thứ của ngày 1 tháng 2 = (Thứ của ngày 1 tháng 1 + 1 + 3) MOD 7
+1 là vì thứ tiếp theo thì phải thêm 1, còn +3 là vì tháng 1 dư 3 ngày (31 - 28 = 3).
Giờ chúng ta sẽ tìm THUẬT TOÁN để điền vào tuần đầu tiên của tháng 2 (tức là có thể có ngày trống, ngày nào mà ngày 1 rơi đúng thứ đó mới là "1", ngày tiếp theo là "2"):
Ở ô Thứ Hai: IF Thứ của ngày 1 tháng 2 = 1 THEN Điền "1" ELSE Để trống
Ở ô Thứ Ba: IF Thứ của ngày 1 tháng 2 = 2 THEN Điền "1" ELSE Để trống
Tuy nhiên, nếu nhỡ ngày thứ Hai là ngày 1 thì thứ Ba do không phải ngày 1 sẽ bị để trống? Do đó, chúng ta phải sửa lại:
Ở ô Thứ Ba:
IF Thứ Hai không trống THEN Ngày thứ Ba = Ngày thứ Hai + 1
ELSE IF Thứ của ngày 1 tháng 2 = 2 THEN Điền "1" ELSE Để trống
Ngoài ra, tháng 2 bạn cũng phải tính số ngày vì nếu NĂM MOD 4 = 0 (năm chia hết cho 4) thì số ngày sẽ là 29, nên sẽ dư 1 ngày đó. Mỗi tháng tùy số ngày dư mà sẽ ảnh hưởng tới thứ của ngày 1 của tháng sau nhỉ?
Vậy làm sao để bạn điền cho hết ngày một tháng? Thuật toán là:
NẾU ngày hôm trước không trống VÀ ngày hôm trước < ngày tối đa THÌ ngày hôm sau = ngày hôm trước + 1 NẾU KHÔNG để trống
Đơn giản vậy thôi.
Sau khi lập trình xong thì bạn tha hồ làm lịch bất kỳ năm nào. Chỉ cần nhập năm vào là sẽ tự động ra lịch.
Nên nhớ là bạn có thể lập trình tự động mọi thứ trong cuộc đời, từ học tập, công việc, luyến ái, sự nghiệp, sở thích, tất tần tật.
Tôi thích lập trình và sẽ còn tiếp tục lập trình đều đều trong tương lai.
Good day!
Mark
Bài tập thuật toán lập trình: Hãy tính ngày 1 tháng 1 kể từ năm 2018 rơi vào thứ mấy trong tuần.
+Xem đáp án
WeekdayNo = (ThisYear - 2017 + Floor((ThisYear - 2017)/4, 1)) MOD 7;
var array = [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
ThisWeekday = array[WeekdayNo];
Ghi chú: Mảng arrray đánh chỉ số từ 0, sở dĩ có làm tròn xuống (ThisYear - 2017)/4 theo đơn vị 1 là vì cứ đủ 4 năm lại có một năm nhuận nên thứ sẽ nhảy thêm một bậc nhỉ ^^