1 คะแนน โดย GN⁺ 2024-10-07 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • sudoku ของ Dyalog APL จะคืนค่า เมทริกซ์คำตอบทั้งหมดที่เป็นไปได้ จากเมทริกซ์ปริศนาที่ใช้ 0 แทนช่องว่าง และมีการนำโจทย์เดียวกันไปใช้งานหลายรูปแบบในสไตล์ APL/K
  • เป้าหมายหลักคือ Sudoku ขนาด 9×9 ซึ่งแต่ละ กล่อง 3×3, แถว และคอลัมน์ ต้องมีตัวเลข 1 ถึง 9 โดยไม่ซ้ำกัน
  • อินพุต prob ใส่ค่า 1-9 ในช่องที่เติมแล้ว และ 0 ในช่องว่าง และสามารถระบุ กล่องที่ไม่ใช่สี่เหลี่ยมจัตุรัส เช่น 2×3, 3×4 ได้ด้วยอาร์กิวเมนต์ซ้ายแบบเลือกได้ shape
  • อัลกอริทึมการแก้ของ Veli-Matti Jantunen จะแปลงเมทริกซ์เป็นเวกเตอร์ สร้างดัชนีแถว·คอลัมน์·กล่อง แล้วค่อย ๆ ลดตัวเลือก พร้อมขยายจาก กลุ่มที่มีข้อจำกัดมากที่สุด ก่อน
  • ตัวอย่าง s33 และ s22 มีคำตอบอย่างละ 3 แบบ ส่วน 3 4 sudoku s34 มีคำตอบ 2 แบบ และยังแนะนำวันไลเนอร์ K 5 ของ Arthur Whitney พร้อมการนำไปใช้งานใหม่ใน APL หลายแบบ

อินพุต Sudoku และผลลัพธ์ของฟังก์ชัน sudoku

  • ปริศนา Sudoku คือกริดที่จัดวางกล่อง 3×3 เป็นรูปแบบ 3×3 โดยแต่ละช่องอาจว่างหรือมีตัวเลขตั้งแต่ 1 ถึง 9
  • คำตอบต้องเป็นไปตามเงื่อนไขห้ามซ้ำทั้งสามข้อ
    • ในแต่ละ กล่อง 3×3 ต้องมีตัวเลข 1 ถึง 9 โดยไม่ซ้ำกัน
    • ในแต่ละ แถว 9 ช่อง ต้องมีตัวเลข 1 ถึง 9 โดยไม่ซ้ำกัน
    • ในแต่ละ คอลัมน์ 9 ช่อง ต้องมีตัวเลข 1 ถึง 9 โดยไม่ซ้ำกัน
  • เมทริกซ์ prob ใช้ตัวเลข 1-9 สำหรับช่องที่เติมแล้ว และใช้ 0 สำหรับช่องว่าง
  • อาร์กิวเมนต์ซ้ายแบบเลือกได้ shape ใช้ระบุ รูปทรงของกล่อง สำหรับปริศนาที่ไม่ใช่แบบสี่เหลี่ยมจัตุรัสมาตรฐาน
    • หากเป็นเมทริกซ์ 6×6 ที่พื้นที่ย่อยเป็น 2×3 ให้เรียกในรูป 2 3 sudoku mat
  • ผลลัพธ์เป็นเวกเตอร์ที่บรรจุเมทริกซ์คำตอบทั้งหมด
    • หากไม่มีคำตอบ จะคืนค่า
    • สถานการณ์ผิดพลาดอาจแสดงเป็น '' โดยเอกสารระบุว่า “ไม่ควรเกิดขึ้น แต่เกิดเมื่อผลลัพธ์มีจำนวนมากมหาศาล”

