Bài viết này phác thảo cách giải quyết các vấn đề lập trình bằng cách sử dụng quy trình Launch PEDAC của Launch School. Có nhiều cách để giải quyết vấn đề code, và PEDAC chỉ là một. Mục đích của bài viết này không phải là để tuyên bố PEDAC là cách tiếp cận tốt nhất hoặc duy nhất mà là nhằm cung cấp nó như một trong những công cụ bạn có thể chuyển sang khi bạn bắt đầu làm việc với một vấn đề. Bạn có thể không cần PEDAC trong mọi vấn đề, nhưng bạn sẽ tìm thấy rất nhiều lợi thế để sử dụng một số hệ thống khi làm việc với các vấn đề phức tạp hơn. Vấn đề code càng phức tạp, bạn càng cần một quy trình nghiêm ngặt như PEDAC. Cách tiếp cận này đặc biệt hữu ích cho người mới bắt đầu học viết code bởi vì nhiều người mới bắt đầu chưa bao giờ bị buộc phải sử dụng một hệ thống tư duy trước đây.

PEDAC là gì?

PEDAC là viết tắt của Problem, Examples / Test cases, Data Structure, Algorithm, và Code:

  • Problem là vấn đề cần giải quyết
  • Examples là các ví dụ
  • Test Cases là các trường hợp kiểm thử
  • Data Structure là cấu trúc dữ liệu
  • Algorithm là giải thuật
  • Và cuối cùng là code

PEDAC có 2 mục tiêu chính đó là process the problem (PEDA) – xử lý vấn đề và code with intent (C) – code với mục tiêu. Xem bảng dưới đây để biết thêm chi tiết:

Mục tiêu

Bước

Mô tả

Xử lý vấn đề

Hiểu vấn đề

  • Xác định input và output mong muốn
  • Làm rõ các yêu cầu
  • Xác định các quy tắc
  • Mô hình tư duy (tùy chọn)

 

Các ví dụ/trường hợp kiểm thử

Xác thực sự hiểu biết về vấn đề

 

Cấu trúc dữ liệu

Cách chúng ta biểu thị dữ liệu mà chúng ta sẽ làm việc khi chuyển đổi input thành output

 

Giải thuật

Các bước để chuyển đổi input thành output

Code với mục tiêu

Code

 Thực hiện triển khai giải thuật bằng code.

 

Xử lý vấn đề bao gồm 4 bước dẫn bạn từ xác định vấn đề ban đầu đến sự hiểu biết vững chắc về những gì được yêu cầu. Kết quả là thuật toán (Algorithm) mà bạn sẽ sử dụng để thực thi giải pháp.

Khi bạn đã hiểu vấn đề, chọn cấu trúc dữ liệu phù hợp và có thuật toán để tiếp cận vấn đề, tất cả những gì bạn cần làm là chuyển đổi thuật toán thành ngôn ngữ lập trình mà bạn chọn. Chúng ta gọi đó là code with intent – code với mục tiêu, và kết quả cuối cùng là hoàn thành việc giải quyết vấn đề bằng code.

Tại sao sử dụng PEDAC?

Đối với các vấn đề về độ tinh vi nhất định, PEDAC tiết kiệm thời gian. Có vẻ như khó tin rằng một quy trình tốn nhiều công sức như PEDAC có thể tiết kiệm thời gian, nhưng đó chính xác là những gì nó làm khi vấn đề phức tạp. Điều đó không có nghĩa là code ngay thì luôn chậm hơn; trong thực tế, đối khi việc code ngay lại nhanh hơn với các vấn đề đơn giản. Tuy nhiên, vấn đề càng phức tạp, càng có nhiều khả năng code ngay lập tức sẽ dẫn đến cái mà chúng ta gọi là “hack and slash”, một thuật ngữ không hay được sử dụng để mô tả code được viết mà không có ý định hoặc ngữ cảnh. “Hack and slash” thường không đáp ứng được các yêu cầu, không xử lý được toàn vẹn vấn đề và tạo ra các chương trình khó hiểu, khó duy trì và mở rộng quy mô. Một cách tiếp cận có quy củ và kỉ luật, chẳng hạn như PEDAC, giúp bạn xác định và tránh những cạm bẫy mà bạn có thể gặp phải trong quá trình code. Một vài sai lầm phổ biến khi code mà không có mục tiêu xác định:

  • Bỏ sót các yêu cầu.
  • Không lường trước được các trường hợp sẽ xẩy ra
  • Code khó hiểu
  • Code khó bảo trì, nâng cấp

