Friday, December 29, 2006

Ninety-nine Lisp Problem #p04,#p05


P04 (*) Find the number of elements of a list.

ทำได้ 2 แบบคือ
1. ใช้ recursive ธรรมดา
2. ใช้ tail recursive

clisp
(defun len (lst)
(if (null lst)
0
(1+ (len (cdr lst)))))

(defun len-2 (lst &optional (cnt 0))
(if (null lst)
cnt
(len-2 (cdr lst) (1+ cnt))))


haskell
len :: [a] -> Int
len ([]) = 0
len (_:xs) = 1 + len xs


len_2 :: [a] -> Int
len_2 (xs) = len_helper xs 0
where
len_helper ([]) n = n
len_helper (_:xs) n = len_helper xs (n + 1)


erlang
-module(p04).
-export([len/1,len_2/1]).

len([]) ->
0;
len([_|XS]) ->
1 + len(XS).


len_2(L) ->
len_iter(L,0).

len_iter([],N) ->
N;
len_iter([_|XS],N) ->
len_iter(XS,N+1).


P05 (*) Reverse a list.


implement ทั้งหมดแบบ tail-recursive

clisp
(defun rev (lst &optional (tmp '()))
(if (null lst)
tmp
(rev (cdr lst) (cons (first lst) tmp))))


haskell
inv :: [a] -> [a]
inv l = invx l []
where
invx [] y = y
invx (x:xs) y = invx xs (x : y)

ดูยาว, แต่ถ้าไปดู implement ของ hugs เขาจะเขียนแค่นี้
reverse   :: [a] -> [a]
reverse = foldl (flip (:)) []


erlang
-module(p05).
-export([rev/1]).

rev(X) ->
rev(X,[]).

rev([], L) ->
L;
rev([H|T], L) ->
rev(T, [H|L]).

Related link from Roti

Thursday, December 28, 2006

clouds

เคยได้ยินเมฆที่ชื่อแบบนี้ไหม
Lenticular cloud, Wave cloud, Nacreous cloud,
Mammatus cloud

ลองไปดูภาพได้ที่นี่ Strange cloud

นึกถือตอนเด็กๆ มีอยู่ช่วงหนึ่งผมสร้างบ้านบนต้นไม้ (แค่เอาแผ่นไม้ 1 แผ่น กับกล่อง 1 กล่อง ไปวาง)
แล้วก็ใช้เป็นสถานีดูเมฆ
ตอนนั้นจำได้ว่าได้แรงบันดาลใจจากบทความว่าด้วยประเภทของเมฆ ในวารสาร "ทักษะ"
หนังสือซึ่งใครที่แก่สักหน่อยคงจะรู้จัก

Related link from Roti

เสริม ICU4J

bact' เขียนเรื่อง Using dictionary with ICU4J BreakIterator
เห็น code ที่ bact' ใช้ในการ initialize
String rules = (RuleBasedBreakIterator.getWordInstance(new Locale ("th"))).toString();

ในส่วนของการได้มาซึ่ง rules มันดูแปลกๆ
ก็เลยไปนั่งไล่ code ดูว่ามันมาจากไหนกันแน่

เริ่มแรกสุด method getWordInstance มันเป็น static method
ใน class BreakIterator
ดังนั้นถ้าจะเขียนให้สื่อหน่อย อาจจะเขียนอย่างนี้แทน
String rules = BreakIterator.getWordInstance(new Locale ("th")).toString()


method getWordInstance ไม่ได้สร้าง BreakIterator เอง
แต่ delegate งานไปให้ BreakIteratorFactory เป็นคนทำ
ซึ่ง BreakIteratorFactory จะใช้กลไก ResourceBundle ในการค้นหา
ว่าจะใช้ rule file ตัวไหนดี

จากการ debug, ตัว rule file จะใช้ file
com/ibm/icu/impl/data/icudt36b/brkitr/word.brk
ภายในเป็น binary file ก็เลยไม่รู้ว่ามีเนื้อหาอะไรบ้าง

เมื่อได้ rule มาแล้ว
BreakIteratorFactory มันจะสร้าง BreakIterator ให้เราโดยใช้คำสั่งนี้
//TODO: Hard code this for now! fix it once CompactTrieDictionary is ported
if(locale.equals("th")){
String fileName = "data/th.brk";
InputStream is = ICUData.getStream(fileName);
iter = new DictionaryBasedBreakIterator(ruleStream, is);
}

Note: สังเกตุ comment ใน Todo ด้วย

ดังนั้นตัวอย่างของ bact'
ถ้าเขียนใหม่ให้ชัดเจนไปเลยว่า rule มาจากไหน
อาจจะเขียนดังนี้
InputStream rules = ICUData.getStream("data/icudt36b/brkitr/word.brk");
InputStream dict = new FileInputStream("tdict.dic");

DictionaryBasedBreakIterator iter =
new DictionaryBasedBreakIterator(rules, dict);

Related link from Roti

Wednesday, December 27, 2006

การข่าวมหาดไทย

เฮ้อ อ่านข้อเขียนเรื่อง "การข่าวท่านปลัด"
ของ พลเอกบัญชร ชวาลศิลป์ ในมติชนสุดสัปดาห์
ที่เขียนเล่ากรณี การจราจลที่เกิดจากการประท้วงเรื่องโรงงานแทนทาลัมที่ภูเก็ต
แล้วเหนื่อยใจ

ก็พอรู้นะว่า กระทรวงนี้ คาดหวังอะไรไม่ได้
แต่ไม่นึกว่า มันจะแย่ขนาดนี้

Note: เรื่องนี้เกิดมานานแล้ว จำปีไม่ได้แล้ว
แต่เชื่อว่า ปัจจุบันก็มหาดไทยก็คงไม่หนีไปไหนไกลหรอก

ลองอ่าน quote นี้ดู

นายพิศาล มูลศาสตรสาทร ท่านสรุปว่า
เหตุการณ์รุนแรงที่เกิดขึ้นที่ภูเก็ตครั้งนี้มาจากกลุ่มผู้ก่อการร้าย 2 กลุ่มด้วยกัน
ผู้ก่อการร้ายพวกแรกคือพรรคคอมมิวนิสต์แห่งประเทศไทย
...
ในคืนก่อนหน้าที่จะเกิดเหตุ ผกค. จำนวนหนึ่งได้เคลื่อนย้าย
เข้ามายังตัวจังหวัดภูเก็ต เพื่อเป็นแกนนำในการปฏิบัติการ
โดยแทรกซึมเข้ามาด้วยรถบรรทุกสิบล้อจำนวนหนึ่ง
เพื่ออำพรางเจ้าหน้าที่ แล้วโดดลงข้างทางบริเวณที่เป็นสวนยาง
ค่อยๆเดินเท้าแทรกซึมไปรวมตัวกันที่วัดฉลอง แล้วเข้าปฏิบัติการจนเป็นผลสำเร็จ
สามารถเผาโรงแรมและโรงงานได้สำเร็จตามแผน
...
ผม[พลเอกบัญชร]ฟังคำบรรยายสรุปของปลัดมหาดไทยด้วยความแปลกใจ
และขนลุก แต่การรายงานข่าวของท่านยังไม่จบลงเพียงแค่นั้น

นอกจาก ผกค. แล้ว ... มีพวก ขจก. ซึ่งปกติจะเคลื่อนไหว
อยู่เฉพาะจังหวัดชายแดนภาคใต้เท่านั้น
...
ก่อนเกิดเหตุการณ์จราจลไม่กี่วัน เด็กหนุ่ม ขจก. เหล่านี้
ได้กระโดดร่มลงยังบริเวณพื้นที่จังหวัดพังงา

แล้วเดินทางแทรกซึมเข้ามาร่วมการก่อจราจล


พลเอกบัญชร เขาเขียนให้ความเห็นว่า

นี่คือความเชื่อเป็นตุเป็นตะ จนกล้านำเสนอในที่ประชุมระดับชาติของปลัด
ซึ่งน่าจะสะท้อนความเป็นจริงของหน่วยงานที่มีความสำคัญทางด้าน
ความมั่นคงของประเทศหน่วยนี้ในขณะนั้น


น่าสนใจมาก
plot เรื่องเน่าสนิท เหมือนละครก่อน/หลังข่าวเลย

Related link from Roti

Tuesday, December 26, 2006

Chart with dojo

ใครอยาก plot graph บน browser
ตอนนี้มีทางเลือกง่ายๆอีกทางแล้ว

ใน dojo 0.4.x,
มีคน contribute dojo.charting package เข้าไปแล้ว

technique การ implement ที่ใช้ ก็คือ
ถ้าเป็นพวก browser ที่ support svg ก็จะใช้ svg ในการ render
แต่ถ้าเป็น IE ก็ใช้ vml ในการ render

การออกแบบ object Structure ก็ซับซ้อนนิดๆ
แต่ก็ทำให้มันยืดหยุ่นดี
ลอง plot graph เส้นง่ายๆแบบนี้ดู



เริ่มแรกสุด data ที่จะ plot ต้องอยู่ในรูป object dojo.collections.Store
var json = [
{ Id:1, year:2001, value:20000 },
{ Id:2, year:2002, value:30000 },
{ Id:3, year:2003, value:40000 },
{ Id:4, year:2004, value:35000 }
];

var store = new dojo.collections.Store();
store.setData(json);

กำหนด series ซึ่งเป็นชุดของข้อมูลที่จะ plot
(graph หนึ่งๆสามารถมีได้หลาย series)
var s1 = new dojo.charting.Series(
{
dataSource: store,
bindings: { x:"year", y:"value" },
color:"#0022bb",
label:"SFCT"
});

กำหนด Axis (แกน x, แกน y)
var xA = new dojo.charting.Axis();
xA.range = {upper:2004, lower:2001};
xA.origin="year";
xA.showTicks = true;
xA.label = "year";
xA.labels = [2001,2002,2003,2004];

var yA = new dojo.charting.Axis();
yA.range = {upper:100000, lower:0};
yA.showLines = true;
yA.showTicks = true;
yA.label = "value";
yA.labels = [ {label:"0", value:0}, {label:"100,000", value:100000} ];

สร้าง Plot object ซึ่งเป็นการจับคู่แกน axis
และกำหนด series ให้กับ Plot object
(1 Plot สามารถมีได้หลาย Series)
var p = new dojo.charting.Plot(xA, yA);
p.addSeries( {data:s1, plotter: dojo.charting.Plotters.Line} );

กำหนด PlotArea
var pa = new dojo.charting.PlotArea();
pa.size = {width:700, height:200};
pa.padding={top:20, right:40, bottom:30, left:70};
pa.plots.push(p);

สุดท้ายก็คือ Chart object
โดย 1 chart สามารถมีได้หลาย PlotArea
var chart = new dojo.charting.Chart(null, "Test", "description");
chart.addPlotArea({ x:0, y:0, plotArea:pa});


เวลาจะแสดง graph ก็แค่ bind object เข้ากับ dom element ที่ต้องการ
chart.node = dojo.byId("chartTest1");
chart.render();

Related link from Roti