สวัสดีทุกคนที่เข้ามาอ่านนะครับ สำหรับบทแรกนี้จะเป็น overall introduction เกี่ยวกับคอร์สนี้ รวมไปถึงคำถามที่พบบ่อยต่าง ๆ ก่อนที่จะเริ่มไปเข้าเนื้อหาจริง ๆ จัง ๆ ในบทที่ 2 แต่ก่อนที่จะไปเริ่มลงรายละเอียดกัน เราอยากจะเล่าเกี่ยวกับโปรเจคนี้คร่าว ๆ สักหน่อย
A Breif History, 2020
โปรเจค LearnAlgorithm เริ่มต้นเมื่อปี 2020 ซึ่งช่วงนั้นเป็นช่วงที่เรากำลังเรียน Data Structures & Algorithm ในมหาลัยเลย
ด้วยความที่ตอนนั้นก็กำลังอินในเรื่องนี้ และก็ทำเพจแชร์เรื่องเกี่ยวกับสิ่งที่เรียนอยู่ด้วยก็เลยได้เขียนเรื่องนี้เยอะเป็นพิเศษ ได้ฝึกทำโจทย์แล้วก็ลองไปลงแข่ง รวมถึงทำคลิปแชร์ลง YouTube ด้วย (ถึงจะไม่ได้ทำต่อแล้วก็เถอะ)
หลังจากเขียนแชร์และฝึกทำโจทย์อยู่หลายเดือน สุดท้ายก็เลยตัดสินใจออกแบบคอร์สเรียนเล็ก ๆ ขึ้นมาอันนึง ไว้แชร์เรื่องที่ตัวเองได้เรียนรู้สำหรับคนที่เป็น programmer ที่สนใจเรื่องนี้เหมือนกัน จนสุดท้ายเกิดเป็นโปรเจค LearnAlgorithm ขึ้นมา
Feedback ที่ได้จากการทำคอร์สเมื่อปี 2020
ส่วนตัวมองว่า programmer จริง ๆ แล้วไม่ใช่คนที่นั่งเขียนโค้ด แต่คือคนที่เป็น problem solver และ creator เป็นนักออกแบบและนักแก้ปัญหาคนหนึ่ง; สำหรับเราการเขียนโค้ดมันเป็นแค่ปลายทางสุดท้ายหลังจากที่เราคิดวิธีแก้ปัญหาได้แล้ว หรือออกแบบ algorithm เพื่อ solve problem ได้แล้ว
(นั่นเป็นเหตุผลว่าทำไมหลาย ๆ ครั้ง programmer อย่างเรา ๆ อาจจะใช้เวลากับ whiteboard หรือกระดาษมากกว่า code editor ด้วยซ้ำ)
ด้วยเหตุผลนี้เองมันทำให้ mission ของคอร์สนี้ไม่ได้ซับซ้อนอะไรขนาดนั้น เราอยากจะออกแบบเนื้อหาที่ช่วยให้คนอื่น (รวมถึงตัวเราเองด้วย) เป็น creator, problem-solver ที่เก่งขึ้น และเราคิดว่า data structures and algorithms มันเป็น fundamentals และ tools ที่ช่วยให้เราได้พัฒนา skills ตรงนั้น
น่าเสียดายมากที่ด้วยเหตุผลหลาย ๆ อย่าง ณ เวลานั้นมันทำให้เราต้องพับโปรเจคนี้เก็บเอาไว้ และหลังจากนั้นก็ไม่มีโอกาสได้กลับมาพัฒนาต่ออีกเลย
กลับมาทำใหม่, 2024
พอเวลาผ่านมาหลายปีเราก็ได้มีโอกาสได้ไปทำงานที่ต่าง ๆ ได้ลองทำโปรเจคหลาย ๆ แบบ รวมไปถึงได้มีโอกาสออกจากงานมาเป็น Indie hacker ที่ focus กับโปรเจคของตัวเองแบบเต็มตัว ได้ลองแก้ปัญหาที่หลากหลายขึ้น ทั้งในด้านที่ไม่ใช่ tech ด้วยเช่น marketing, business หรืออะไรต่าง ๆ เรารู้สึกว่าเราได้เรียนรู้อะไรมากขึ้น และมีเรื่องที่อยากจะแชร์เยอะขึ้นมากเมื่อเทียบกับ 4 ปีก่อน
เมื่อปลายปีที่ผ่านมา (August 2023) เราได้มีโอกาสขายหนึ่งในโปรเจคที่เคยทำ มันทำให้เราได้มีเวลาได้กลับมาคิดมากขึ้นว่าอยากจะทำอะไรต่อไป ซึ่ง LearnAlgorithm ก็เป็นหนึ่งในโปรเจคที่สนุกที่ได้ทำ (รวมถึงเสียดายด้วยที่ไม่ได้ทำต่อในตอนนั้น) เราเลยคิดว่ามันเป็นโอกาสที่ดีที่จะกลับมาทำโปรเจคนี้อีกครั้ง กลับมา redesign เนื้อหาใหม่ทั้งหมดให้มีความ up to date มากขึ้น
แน่นอนว่า mission ของคอร์สนี้ก็ยังเหมือนเดิม แต่ว่าก็มีบางอย่างที่ในครั้งนี้เราก็อยากจะลองทำแตกต่างจากเดิมออกไปดูบ้าง ด้านล่างนี้ก็เลยอยากจะเขียน core ideas สำคัญ ๆ ที่เราใช้ในการ design คอร์สนี้เอาไว้หน่อย เชื่อว่ามันน่าจะตอบคำถามที่หลาย ๆ คนสงสัยได้
คอร์สนี้เหมาะสำหรับใคร ?
คนที่เขียนโปรแกรมได้อย่างน้อย 1 ภาษา ที่อยากจะพัฒนา problem-solving skills และ explore ideas ในการแก้ปัญหาแบบต่าง ๆ ผ่านเนื้อหา data structures และ algorithms
(เนื้อหาทั้งหมดในคอร์สนี้จะใช้ภาษา Javascript เป็นตัวอย่างทั้งหมด)
Be More Personal
เรารู้สึกว่ามีคอร์สสอน data structures & algorithms ดี ๆ เยอะมากที่ทุกคนสามารถไปลงเรียนได้ทั้งที่เสียเงินและฟรี ยกตัวอย่างเช่น Havard CS50, MIT OpenCourseWare, FreeCodeCamp.org หรือแม้กระทั่งหนังสือดี ๆ อย่าง Grokking Algorithms (ซึ่งไว้ถ้ามีเวลาจะรวบรวม resources พวกนี้แล้วก็เขียนรีวิวของแต่ละอันอีกที) ซึ่งแน่นอนว่าเราเองก็เรียนรู้หลายอย่างมากจาก resources เหล่านี้
ดังนั้นในคอร์สนี้เราเลยอยากจะออกแบบให้มันมีความเป็น personal มากขึ้น เราอยากจะนำเสนอเนื้อหาในมุมมองในแบบของเรา ใส่ประสบการณ์หรือความเห็นส่วนตัวลงไปให้มากขึ้น ซึ่งเราเชื่อว่าคนเรียนก็คงจะได้เห็นมุมมองที่หลากหลายมากขึ้นเมื่อได้อ่านควบคู่ไปกับ resources อื่น ๆ
ถ้าให้ลอง breakdown ออกมาก็อาจจะเช่น: การใส่ opinion ต่าง ๆ ลงในในเนื้อหา, การแก้ปัญหาในด้านอื่น ๆ เช่น product design หรือ business, ประสบการณ์ในการทำงานต่าง ๆ ที่เคยเจอเกี่ยวกับ software engineering, fundamental-focused, history and etymology, creators mindset, learn and build in public และอื่น ๆ
เราคิดว่ามันคือ collection of beliefs, interests, and experiences พวกนี้หละที่มันประกอบร่างขึ้นมาเป็นคน ๆ หนึ่ง และเราอยากจะนำเสนอเนื้อหาคอร์สนี้ผ่าน collection ของตัวเราเอง
รูปแบบของเนื้อหา
สำหรับ format หลัก ๆ ของเนื้อหามีอยู่ 3 อย่างคือ:
Text-and-visual-based storytelling: เนื้อหาในคอร์สนี้จะนำเสนอผ่านรูปและตัวหนังสือทั้งหมด (ไม่มีในแง่ของ video อธิบายหรือเสียงอะไรแบบนั้น) เราอยากให้คนอ่านได้ feel เหมือนกับการอ่านหนังสือ ที่เหมือนกับการที่เราได้นั่งคุยกับตัวเอง ได้ใช้เวลา reflect และ explore ไอเดียใหม่ ๆ
Interactivity: เราพยายามออกแบบเนื้อหาให้หลาย ๆ ส่วนสามารถกดเล่นได้ ไม่ว่าจะเป็น Quiz, Problem Challenge, หรือการ visualize algorithm ต่าง ๆ เพื่อให้ผู้อ่านสามารถเข้าใจ concepts ต่าง ๆ ได้ง่ายและดียิ่งขึ้น
Get your hands dirty: ในตอนท้ายของแต่ละบทจะมี Additional Questions กับ Challenge Problem เพื่อให้ผู้อ่านได้ลองลงมือทำและได้ลอง explore ideas อื่น ๆ ที่กว้างและลึกมากขึ้น
ตัวอย่าง Challenge Problem ท้ายบท; ถ้าหากว่า submit code ไม่ผ่านเกิน 3 ครั้งจะมีปุ่ม “See the solution” ขึ้นมาให้กดดูเฉลย
Free and Open
อีกอย่างที่เราตั้งใจที่จะทำในรอบนี้ก็คือ เราอยากจะเปิดเนื้อหาให้ทุกคนสามารถเข้าถึงได้ฟรี รวมไปถึงให้ทุกคนสามารถที่จะ contribute ในส่วนของเนื้อหาได้ด้วย
เรารู้สึกว่า data structures & algorithms เป็นเรื่องพื้นฐาน และมันจะเป็นอะไรที่ดีมากถ้าทุกคนสามารถเข้าถึงเนื้อหาตรงนี้ได้ เราเลยอยากให้เนื้อหาในคอร์สนี้เป็นเหมือนกับแหล่งรวมไอเดียที่ใครก็ได้สามารถเข้ามา explore
แน่นอนว่าเราตั้งใจจะอัพเดตเนื้อหาเรื่อย ๆ อยู่แล้วตามประสบการณ์ที่โตขึ้นของเราเอง แต่ไอเดียหรือความคิดเห็นจากหลาย ๆ คนก็สำคัญเช่นกันที่จะทำให้เนื้อหามันครบถ้วนมากขึ้น
ดังนั้นถ้าหากว่าใครมี ideas อะไรอยากที่จะ suggest หรือมี feedback อะไรก็ตามสามารถเข้าไปเปิด Github issues ได้เลยครับ มาช่วยพัฒนาเนื้อหานี้สำหรับทุกคนไปด้วยกัน
วิธีการสร้าง issue ใหม่ใน Github
จริง ๆ เรามีไอเดียที่น่าสนุกหลายอย่างเลยที่อยากลองทำกับโปรเจค LearnAlgorithm นี้ ซึ่งคอร์สนี้ก็เป็นหนึ่งใน milestone ที่สำคัญ ดังนั้นรอติดตามใน Facebook Page ได้เลยครับ (หรือใครมีไอเดียอยาก collaborate อะไรก็ทักมาได้เช่นกันครับ 😎)
ปัญหาคืออะไร ?
ก่อนจะไปเริ่มต้นบทถัดไปเราอยากจะมาชวนทุกคนได้ลองนั่งคิดเล่น ๆ กับตัวเองว่า “ปัญหาคืออะไร ?” เพราะมันคงจะไม่ make sense ใช่ไหมครับถ้าหากว่าเรากำลังสนใจเรื่อง problem solving โดยที่ไม่เข้าใจคำว่า “problem”
ด้านล่างนี้เป็นบทความที่เกี่ยวข้องที่อยากชวนทุกคนไปลอง explore คำตอบของคำถามนี้กันครับ
สุดท้ายนี้ขอให้ทุกคนสนุกกับเนื้อหาและ enjoy problem solving ครับ~
Exercises
- ปัญหาคืออะไร ลองเขียนนิยามในแบบของตัวเอง ?
- เราจะ define ปัญหาใดปัญหาหนึ่งออกมาให้ชัดได้ยังไง ?
- เมื่อเรามีปัญหาที่ชัดแล้ว เราควรจะทำอะไรต่อเพื่อพาเราไปสู่ solution ที่เราต้องการ ?
- ถ้าหากเราคิด solution ออกมาได้แล้ว เราจะตัดสินใจจากอะไรว่า solution นี้คือ solution ที่เราควรจะเอาไป implement ต่อหรือเราควรมองหา solution ที่ดีมากขึ้นกว่านี้ ?
- Process ของการหานิยามของคำต่าง ๆ เป็นอย่างไร ? ลอง reflect สิ่งที่คิดออกมา
Challenge Problem
เขียน function ชื่อว่า add โดยที่รับตัวแปรมา 1 ตัวเป็นจำนวนเต็มบวก (\(n\); โดยที่ \(n > 0\)) และให้ return ผลลัพธ์ออกมาเป็นผลบวกตั้งแต่เลข 1 ถึงตัวเลขนั้น
Example 1:
Input: 3
Output: 6
Explaination: 1 + 2 + 3 = 6
Solution #1
เราสามารถแก้โจทย์ข้อนี้โดยการสร้างตัวแปร result ไว้ตัวนึง จากนั้น loop ค่าตั้งแต่ 1 ถึง n และบวกเก็บค่าลงตัวแปร result ไปเรื่อย ๆ (Naive Solution)
Solution #2
สำหรับวิธีการนี้เราจะเริ่มจากเขียนวิธีการแก้ปัญหาออกมาก่อนเพื่อดูว่ามันมี pattern อะไรที่เราสามารถนำมาสู่วิธีแก้ปัญหาที่ดีขึ้นได้ไหม เราอาจจะเริ่มจาก input น้อย ๆ ก่อนเช่น n = 10
ถ้าหากสังเกตดูจะพบว่า ตัวหน้าสุดกับตัวท้ายสุดบวกกันได้ 11 (1 + 10) ตัวที่ 2 จากด้านหน้า กับตัวรองท้ายก็บวกกันได้ 11 (2 + 9) และตัวที่เหลือถ้าเราจับคู่เข้าด้วยกันมันก็จะบวกได้ 11 ด้วย เช่น (3 + 8), (4 + 7), (5 + 6)
หรือถ้าในกรณีที่ n เป็นเลขคี่เช่น n = 5; เราก็จะได้ (1 + 5 = 6), (2 + 4 = 6), และ 3 ซึ่งเป็นค่าที่เหลืออยู่ตรงกลางที่ไม่จับคู่กับใคร
จาก pattern ตรงนี้เราจะพบว่าในกรณีของเลขคู่ เราจะสามารถจับคู่ n + 1 ได้ n / 2 คู่ ซึ่งเราสามารถคำนวนได้โดย
ส่วนกรณีที่เป็นเลขคี่ เราสามารถจับคู่ n + 1 ได้ (n - 1) / 2 คู่ และบวกกับค่าตรงกลางที่ไม่จับกับตัวไหนเลยก็คือ (n + 1) / 2 ซึ่งสามารถสรุปสมการออกมาได้เป็น
เราสามารถเขียนเป็นสมการได้เป็น