Ví dụ mẫu.

Hiểu cách làm việc của PEDAC thông qua một ví dụ.

Giả sử bạn có một số tự nhiên tùy ý (mục tiêu) và một bộ gồm một hoặc nhiều số tự nhiên bổ sung (các yếu tố). Viết chương trình tính tổng của tất cả các số từ 1 đến số mục tiêu cũng là bội số của một trong các yếu tố.

Chẳng hạn, nếu mục tiêu là 20 và các yếu tố là 3 và 5, điều đó cho chúng ta danh sách các bội số 3, 5, 6, 9, 10, 12, 15, 18. Tổng của các bội số này là 78.

Nếu không có yếu tố nào được đưa ra, hãy sử dụng 3 và 5 làm yếu tố mặc định

Hiểu vấn đề.

Thật hấp dẫn khi nhảy vào REPL và gõ code thật nhanh. Phải chống lại sự cám dỗ này. Bước quan trọng đầu tiên của PEDAC là "tiêu hóa" vấn đề để có được sự hiểu biết đầy đủ và toàn diện về những gì vấn đề cần xử lý. Đừng có vội vàng! Đọc kỹ phần mô tả vấn đề; đừng bỏ lỡ bất kỳ chi tiết nào. Trong hầu hết các phần mô tả, không có từ nào thừa cả, vì vậy đừng đọc nó như đọc một bài báo hay tạp chí nào đó. Mỗi từ và mọi chi tiết đều quan trọng. Bộ não của bạn có xu hướng lấp đầy các khoảng trống nếu bạn bỏ qua bất kỳ chi tiết nào, nhưng nó có thể không thực hiện chính xác, như được minh họa bằng cách sau:

Trước tiên, hãy xác định input và output cho vấn đề của chúng ta. Đọc phần mô tả yêu cầu, chúng ta có thể thấy rằng chúng ta có 2 input và 1 output:

input:

  số mục tiêu

  tập hợp các yếu tố

output:

  tổng bội

Trừ khi bạn quen thuộc với miền vấn đề (problem domain), còn có một khái niệm ngầm ẩn tinh tế được giới thiệu: bội số.

Để làm cho các yêu cầu/điều kiện trở nên rõ ràng, chúng ta phải hiểu các điều kiện khi chúng áp dụng cho miền vấn đề. Những từ này không giới hạn trong những từ bạn không quen thuộc, nhưng cũng có những từ có nhiều nghĩa. Chẳng hạn, từ "balance" có thể có nghĩa là những thứ khác nhau tùy thuộc vào việc chúng ta sử dụng nó trong bối cảnh kế toán hay chuỗi cung ứng.

Quay trở lại với thuật ngữ bội số (multiple), người cho rằng đây là một thuật ngữ toán học của người Bỉ có nghĩa là một số có thể được chia cho một số khác mà không có phần còn lại. (Thông thường, bạn sẽ không muốn thừa nhận điều gì đó nếu bạn không quen thuộc với miền vấn đề nhưng sẽ tìm hiểu trước. Ở đây, chúng tôi là người đưa ra vấn đề, vì vậy chúng tôi sẽ xác nhận rằng định nghĩa giả định này là chính xác.) ví dụ trong đoạn thứ hai, chúng ta có thể xác nhận điều này:

số mục tiêu:

20

bội số của 3 (multiple of 3):

3, 6, 9, 12, 15, 18 (tất cả không có phần dư khi chia cho 3)

bội số của 5 (multiple of 5):

5, 10, 15 (tất cả không có phần dư khi chia cho 5)

Những quy tắc ẩn

