Fibonacci

posted on 02 Jun 2008 22:55 by ipats
สวัสดีครับ
ก่อนอื่น ก็ขอขอบคุณทุกๆ คน ที่อวยพรวันเกิด exteen ให้นะครับ
ตอนแรกว่าจะเขียนบล็อกถึงเหมือนกัน แต่ด้วยตัวแปรบางอย่าง เลยขอติดไว้ก่อนนะครับ ;)

พอดีว่าช่วงนี้เพิงได้ดูซีรีย์ Numb3rs มาครับ สนุกดีอ่ะ
แล้วบวกกับวันนี้คุยกับอ. มะนาวนิดหน่อย ว่าอาจารย์กำลังสอนเด็กอยู่
วิชา practicum สอน python ซะด้วยอ่ะ.. สมัยนี้เขา พัต-ตะ-นา แล้วววว
(หมายเหตุ: วิชานี้ เป็นวิชาแนวๆ เตรียมความพร้อมเด็กปีสอง สอบพื้นฐานหลายอย่างมาก)

มันก็เลยเกิดการคิดถึงสมัยเรียน (แก่แล้วเนาะ)
แถมวันนี้ได้มีบทสนทนาเกี่ยวกับแนวคิดการเขียนโปรแกรมนิดหน่อย
เลยมีไอเดียเขียนบล็อกขึ้นมาซะงั้น ;)

วันนี้ จะมาเขียนถึงเรื่อง การแก้ปัญหา, เขียนโปรแกรม โดยใช้กรณีเลข Fibonacci ครับ

ก่อนอื่น ก็คงต้องว่ากันก่อนว่า ไอ้เลขนี้คืออะไร
เลข Fibonacci เป็นชุดตัวเลข ที่เลขตัวใดๆ ในชุด จะมาจากผมรวมของเลขสองตัวหน้ามัน
โดยกำหนดเริ่มต้นให้ เลขสองตัวแรก (คือตัวที่ 0 และตัวที่ 1) คือ 0 กับ 1 ตามลำดับ

ลองมาดูนิยามทางคณิตศาสตร์ และตัวเลขสิบเอ็ดตัวแรกกันครับ (จากวิกิ)



ทีนี้ เนื่องด้วยมันเป็นปัญหาคลาสสิกหรืออย่างไรไม่ทราบได้
หนังหลายเรื่องเลยพูดถึงไอ้เลขชุดนี้
แถมโจทย์ฝึกเขียนโปรแกรมจากหนังสือแทบทุกเล่มก็จะมีให้คิดไอ้เลขชุดนี้ด้วย

เพราะงั้น ผมก็เลย.. ขอเขียนมันซะหน่อย โดยใช้ภาษาซี และจำกัดให้หาได้ถึงแค่ F(40)
ซึ่งลองเขียนมาสามแบบดังนี้ครับ

แบบแรก
long int fibo1(int n){
if ((n < 0) || (n > 40)) {
return -1;
} else if (n < 2) {
return n;
} else {
return fibo1(n - 1) + fibo1(n - 2);
}
}

แบบที่สอง
int fibocal = 0;
long int fibotab[41];

long int fibo2(int n){
int i;
if (!fibocal) {
fibotab[0] = 0;
fibotab[1] = 1;
for(i=2;i<=40;i++){
fibotab[i] = fibotab[i - 1] + fibotab[i - 2];
}
fibocal = 1;
}

return ((n<=40) && (n>=0))?fibotab[n]:-1;
}

แบบที่สาม
long int fibo3(int n){
long int clist[3];
int i;
if ((n < 0) || (n > 40)) {
return -1;
} else if (n < 2) {
return n;
} else {
clist[0] = 0;
clist[1] = 1;
for(i=2;i<=n;i++) {
clist[i % 3] = clist[(i + 2) % 3] + clist[(i + 1) % 3];
}
return clist[(i - 1) % 3];
}
}


ถ้าใครอ่านโค้ดเข้าใจ ลองอ่านดูนะครับ
แล้วคิดหน่อยว่า... สามแบบนี้ มันต่างกันยังไง ข้อดีข้อเสียแต่ะแบบเป็นยังไง
แล้วคราวหน้า ผมจะมาลองเล่าให้ฟัง (อุ๊บไว้ก่อน อิอิ)