ลำดับการทำงานของวิธีแก้ของ Veli-Matti Jantunen

  • อัลกอริทึมจัดการเมทริกซ์ Sudoku เป็น เวกเตอร์ และแทนแถว·คอลัมน์·พื้นที่ Sudoku แต่ละแบบด้วย เวกเตอร์ดัชนี
  • หลังผ่านการตรวจสอบพื้นฐานแล้ว จะตรวจทางเลือกในรายการตัวเลือกทีละรายการ
  • ในแต่ละขั้นตอน จะกรองค่าที่เป็นไปได้ของทุกช่อง
    • หากมีช่องใดช่องหนึ่งที่ไม่มีค่าที่เป็นไปได้เลย จะตัดออกจากตัวเลือกคำตอบ
    • หากช่องหนึ่งมีตัวเลขผู้สมัครมากกว่าหนึ่งตัว จะเลือกช่องจากกลุ่มที่มีข้อจำกัดมากที่สุด แล้วเพิ่มชุดตัวเลือกของช่องนั้นลงในรายการ
    • หากทุกช่องเหลือตัวเลขเพียงตัวเดียว จะถือเป็นคำตอบ แล้วไปยังตัวเลือกถัดไป
  • ในส่วนเดียวกันยังมีฟังก์ชัน Shuffle สำหรับสลับตาราง Sudoku เดิมให้เป็นตารางอื่นด้วย

วันไลเนอร์ของ Arthur Whitney และการใช้งานทางเลือก

  • การใช้งาน sudoku ทางเลือกของ David Crossley รับการตั้งค่า N×N เป็นอินพุต และรองรับกรณีที่ขนาดกล่อง N*÷2 เป็นจำนวนเต็ม
    • อินพุตต้องเป็นการจัดวางที่ถูกต้อง โดยบางช่องมีตัวเลขตั้งแต่ 1 ถึง N และช่องที่เหลือเป็น 0
    • ในผลลัพธ์ แต่ละแถว คอลัมน์ และกล่อง ต้องมีตัวเลขตั้งแต่ 1 ถึง N ครบทุกตัว
    • ภายในการใช้งานมีฟังก์ชันช่วยอย่าง valid, search, rules, sole, singles, uniques, matches, NinN, setup
  • โซลูชัน K 5 ของ Arthur Whitney ถูกนำเสนอเป็น โค้ดหนึ่งบรรทัด