Mô tả vấn đề này cũng truyền tải một vài quy tắc mà chúng ta phải ghi nhớ:

  • Các bội số được tính tổng phải là duy nhất. Số 15 là bội số của cả 3 và 5, nhưng chúng ta chỉ thêm một lần khi tính tổng (3 + 5 + 6 + 9 + 10 + 12 + 15 + 18 = 78). Lưu ý rằng chúng ta học điều này ngầm từ ví dụ: yêu cầu duy nhất không được nêu rõ ràng.
  • Giá trị mục tiêu là giới hạn, nhưng nó không được coi là bội số. Trong ví dụ, mục tiêu, 20, không được bao gồm trong tổng số mặc dù nó LÀ bội số của 5. Tương tự với quy tắc đầu tiên, quy tắc này là ẩn.
  • Tất cả các số là số tự nhiên: chúng là tập hợp các số nguyên lớn hơn hoặc bằng 0 hoặc 1 (xem định nghĩa này từ mathworld.wolfram.com). Vì việc thêm 0 vào bất kỳ số nào không làm thay đổi nó, nên chúng ta không sử dụng định nghĩa nào. Để đơn giản, chúng ta sẽ giả sử rằng các số tự nhiên bắt đầu bằng 1.

Bây giờ chúng ta đã xử lý vấn đề và có thể xác định liệu có bất cứ điều gì cần làm rõ hay không.

 

Làm rõ các câu hỏi

  1. Các giá trị có thể cho số mục tiêu là gì? Số âm có được phép không? Bất kỳ số tự nhiên nào lớn hơn 0. Sẽ luôn có một giá trị mục tiêu
  2. Làm thế nào các yếu tố sẽ được cung cấp cho chương trình? Ví dụ như sử dụng một mảng.
  3. Điều gì xảy ra nếu chỉ 3 hoặc 5 được cung cấp như một yếu tố? Chương trình vẫn nên mặc định cho cả hai yếu tố 3 và 5? Không. Mặc định là 3 và 5 chỉ khi không có yếu tố nào được cung cấp.

Bây giờ, chúng ta đã hiểu biết thấu đáo vấn đề cần giải quyết. Tuy nhiên, để cho đầy đủ, hãy thực hiện một bước xử lý tùy chọn cuối cùng là đưa ra một mô hình mang tính ý niệm (mental model) mô tả vấn đề cần giải quyết.

Chúng ta có thể hình dung mô hình mang tính ý niệm như là một cái nhìn tóm tắt của chúng ta về toàn bộ vấn đề. Nói cách khác, nó là quan điểm của chúng ta về những gì vấn đề yêu cầu giải quyết. Hãy chắc chắn rằng ở đây chúng ta chưa cần quan tâm đến cách giải quyết vấn đề (thuật toán hay giải thuật).

Đây là một mô hình mang tính ý niệm đơn giản cho vấn đề đặt ra ở trên:

Xác định danh sách tất cả các bội số của một tập hợp các yếu tố cho đến một giá trị đích, sau đó lọc danh sách các bội số thành các giá trị duy nhất. Cuối cùng, tính toán và trả về tổng của bội số duy nhất.

Một mô hình khác:

Xây dựng một danh sách các số là bội số của một tập hợp một hoặc nhiều yếu tố. Thêm bội số vào danh sách chỉ khi nó chưa có trong danh sách. Cuối cùng, tính toán và trả về tổng của các số trong danh sách.

Lưu ý rằng chúng tôi đã đưa ra hai mô hình mang tính ý niệm trong ví dụ này. Chúng tôi đã làm điều này để làm nổi bật rằng có nhiều quan điểm để tạo ra một mô hình hợp lý; như một quy tắc chung, bạn không cần phải đưa ra nhiều mô hình miễn là nó nắm bắt được đầy đủ và chính xác các yêu cầu.

 

Ví dụ / Các trường hợp kiểm thử.

Từ đầu đến giờ, chúng ta đã làm được rất nhiều việc, nhưng đó chỉ là bước đầu tiên - PED trong PEDAC. Bây giờ chúng ta đã sẵn sàng để chuyển sang bước E, viết tắt của các ví dụ hoặc các trường hợp thử nghiệm. Trong bước này, mục tiêu của chúng ta là đưa ra các ví dụ xác nhận sự hiểu biết của chúng ta về vấn đề và xác nhận rằng chúng ta đang làm việc đúng hướng. Xác nhận thường sẽ đến từ một người hoặc tài liệu của một quy trình: chúng ta có thể yêu cầu người đó xác nhận output được cung cấp với input tương ứng hoặc chúng ta có thể theo dõi quy trình để kiểm tra output được tạo ra bởi input.

