สามเหลี่ยมของปาสคาล

  • warning: realpath() [function.realpath]: SAFE MODE Restriction in effect. The script whose uid is 1005 is not allowed to access /tmp owned by uid 0 in /var/www/sites/sugree/codenone.com/subdomains/www/html/includes/file.inc on line 190.
  • warning: realpath() [function.realpath]: SAFE MODE Restriction in effect. The script whose uid is 1005 is not allowed to access /tmp owned by uid 0 in /var/www/sites/sugree/codenone.com/subdomains/www/html/includes/file.inc on line 190.

ผมอ่านโจทย์มาจากหนังสือแต่ก็ไม่รู้เข้าใจถูกหรือเปล่า (ถ้าเข้าใจผิดก็นึกว่าเป็นอีกโจทย์แล้วกัน)

    1
   1 1
  1 2 1
 1 3 3 1
1 4 6 4 1

สามเหลี่ยมของปาสคาล ตัวเลขแต่ละตัวเท่ากับการเอาตัวเลข 2 ตัวข้างบนมาบวกกัน

โจทย์คือมีฟังก์ชัน f(column, row) = เลขในสามเหลี่ยม เช่น

f(2,5) = 4 เป็นต้น

veer's picture

scheme แบบถึกๆ ตรงไปตรงมา http://codenone.com/node/152

อธิบายให้ชัดขึ้นว่า column, row ชี้อย่างไร

+--1--2--3--4--5--6 -> col
1| 1  0  0  0  0  0 ...
2| 1  1  0  0  0  0 ...
3| 1  2  1  0  0  0 ...
4| 1  3  3  1  0  0 ...
5| 1  4  6  4  1  0 ...
6| 1  5 10 10  5  1 ...
 | ...
 V ...
row

f(2, 1) = 0
f(3, 3) = 1
f(4, 5) = 4

ของ ruby มาแล้ว
http://www.codenone.com/node/155

โจทย์นี้เหมาะแก่มือใหม่หัด haskell อย่างผมมากเลย
ิเริ่มที่แบบแรก recursive แบบ ธรรมดา

tri :: Int -> Int -> Int
tri 1 _ = 1
tri col row
        | row == col = 1
        | col > row = 0           
        | otherwise = (tri col (row-1)) + (tri (col-1) (row-1))

เขียนแค่นี้ก็ใช้ได้ แต่ดูไม่ haskell เลย
ไม่ต่างอะไรกับใช้ ruby เขียน

ก็พยายามหาเรื่องให้เป็น haskell มากขึ้น
โดยพยายามทำเป็น set
โดยมองว่า ที่ row > 2 มันจะขึ้นต้นด้วย 1 และลงท้ายด้วย 1
ส่วนระหว่างกลาง เกิดจาก row ข้างบนบวกกัน

nthrow :: Int -> [Int]
nthrow 1 = [1]
nthrow 2 = [1,1]
nthrow n = 1 : map (\x -> (rowabove !! x) + (rowabove !! (x-1))) [1..(n-2)] ++ [1]
           where rowabove = nthrow (n-1)

ดูเป็น set มากขึ้น แต่ก็ไม่สวยอยู่ดี
สุดท้ายหลังจากไปลองค้น google ดูก็พบอันนี้

nextPascal xs = ($+) xs (0:xs)
pascalTriangle = iterate nextPascal [1]

หลักการก็ประมาณว่า
row ที่ n เกิดจาก row n-1 กับ (row (n-1) ที่แปะ 0 นำหน้า )
row 1 = [1]
row 2 = [1] $+ [0,1] => [1,1]
row 3 = [1,1] $+ [0,1,1] => [1,2,1]
row 4 = [1,2,1] $+ [0,1,2,1] => [1,3,3,1]

ชอบมาก
Note: นิยาม operator $+ คือ

($+) (a:as) (b:bs) = (a+b) : (($+) as bs)
($+) as [] = as
($+) [] bs = bs
veer's picture

Haskell ดูกระชับดี แต่ว่าก็ดูเหมือนจะมี convention ต้องเรียนรู้เยอะอยู่เหมือนกัน

ย้าย Codenone

ประกาศย้าย Codenone ไปใช้ Forum ของ Blognone แทนครับ ตามไปตั้งกระทู้ต่อได้ที่ Codenone Forum (รายละเอียดอ่านจากกระทู้ ย้าย Codenone ไปรวมกับ Blognone)

กระทู้เก่าๆ จะย้ายตามไปในภายหลัง ตอนนี้ปิดการโพสต์กระทู้ไว้ เหลือไว้เฉพาะอ้างอิงเท่านั้น