x(,/{@[x;y;]'(!10)^x*|/p[;y]=p,:,3/:-3!p:!9 9}')/&~* x
  • Phil Last ให้การใช้งาน sudoku ที่แปลงโค้ดของ Whitney ไปเป็น D-function
  • การเขียนใหม่ของ Morten Kromberg นิยามองค์ประกอบบางส่วนของ K อย่างชัดเจน ทำให้มีรูปแบบใกล้กับต้นฉบับมากขึ้น
    • เช่นเดียวกับเวอร์ชัน K อินพุตและเอาต์พุตไม่ใช่เมทริกซ์ แต่เป็น เวกเตอร์ 81 องค์ประกอบ
  • การใช้งาน Sudoku ของ Roger Hui เป็นรูปแบบที่ทั่วไปกว่า และรองรับปริศนาที่ไม่ใช่สี่เหลี่ยมจัตุรัสด้วย
    • svec สร้างเวกเตอร์คำตอบ ส่วน pvex และ pvec ขยายการจัดวางที่เป็นไปได้
    • avl สร้างรายการตัวเลขที่เป็นไปได้ และ emt ค้นหาดัชนีแถว·คอลัมน์ของช่องว่าง
    • rcb, box, cmap, CMAP สร้างความสัมพันธ์การชนกันของแถว·คอลัมน์·กล่อง

ตัวอย่างปริศนาและจำนวนคำตอบ

  • s33 เป็นโจทย์ตัวอย่าง 9×9 และผลลัพธ์ของ sudoku s33 มี คำตอบ 3 แบบ
  • ฟังก์ชัน sbox แบ่งกล่องภายในเพื่อแสดงกริด Sudoku ให้อ่านง่าย
    • 0 จะแสดงเป็นจุด (·)
    • เอาต์พุตเป็นเมทริกซ์อักขระที่วาดเส้นขอบกล่องไว้
  • s22 เป็นโจทย์ตัวอย่าง 4×4 และผลลัพธ์ของ sbox¨ sudoku s22 มี คำตอบ 3 แบบ
  • s34 เป็นโจทย์ตัวอย่างที่ใช้กล่อง 3×4
    • ใช้ 3 4 sbox s34 เพื่อแสดงโจทย์ในรูปแบบแยกกล่อง
    • ผลลัพธ์ของ 3 4 sudoku s34 มี คำตอบ 2 แบบ

ลิงก์อ้างอิงและรายการที่เกี่ยวข้อง

  • sudoku_bfs เชื่อมไปยังตัวอย่างที่แสดงอัลกอริทึมนี้
  • “Learn” ของ TryAPL มีเดโมแบบทีละขั้นตอน: http://www.TryAPL.org
  • มีวิดีโอแสดงพฤติกรรมการทำงาน: http://www.youtube.com/watch?v=DmT80OseAGs
  • รายการที่เกี่ยวข้อง ได้แก่ queens, sudoku_bfs, X, sudokuX

1 ความคิดเห็น

 
GN⁺ 2024-10-07
ความคิดเห็นจาก Hacker News
  • บรรทัดดังกล่าวเขียนด้วย K โดย K เป็นภาษาที่ Arthur Whitney สร้างขึ้นจากพื้นฐานของ APL และ Scheme
    x(,/{@[x;y;]'(!10)^x*|/p[;y]=p,:,3/:-3!p:!9 9}')/&~*x

  • บางครั้งก็ประเมินความซับซ้อนของโค้ดโดยเทียบจำนวนบรรทัดของโค้ดกับผลลัพธ์ด้านล่าง
    tar -cf - . | gzip | base64 | wc -l
    กล่าวคือดูว่า “บีบอัดได้ดีแค่ไหน?” พอเห็น APL ก็ทำให้นึกถึงตอนที่เผลอส่งเอาต์พุตของ gzip ไปยังเทอร์มินัล
    p←{(↑⍵)∘{(⍺∨.=⍵)/⍳n×n∘}¨,⍵},(n*÷2){⍵,⍺⊥⌊⍵÷⍺}'⍳n n←⍴⍵
    น่าประทับใจที่ยังมีคนไล่อ่านโค้ดแบบนี้แล้วถึงขั้นถามว่า “หา bug เจอไหม?” มันให้ความรู้สึกเหมือน ข้อมูลไบนารีที่ถูกบีบอัด ซึ่งทุกคนมีพจนานุกรมเดียวกันอยู่แล้ว

    • สงสัยจริง ๆ ว่าโปรแกรมเมอร์ APL มองเรื่อง ความสามารถในการบำรุงรักษา และความอ่านง่ายอย่างไร คงมีการใส่คอมเมนต์โค้ดอย่างละเอียดมาก หรือทำเอกสารแยกไว้หรือเปล่า
    • ถ้าถามว่า “หา bug เจอไหม?” ก็เห็นได้ทันทีหลายอย่าง มี syntax error อย่างเครื่องหมายอัญประกาศเดี่ยวที่ไม่ปิด และ ที่ไม่มี operand ด้านขวา ส่วน n n←⍴⍵ ดูเหมือนสัญญาณว่าตั้งค่า n ซ้ำสองครั้งและคาดว่า เป็นสองมิติ แต่ขึ้นอยู่กับเจตนาแล้ว _ n←⍴⍵ หรือ n←⊃⌽⍴⍵ น่าจะเป็นธรรมชาติกว่า
      อีกอย่าง จะเกิด error ถ้า ⍴⍵ ไม่ใช่จำนวนเต็มเดี่ยวหรือเวกเตอร์ว่าง ดังนั้นสุดท้ายก็แทบไม่ต่างจาก n←⍴⍵ และยิ่งทำให้สับสนกว่าเดิม ส่วน , ที่ซ้ำกันหลายจุดกับ ↑⍵ ก็เอาออกได้ และทั้ง expression จริง ๆ แล้วแทบจะเท่ากับ p←(n+1)⍴⊂⍳n×n←⍴⍵ ซึ่งเป็นโครงสร้างที่คืนเวกเตอร์ 1..n² ออกมา n+1 ชุด
      แม้ภายนอกจะดูแปลก แต่เมื่อเรียนรู้สัญลักษณ์และ operation พื้นฐานแล้ว APL กลับตรงไปตรงมาอย่างคาดไม่ถึง เพียงแต่ต้องใช้เวลาเพื่อให้ชำนาญ และเมื่อไปถึงจุดนั้นก็รู้สึกเหมือนมีพลังพิเศษ
    • เมื่อคิดว่ามีคนหลายพันล้านคนที่อ่านและเขียนตัวอักษรที่ไม่ใช่ภาษาอังกฤษอยู่แล้ว ก็ไม่แน่ใจว่าการมีคนอ่าน APL ได้นั้นพิเศษหรือน่าประหลาดใจกว่ากันตรงไหน
  • ที่บอกว่าผู้สนับสนุนภาษานี้เน้นเรื่องความเร็ว ความง่ายในการประมวลผล array และ syntax ที่แสดงออกได้ดี นั้นถูกต้อง
    https://en.m.wikipedia.org/wiki/K_(programming_language)

    • แต่ไม่แน่ใจว่า ความสามารถในการบำรุงรักษา จะนับเป็นข้อดีด้วยหรือไม่
  • จำนวนบรรทัดของโค้ดเป็นตัวชี้วัดที่ไม่ดี เพราะแต่ละภาษามีวิธีเขียนบรรทัดต่างกัน
    มาตรวัดที่ดีกว่าอาจเป็นการนับ จำนวนโหนดใน syntax tree ตาม non-terminal symbol ที่มีความหมาย เช่น “ค่าคงที่” หรือ “การเรียกฟังก์ชัน” และถ้าพิจารณาความลึกกับ branching factor ของต้นไม้นั้นด้วยก็ยิ่งดี

    • เห็นด้วยยากกับแนวคิดที่ว่าแค่ความหมายเท่านั้นสำคัญ ประสบการณ์ผู้ใช้ของภาษา ความชัดเจน วิธีคิด และพลังในการสื่อความก็สำคัญเช่นกัน และ ขนาดทางสายตา ของโค้ดก็ส่งผลต่อสิ่งเหล่านี้
      วิธีแก้แบบบรรทัดเดียวแทบไม่กินพื้นที่หน้าจอ จึงเป็นข้อได้เปรียบมากเมื่อต้องจัดการปัญหาซับซ้อน การขยับสายตาภายในหน้าจอเดียวมีภาระน้อยกว่าการเลื่อนและสลับไปมาระหว่างไฟล์มาก และ cognitive load ก็สำคัญ
      ต่อให้ไม่รู้จัก K ถ้าเห็นค่าคงที่เรียงอยู่ข้างกัน ก็ดูเหมือนกำลังใช้การแทนข้อมูลของปัญหาโดยตรง ถ้าวัฒนธรรมของ K ส่งเสริมโค้ดแบบนี้และทำให้ความคิดเอนไปทางความตรงไปตรงมากับความเรียบง่าย ก็อยากเอา ซอสสูตรพิเศษ แบบนั้นเข้าทีม
    • built-in function และ API ของ system library ทำให้มาตรวัดแบบนี้เสียรูป ตัวอย่างเช่น HQ9+ ทำเรื่องพิมพ์ “Hello, world!” ได้ค่อนข้างดี
      https://cliffle.com/esoterica/hq9plus/
    • มาตรวัดที่นิยมใช้วัดปริมาณข้อมูลก็คือ จำนวนบิต ล้วน ๆ เหมือนในทฤษฎีสารสนเทศเชิงอัลกอริทึม
      https://en.wikipedia.org/wiki/Algorithmic_information_theory
    • โค้ดบรรทัดเดียวนี้เห็นได้ชัดว่าทำขึ้นเล่น ๆ และไม่มีใครอ้างอย่างมีเหตุผลว่ามันเป็นโค้ดที่อ่านง่าย การเถียงเรื่องนิยามตรงนี้คือการพลาดประเด็น ประเด็นคือ “ด้วย K สามารถเขียน โค้ดที่มีความหนาแน่นสูงมาก ได้”
  • เคยสงสัยอยู่บ่อย ๆ ว่าการใช้ภาษาอย่าง APL/K ทำให้โปรแกรมเมอร์คิดแก้ปัญหาได้มีประสิทธิภาพขึ้นจริงหรือไม่

    • ในฐานะโปรแกรมเมอร์ kdb+/Q คิดว่าขึ้นอยู่กับประเภทของปัญหา เวลาจัดการ array ของข้อมูล การคิดและเขียนว่า avg a+b เพื่อบวก array สองตัวแล้วหาค่าเฉลี่ยนั้นง่ายกว่าอย่างชัดเจน
      ถ้าเป็นภาษาที่ไม่ได้มี array เป็นศูนย์กลาง ก็น่าจะต้องมีการตรวจขอบเขต loop for ขนาดใหญ่ ตัวแปรชั่วคราวสำหรับเก็บผลรวมกับจำนวน ฯลฯ ในภาษาอย่าง C งานที่ต้องเขียนราว 6 บรรทัด ใน Q จบได้ด้วย 6 ตัวอักษร
      อย่างไรก็ตาม ทุกภาษาก็มีฟีเจอร์ที่ช่วยให้ให้เหตุผลกับปัญหาบางประเภทได้ดีขึ้น ภาษา functional ที่มี algebraic data type และ pattern matching เช่น OCaml หรือ F# ดีกว่า switch หรือ if-else-if ขนาดใหญ่ และภาษาที่มี syntax sugar อย่าง async/await ก็ได้เปรียบในการจัดการ concurrency
    • สำหรับกลุ่มปัญหาที่ vectorize ได้ง่าย ภาษาที่มี array เป็นศูนย์กลาง ช่วยให้การคิดและคำตอบมีประสิทธิภาพขึ้น เพราะสามารถ abstract รายละเอียดของโครงสร้างข้อมูลและการวนซ้ำได้
      ตอนทำงานเป็นควอนต์ ผมใช้ kdb+/q อย่างหนักกับกลยุทธ์ความถี่ปานกลางมานานกว่า 5 ปี แต่พอย้ายไปทำ high-frequency trading ที่สิ่งอย่างการคำนวณ order book ไม่ได้ vectorize ได้ง่ายหรือมีประสิทธิภาพ การใช้ภาษาที่มี array เป็นศูนย์กลางต่อไปกลับทำให้การให้เหตุผลกับปัญหาซับซ้อนขึ้น
    • เคยได้ฟังในงานนำเสนอของ Dyalog ซึ่งเป็นภาษาสมัยใหม่สาย APL ว่าสัญกรณ์แบบนี้ช่วยให้มองเห็น idiom บางอย่างได้ง่ายขึ้น
      https://youtu.be/PlM9BXfu7UY?si=ORtwI1qmfmzhJGZX&t=3598
      ส่วนนั้นอยู่ในบริบทของ compiler แต่ภาพรวมของการนำเสนอพูดถึง Dyalog และ APL ในฐานะระบบสัญกรณ์ทางคณิตศาสตร์ แกนหลักคือการ optimize นิพจน์คณิตศาสตร์อาจง่ายกว่า optimize โค้ดทั่วไป
    • Hillel Wayne พูดถึงหัวข้อนี้เป็นครั้งคราวใน newsletter ของเขา ผมเชื่อแล้วว่าเขาคิดแก้ปัญหาบางอย่างใน ภาษา array ได้ดีกว่าจริง แต่ก็ยังนึกไม่ออกว่าประสบการณ์นั้นให้ความรู้สึกอย่างไร
    • ข้อดีของสไตล์ภาษา array คือเวลาถกเถียงเรื่องการปรับเปลี่ยนอัลกอริทึม ชิ้นโค้ดที่เกี่ยวข้องมีเพียงไม่กี่ตัวอักษร จึงใส่ไว้ในเนื้อความได้เลย ต่างจากภาษาดั้งเดิมแบบเขียนแนวตั้งที่ต้องใช้หลายบรรทัดหรือหลายสิบบรรทัดเพื่อพูดเรื่องเดียวกัน ทำให้ต้องสลับระหว่าง code block กับข้อความอธิบายอยู่เรื่อย ๆ
  • หนึ่งในสิ่งที่สำคัญที่สุดตรงนี้คือ ตัวสร้างโจทย์ด้านบนนั้นชัดเจนมาก นี่คือความต่างระหว่าง ภาษาสัญลักษณ์แบบ Iverson ซึ่งรวมถึง J และ K กับภาษาอื่นๆ
    แม้จะไม่มีความงดงามและพลังของวิธีแก้แบบบรรทัดเดียว แต่ก็เรียบร้อยและเข้าใจได้มากแม้ไม่มีคอมเมนต์อย่างเข้มงวด อย่างไรก็ตาม ผมคิดว่า lamp ไม่ใช่สัญลักษณ์คอมเมนต์ที่ดี
    วิธีแก้แบบบรรทัดเดียวนั้นน่าทึ่ง และการเขียนโปรแกรมแบบ implicit ก็เจ๋งจนบิดสมอง แนวคิดที่ใช้ความกระชับเฉพาะตัวของภาษาที่อิง glyph เพื่ออธิบายและทำ functional programming แล้วนำสิ่งนั้นไปใช้กับอาร์เรย์ทั้งชุดอีกที เป็นความคิดระดับอัจฉริยะ
    https://www.jsoftware.com/papers/fork.htm

    • แค่เพราะสามารถเขียนทุกอย่างในบรรทัดเดียวโดยไม่มีช่องว่างได้ ไม่ได้แปลว่าจำเป็นต้องทำอย่างนั้น
      แน่นอนว่าถ้าตัดความสามารถนั้นออก ก็อาจบังคับให้เขียนโค้ดยืดยาวขึ้นได้ แต่แบบนั้นจะลดจุดแข็งในฐานะเครื่องมือแบบโต้ตอบลงอย่างมาก ภาษาแบบ Iverson มีประโยชน์กับ งานแบบโต้ตอบ เพราะเขียนโค้ดที่สั้นมากได้ โค้ดในตอนนั้นถึงขั้นไม่ได้ถูกบันทึกไว้ด้วยซ้ำ จึงเป็นโค้ดแบบ write-only อย่างแท้จริง
      เวลาจะเขียนโค้ดลงไฟล์ ก็เลือกสไตล์ที่ต้องการได้ และตอนนั้นแนะนำให้เขียนแบบไม่บีบอัดมากนัก ถึงอย่างนั้น ต่อให้เขียนภาษาแบบ Iverson ในสไตล์ยืดยาว ก็ยังให้โค้ดที่สั้นกว่าภาษาส่วนใหญ่อยู่ดี
  • คนส่วนใหญ่ไม่ชอบเพราะสัญลักษณ์ แต่ปัญหาของผมไม่ใช่ตรงนั้น
    ผมชอบ APL และภาษาอาร์เรย์ และสิ่งที่ได้เรียนมาก็ช่วยได้มากเวลาใช้ภาษาอื่นๆ แต่สุดท้ายมันไม่ได้กลายเป็นเครื่องมือประจำวัน ไม่ใช่เพราะสัญลักษณ์ แต่เพราะหลังจากใช้งานแบบเป็นพักๆ ราว 3–4 ปี ผมชนกำแพงที่ก้าวข้ามไม่ได้
    ในภาษาอื่นๆ มักจะมี แนวทางทั่วไป ที่ช่วยแก้ปัญหาไปแบบคร่าวๆ ได้ และภายหลังถ้าพบ “เคล็ดลับ” ของปัญหานั้น ก็ค่อยแก้ให้สง่างามและมีประสิทธิภาพขึ้นได้ แต่ APL ให้ความรู้สึกว่าไม่มีทางเลี่ยงชั่วคราวแบบนั้น มีแค่รู้เคล็ดลับหรือไม่รู้เท่านั้น
    ผมไม่แน่ใจว่านั่นเป็นความจริงหรือเปล่า หรือถ้าเรียนเคล็ดลับมากพอแล้วจะเกิดสัญชาตญาณในการแก้ปัญหาขึ้นมา หรือท้ายที่สุดมันก็มีแต่เคล็ดลับอยู่ดี หรือผมแค่ไม่ได้อ่านเอกสารกลยุทธ์แกนหลักกันแน่

    • ความรู้สึกนั้นไม่ได้ผิด การเรียนภาษาอาร์เรย์ทำให้เกิดความประทับใจแบบนั้นได้ง่ายมาก คนที่ใช้มานานมักเห็นปัญหาแล้วพูดว่า “ทำไมแก้ซับซ้อนขนาดนั้น ก็แค่ใช้ ⍸⍣¯1 ก็ได้แล้วไม่ใช่เหรอ?” แต่มีความเป็นไปได้สูงว่าไม่เคยมีใครบอกมาก่อนว่า มีการดำเนินการผกผัน และใช้อย่างไร
      แม้ตอนนี้จะใช้ภาษาพวกนี้มาหลายปีแล้ว แต่กำแพงโค้ดที่โปรแกรมเมอร์อาร์เรย์บางคนสร้างขึ้นก็ยังทำให้รู้สึกหนักใจอยู่บ้าง เข้าใจว่าทำไมเขียนแบบนั้น แต่โดยส่วนตัวชอบให้โค้ดมีช่องว่างบ้าง
      ผมกำลังสร้างภาษาอาร์เรย์ที่อิง APL อยู่ และหนึ่งในเป้าหมายช่วงแรกคือทำให้ สไตล์ imperative เป็นพลเมืองชั้นหนึ่ง โดยไม่ลงโทษมือใหม่ที่ใช้สิ่งอย่างคำสั่ง if ผมมองว่าสไตล์นี้อยู่กึ่งกลางระหว่างแนว APL บริสุทธิ์กับภาษา imperative ทั่วไป
      https://codeberg.org/loke/array/src/branch/master/array/standard-lib/output3.kap
    • กำแพงที่พูดถึงเป็นปัญหาจริงของเส้นทางเริ่มต้นเรียน APL ในปัจจุบัน ปีที่แล้วผมก็เคยนำเสนอในหัวข้อนี้โดยตรง และมันไม่ใช่ความผิดส่วนบุคคลเลย
      แต่ก็ไม่ใช่ข้อจำกัดของตัวภาษาเองเช่นกัน จากประสบการณ์ของผม กระบวนการทะลุกำแพงนั้นก็คือกระบวนการที่พาราไดม์เริ่มเข้าที่เข้าทาง หลังจากแฮ็กโปรโตไทป์ YAML parser อยู่ราว 500 ชั่วโมงตลอด 1 ปี ชิ้นส่วนต่างๆ จึงเริ่มประกอบกันได้
      แก่นสำคัญดูเหมือนจะเป็นการผสมกันของหลักการออกแบบที่ขับเคลื่อนด้วยข้อมูล วิธีนำคุณสมบัติแบบ Iverson ของสัญกรณ์ที่ดีมาใช้ในสถาปัตยกรรมซอฟต์แวร์อย่างเป็นรูปธรรม และการคุ้นเคยกับ idiom รวมถึงวิธีที่มันแสดงแนวคิดของโดเมน
      https://dyalog.tv/Dyalog23/?v=J4cg6SV92C4
      https://www.jsoftware.com/papers/tot.htm
  • มีวิดีโอเกี่ยวกับหัวข้อนี้
    https://www.youtube.com/watch?v=DmT80OseAGs
    สามารถลองวิธีแก้ได้ด้วยตัวเองที่ https://tryapl.org/

  • ถ้าเปรียบเทียบบรรทัดเดียวนี้กับวิธีแก้แบบ code golf ในภาษาโปรแกรมต่างๆ ก็น่าจะน่าสนใจ
    https://codegolf.stackexchange.com/questions/tagged/sudoku?tab=Votes

    • ที่น่าสนใจคือ สำหรับโจทย์เฉพาะอย่างการแก้ซูโดกุด้วย brute force วิธีแก้อันดับ 1 คือ ชิ้นส่วน K พอดี ส่วนอันดับ 2 คือวิธีแก้ J ที่ทำตามวิธีแก้ K
      https://codegolf.stackexchange.com/a/5030