[Lời người dịch] Hãy tưởng tượng có người yêu cầu bạn làm máy tạo ra xúc xích. Bước xác nhận này chính là việc chúng ta hỏi người đó về việc đầu ra của máy là gì (trường hợp này là xúc xích) hoặc bạn đi xem xét một cái máy làm xúc xích đang hoạt động (theo giõi quy trình) để biết rằng với những nguyên liệu đầu vào (input) thì cái máy cho sản phẩm đầu ra (output) là xúc xích.

Quay trở lại với vấn đề được đưa ra trong ví dụ. Chúng ta sẽ thử đưa ra một vài trường hợp kiểm thử, xác định output dự kiến với một số input nhất định.

Trường hợp 1:

  • Input
    • Số mục tiêu: 20
    • Các số yếu tố: [3, 5]
  • Output: 78

Trường hợp 2:

  • Input
    • Số mục tiêu: 20
    • Các số yếu tố: [3]
  • Output: 63

Trường hợp 3:

  • Input:
    • Số mục tiêu: 20
    • Các số yếu tố: [5]
  • Output: 30

Trường hợp 4:

  • Input:
    • Số mục tiêu: 20
    • Các số yếu tố: []
  • Output: 78

Trường hợp 5:

  • Input:
    • Số mục tiêu: 1
    • Các số yếu tố: []
  • Output: 0

Lưu ý chúng ta đã lấy ví dụ từ các quy tắc ẩn ở trên. Đó là nơi tuyệt vời để tìm kiếm các trường hợp kiểm thử.

Ngoài các trường hợp kiểm thử dựa trên các quy tắc của chúng ta, cũng nên cung cấp các trường hợp kiểm thử xử lý bất kỳ trường hợp biên nào có thể tìm thấy. Các trường hợp biên là các đầu vào tại các biên của phần mô tả vấn đề có thể bị xử lý sai nếu chúng ta không cẩn thận. Chẳng hạn, các vấn đề liên quan đến việc lặp qua các số có trường hợp biên ở một hoặc cả hai đầu của phạm vi. Nếu không cẩn thận, bạn có thể nhận được câu trả lời không chính xác ở các biên này. Các trường hợp biên điển hình có thể liên quan đến việc làm việc với các số âm, số 0 hoặc giá trị cực cao (nếu hiệu suất là một yêu cầu). Khi làm việc với các tập hợp, một ý tưởng tốt là tìm các trường hợp thử nghiệm xử lý bằng 0, một hoặc nhiều phần tử trong tập hợp.

Với ví dụ này, có một trường hợp biên đáng kể: điều gì xảy ra ở số cuối cùng trước khi số mục tiêu là bội của một hoặc nhiều số yêu tố

Trong mỗi trường hợp thử nghiệm của chúng ta ở trên, số cuối cùng được thêm vào tổng là 18 hoặc 15. Điều đó khiến 19 (giá trị cuối cùng được kiểm tra) không nằm trong tổng, đó là điều đúng đắn. Tuy nhiên, giả sử rằng 19 sẽ được bao gồm trong tổng, mà nếu 19 là một trong các yếu tố. Vì 19 là con số cuối cùng có thể kiểm tra (đưa ra mục tiêu là 20), nên nó ở biên của phạm vi giá trị được tính tổng. Để chắc chắn, chúng ta bao gồm 19 trong tổng số, chúng ta cần cung cấp một trường hợp thử nghiệm xử lý nó.

Trường hợp 6:

  • Input:
    • Số mục tiêu: 20
    • Các số yếu tố: [19]
  • Output: 19

 

Cấu trúc dữ liệu

Bây giờ chúng ta đã sẵn sàng để chuyển sang bước thứ ba trong phương pháp PEDAC, đó là D. Với các trường hợp thử nghiệm của chúng ta đã đưa ra, điều tiếp theo cần làm là xác định cấu trúc dữ liệu nào sẽ được sử dụng để chuyển đổi input thành output. Các cân nhắc chính ở đây là ngôn ngữ lập trình dự định và mô hình mang tính ý niệm của chúng ta.