ทิ้งท้าย เฉลยโค้ดเก่าหน่อย (เหลือบไปเห็นมีคนมาตอบพอดี 555)
เริ่มจาก
ybtb ng uhaqerq qvi guerr cyhf sbhe.cv naq n dhnegre bs sbhe fvk guerr qbhoyr h

อันนี้มีคนบอกว่า แค่เห็นก็รู้แล้วว่าแปลงกลับยังไง ซึ่งมันก็ได้เป็น
logo at hundred div three plus four.pi and a quarter of four six three double u

ขั้นตอนนี้ใช้ ROT13 ครับ เป็นการเข้ารหัสแบบง่ายๆ โดยการแทนที่ด้วยตัวอักษรสิบสามตัวถัดไป
ในภาษาอังกฤษมันมี 26 ตัว ก็คือครึ่งนึงพอดี เวลาจะเข้ารหัส หรือถอดรหัส ก็เลยใช้วิธีเดียวกัน

ทีนี้ จากประโยคนั้น มันก็ได้เป็น
logo ที่ 100 / 3 + 4.31416 และ 1/4 * 463 W
logo ที่ 37.64749 และ 115.75 W

เห็นเลขสองตัว พร้อมคำว่า ที่ (at) ก็ควรจะนึกถึงพิกัดอะไรซักอย่างเนาะ
แถมมีตัว W ห้อยท้าย... พิกัดไรน้อ มี W ด้วย...

ติ๊ก ต๊อก ติ๊ก ต็อก

มันคือ lat/long นั่นเอง เอ๊า.. จิ้มไปโลด
(W = West ใน Google Map ก็แทนด้วยค่าติดลบนั่นเอง)

ปล. เลขไฟโบ มีชื่อเล่น (ที่ตั้งเอง) ว่า.. "เลขกระต่ายเอากัน" :p
(อยากรู้ทำไม ไปดูในวิกิ หาคำว่า rabbit ในหน้านั่นอ่ะ)

Comment



smilebig smileopen-mounthed smileconfused smilesad smileangry smiletonguequestionembarrassedsurprised smilewinkdouble winkcry

ตอนแรกว่าจะเขียนบล็อกถึงเหมือนกัน แต่ด้วยตัวแปรบางอย่าง เลยขอติดไว้ก่อนนะครับ ;) << ตัวแปรความง่วงฤา
sad smile อ่านออก แบบว่า ต่างกันไงหว่า ดูคราวๆ ก็ แบบสุดท้ายประหยัดเมมโมรี่สุด แล้วก็น่าจะเร็วสุดมั้ย หว่า แค่วนๆลูปเอา ความเร็วเท่าๆ กับแบบ สองหละมั่ง แต่แบบสองต้องใช้พื้นที่ในการเก็บค่าตัวแปลมากก่า

...มั่วไปเรื่อย...

#2 By หมูทอดซามะ on 2008-06-02 23:53

สอนเขียนโปรแกรมพื้นฐานต้องมี 3 อย่าง
Hello World
หา Leap Year
Fibonacci

open-mounthed smile open-mounthed smile

#3 By @ri on 2008-06-03 00:24

ผมเคยเรียนแค่ Pascal ตอนปี 1
และคืนอาจารย์ไปเรียบร้อยแล้ว
ยิ่ง Mathlab ยิ่งแล้วใหญ่
ลอกเพื่อนตลอด

#4 By AkE on 2008-06-03 08:59

สมัยก่อนนิยมสอนการเขียนฟังก์ชั่น recursive
จากตัวอย่างการหาค่า factorial

แต่เดี๋ยวนี้ใช้ Frodo เอ๊ย Fibonacci แล้วเหรอ
ยุคนี้เค้าพัฒนาแล้วจริง ๆ แฮะ
open-mounthed smile

#5 By oatato on 2008-06-03 09:09

ช่วยหน้อยครับ
ถ้าหากจะแสดงเฉพาะค่า เช่น ใส่ค่า 3
ผลลัพธ์จะได้เป็น 0,1,1

#6 By jung (202.91.18.206) on 2008-07-18 01:04

ต่อจากเมื่อกี้ครับ
แบบว่าให้ใชฟังก์ชั่น fibonacci ครับ

#7 By jung (202.91.18.206) on 2008-07-18 01:06