Sử dụng một trong các mô hình ý niệm, chúng ta thấy rằng cần thu thập các giá trị là bội số của các số yếu tố. Một mảng có vẻ như phù hợp với bộ sưu tập bội số này. Sự khác biệt duy nhất giữa các mô hình của chúng ta nằm ở cách thức và thời điểm chúng ta lọc các số đó, nhưng chúng ta sẽ lo lắng về điều đó sau.

Một điều cần lưu ý là Cấu trúc dữ liệu sẽ ảnh hưởng đến thuật toán của bạn. Vì vậy, chúng ta thường thấy "Data structure" - Cấu trúc dữ liệu đi kèm với "Algorithm" - Giải thuật

 

Giải thuật

Trong bước này, nếu bạn đã có một mô hình ý niệm trong đầu, bạn có thể bắt đầu từ đó. Mặt khác, nếu chưa có, hãy bắt đầu với bước "Cấu trúc dữ liệu" và nghĩ về cách bạn xây dựng và thao tác để có được output tương ứng. Chẳng hạn, nếu đó là một mảng, có lẽ bạn sẽ tập trung vào việc xây dựng hoặc lặp lại qua một tập hợp.

Mục tiêu chính của chúng ta ở đây là xác định một loạt các hướng dẫn sẽ chuyển đổi input thành output mong muốn. Thách thức là để có được mức độ chi tiết phù hợp; chúng ta cần một cái gì đó có thể dễ dàng chuyển đổi thành code mà không cần thực sự phải viết code ngay. (Tức là ở đây chúng ta cần gì đó để mô tả nên thuật toán một cách rõ ràng, từ đó có thể chuyển đổi thành code của bất kì ngôn ngữ lập trình nào phù hợp - Lời người dịch)

Lý do bạn không muốn (và cũng không nên) mô tả giải thuật bằng cách sử dụng một ngôn ngữ lập trình nào đó là vì điều đó sẽ làm mất đi tính linh hoạt trong quá trình thực hiện. Ngôn ngữ lập trình thường cung cấp một số cách để đạt được một kết quả nhất định, nhưng mỗi cách tiếp cận đó có thể ảnh hưởng đến các phần khác của chương trình. Nếu bạn đưa ra lựa chọn triển khai quá sớm bằng cách dùng một ngôn ngữ lập trình cụ thể (ví dụ Java) để mô tả giải thuật, rồi sau đó bạn phát hiện ra nên chọn một thứ khác, bạn có thể cần quay lại và sửa đổi cả code và giải thuật. Nếu bạn không giải quyết các thay đổi ở cả hai cấp độ, bạn có thể gặp phải những cạm bẫy mà chúng ta đã thảo luận trước đó.

Điều đó cho thấy, không có gì lạ nếu thay đổi thuật toán khi bắt đầu code cả; đừng cảm thấy bị bó buộc với những gì bạn đã viết ban đầu. Trên thực tế, hai hay nhiều cá nhân làm việc với cùng một vấn đề thường sẽ đưa ra các giải thuật khác nhau, đặc biệt nếu mỗi cá nhân đã xây dựng các mô hình ý niệm khác nhau. Để chứng minh điều này, đây là các thuật toán sử dụng cả hai mô hình ý niệm từ ví dụ của chúng ta:

Mô hình ý niệm thứ nhất:

Xác định danh sách tất cả các bội số của một tập hợp các yếu tố cho đến một giá trị đích, sau đó lọc danh sách các bội số thành các giá trị duy nhất. Cuối cùng, tính toán và trả về tổng của bội số duy nhất.

  1. Khởi tạo một mảng rỗng, đặt tên là multiples để lưu các số yếu tố.
  2. Kiểm tra xem danh sách các số yếu tố có rỗng không, nếu rỗng, hãy đặt danh sách thành [3, 5]
  3. Với mỗi số yếu tố trong danh sách số yếu tố:
    1. Đặt current_multiple thành hệ số để theo dõi bội số của số yếu tố.
    2. Khi current_multiple còn nhỏ hơn số yếu tố thì:
      1. Kiểm tra xem current_multiple đã nằm trong mảng multiple hay chưa?
        1. Nếu có thì không làm gì cả
        2. Nếu chưa thì thêm current_multiple vào mảng multiples
  4. Tính và trả về tổng của các số trong mảng multiples

 

Trước khi thực hiện giải thuật của bạn, bạn nên kiểm tra thủ công với các trường hợp thử nghiệm của mình. Bạn không cần phải kiểm tra tất cả các trường hợp thử nghiệm, chỉ đủ để tự tin rằng thuật toán hoạt động.

Trường hợp 1:

  • Input
    • Số mục tiêu: 20
    • Các số yếu tố: [3, 5]
  • Output: 78

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

Giải thuật

  1. Tạo một mảng trống được gọi là multiple sẽ chứa danh sách bội số   multiple = []
  2. Kiểm tra xem danh sách các số yếu tố có trống không. Nếu không có sô yếu tố nào, hãy đặt danh sách thành [3, 5]                                 [3, 5] thu được từ các số yếu tố được cung cấp. 
  3. Với mỗi số yếu tố trong danh sách: [3, 5]
    1. Đặt current_multiple thành hệ số để theo giõi bội số của các số yếu tố
      1. current_multiple = 3
        current_multiple = 5
    2. Khi current_multiple < hệ số
      1. Thêm current_multiple vào mảng multiples
        1. multiples = [3]
          multiples = [3, 6]
          multiples = [3, 6, 9]
          ...
          multiples = [3, 6, 9, 12, 15, 18, 5, 10, 15]
      2. Gán hệ số vào = current_multiple
        1. current_multiple = 6
          current_multiple = 9
           ...
          current_multiple = 18
          current_multiple = 21
          current_multiple = 5
          current_multiple = 10
          current_multiple = 15
          current_multiple = 20
  4. Lọc các số trùng lặp trong mảng multiples
    1. multiples = [3, 6, 9, 12, 15, 18, 5, 10]
  5. Tính và trả về tổng của các giá trị trong mảng multiples

       78

 

Sau khi xác minh rằng một vài trường hợp thử nghiệm của chúng ta cung cấp output đúng như dự kiến, đã đến lúc triển khai giải thuật bằng code.

Code nào!!!

Đây là bước cuối cùng trong PEDAC - C, viết tắt của "code with intent". Giai đoạn này là tất cả về việc thực hiện các giải pháp trong ngôn ngữ của bạn lựa chọn. Lợi ích chính của việc đầu tư thời gian vào các bước trước (PEDA) là nó đơn giản hóa việc chuyển đổi thuật toán sang cú pháp của một ngôn ngữ lập trình.

Đừng sợ nếu sau khi thực hiện tất cả các bước trên, bạn vẫn phải quay lại với giải thuật của mình. Điều này có thể và sẽ xảy ra thường xuyên. Dù sao thì, bạn là con người, và bạn có thể đã bỏ lỡ điều gì đó. Tuy nhiên, PEDAC nhằm mục đích giảm thiểu những sai lầm đó, vì vậy bạn không bỏ lỡ các yêu cầu chính và ngay cả khi bạn quay trở lại các bước trước đó, nó chủ yếu là để điều chỉnh cách tiếp cận.

Ở đây, tôi triển khai giải thuật trên bằng Ruby theo mô hình mang tính ý niệm đầu tiên:

def sum_of_multiples(target, factors)
  multiples = []
  factors = [3, 5] if factors.length == 0

  factors.each do |factor|
    current_multiple = factor

    while current_multiple < target
      multiples << current_multiple
      current_multiple += factor
    end
  end

  multiples.uniq.inject(0, :+)
end

sum_of_multiples(20, [3, 5])  # returns 78
sum_of_multiples(20, [3])     # returns 63
sum_of_multiples(20, [5])     # returns 30
sum_of_multiples(20, [])      # returns 78
sum_of_multiples(1, [])       # returns 0
sum_of_multiples(20, [19])    # returns 19

Tiếp đó, đây là code JavaScript sử dụng giải thuật thiết kế cho mô hình ý niệm thứ 2 đã xây dựng ở trên:

function sumOfMultiples(targetNumber, factors) {
  var multiples = [];
  if (factors.length === 0) {
    factors = [3, 5];
  }

  factors.forEach(function(factor) {
    var currentMultiple;
    for (currentMultiple = factor; currentMultiple < targetNumber; currentMultiple += factor) {
      if (multiples.indexOf(currentMultiple) === -1) {
        multiples.push(currentMultiple);
      }
    }
  });

  return multiples.reduce(function(sum, value) {
    return sum + value;
  }, 0);
}

sumOfMultiples(20, [3, 5]);  // returns 78
sumOfMultiples(20, [3]);     // returns 63
sumOfMultiples(20, [5]);     // returns 30
sumOfMultiples(20, []);      // returns 78
sumOfMultiples(1, []);       // returns 0
sumOfMultiples(20, [19]);    // returns 19

Ruby hoặc JavaScript sẽ hoạt động cho cả hai mô hình ở trên. Tuy nhiên, mô hình đầu tiên phù hợp hơn với Ruby vì Ruby có phương thức trả về các giá trị duy nhất trong một mảng; JavaScript thì không.

Thêm một chút. Code của người dịch bài, sử dụng Java:

public static int sumOfMultiples(int target, int[] factors){
        Set<Integer> hashsetMultiples = new HashSet<>();

        for (int number: factors) {
            for (int i = 1; i < target ; i++) {
                if(i % number == 0){
                    hashsetMultiples.add(i);
                }
            }
        }

        int total = 0;
        for (int item: hashsetMultiples) {
            total += (int)item;
        }
        return total;
    }

Tổng kết

Chúng tôi hi vọng bài viết mô tả quy trình PEDAC này đã đưa ra cho các bạn thêm những gợi ý mới. Mặc dù có vẻ dài dòng để để bao phủ rộng rãi và mô tả các bước, nhưng mức độ chi tiết này luôn là cần thiết cho mọi vấn đề. Bạn cũng không cần phải sử dụng PEDAC. Ý tưởng chính nêu lên ở đây là để giúp bạn đưa ra được một giải thuật, sau đó code theo một cách có mục tiêu. Ban đầu, có vẻ bạn sẽ phải làm rất nhiều việc, nhưng một khi bạn đã quen với việc sử dụng nó, bạn sẽ ngạc nhiên khi thấy PEDAC nhanh và hiệu quả trong việc hỗ trợ khả năng giải quyết vấn đề của bạn đấy!

 

FAQ - Những câu hỏi thường gặp

  1. Những vấn đề nào tôi có thể giải quyết bằng PEDAC? PEDAC không thích hợp cho nhiều hoạt động trừu tượng như thiết kế giao diện người dùng. Nó hoạt động tốt với các vấn đề code có thủ tục vì nó dẫn bạn đến một loạt các bước / hướng dẫn mà bạn có thể làm theo để tạo ra kết quả xác định.
  2. Khi nào tôi nên sử dụng PEDAC? Tôi có nên sử dụng nó ngay cả khi vấn đề nhỏ? Nếu bạn không có kinh nghiệm trước khi sử dụng quy trình giải quyết vấn đề chính thức thì, vâng, hãy sử dụng nó cho các vấn đề tầm thường. Làm cho tâm trí của bạn được sử dụng để giải quyết vấn đề bằng cách làm theo PEDAC. Khi bạn đã quen với nó, nó sẽ trở thành một phần bộ não của bạn, và bạn sẽ có thể triển khai nó một cách tự nhiên hơn trong các vấn đề khó khăn hơn, đó là nơi bạn sẽ thực sự cần nó. Nếu lần tiếp xúc đầu tiên với PEDAC của bạn gặp phải những vấn đề khó khăn nhất, thì nó sẽ khó có thể sử dụng tốt quy trình này.
  3. Tôi có thể sử dụng PEDAC để phát triển ứng dụng và không chỉ giải quyết vấn đề mã hóa không? Có, nhưng bạn sẽ có một số công việc cần làm trước khi sử dụng nó. Để sử dụng PEDAC hiệu quả, hãy chia nhỏ ứng dụng thành các yêu cầu nhỏ hơn. Bạn có thể phải so sánh với các vấn đề code trước đây mà bạn đã giải quyết nếu nó có kích thước nhỏ phù hợp với PEDAC. PEDAC có thể được áp dụng cho bất kỳ vấn đề nào có input cụ thể và output rõ ràng, do đó, bạn sẽ phải chia nhỏ ứng dụng của mình cho đến khi bạn có các yêu cầu cụ thể và rõ ràng.

 

Dịch từ bài viết Solving Coding Problems With PEDAC