tag:blogger.com,1999:blog-33158715735099446182024-03-05T19:11:56.205+07:00neizodinsufficient data for meaningful answer.nzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.comBlogger250125tag:blogger.com,1999:blog-3315871573509944618.post-31789129108276652902016-03-23T07:18:00.002+07:002016-09-25T21:58:14.544+07:00ใบเฟิร์น Barnsley<p>ความสวยงามอย่างหนึ่งของใบเฟิร์น คือ รูปทรงของส่วนย่อยๆ ภายในใบจะมีความคล้ายคลึงกับใบเฟิร์นทั้งใบ ภาษาคณิตศาสตร์มีชื่อเรียกพิเศษให้รูปทรงเหล่านี้เลยว่า <a href="https://en.wikipedia.org/wiki/Fractal">fractal</a> แต่ถ้าใครคุ้นเคยกับศัพท์สายคอมพิวเตอร์มากกว่า ก็อาจจะมองว่ามันเป็น <a href="https://en.wikipedia.org/wiki/Recursion">recursion</a> ก็ได้</p><br />
<p>การสร้าง fractal รูปใบเฟิร์นอย่างง่าย สามารถอธิบายคร่าวๆ ได้ด้วยขั้นตอนวิธีนี้</p><br />
<ol> <li>ลากเส้นตรงความยาว $l$ ไม่ต้องเยอะมากนัก แล้วเลือกปลายข้างหนึ่งไว้เป็นปลายที่จะต่อยอดออกไป</li>
<li>ที่ปลายยอดของเส้นตั้งต้น ทำสองขั้นตอนต่อไปนี้เพื่อลากเส้นเพิ่ม 3 เส้น<br />
<ul> <li>ลากเส้นตรงความยาว $0.2$ เท่าของความยาวเส้นตั้งต้น ในทิศทางตั้งฉากกับเส้นตั้งต้นทั้งสองข้าง</li>
<li>ลากเส้นตรงความยาว $0.8$ เท่าของความยาวเส้นตั้งต้น ในทิศทางต่อขึ้นไปตรงๆ จากเส้นตั้งต้น</li>
</ul> </li>
<li>สำหรับแต่ละเส้นที่ลากต่อออกมาในข้อ 2 นั้น เลือกปลายด้านที่ว่างๆ ไว้เป็นปลายต่อยอด แล้ววนกลับไปทำขั้นตอนที่ 2 โดยเปลี่ยนมาใช้เส้นตั้งต้นเป็นเส้นที่ได้จากข้อ 2 แทน (คิดซะว่าเส้นใหม่นี้ยาว $l$) ทำไปเรื่อยๆ จนกว่าจะพอใจผลลัพธ์</li>
</ol><br />
<p>วิธีการข้างต้นจะให้ผลลัพธ์เป็นรูปใบเฟิร์นเรียบๆ ตรงๆ ไม่หวือหวานัก แต่ก็มีนักคณิตศาสตร์นามว่า Michael Barnsley ได้เขียนสมการกำหนดมุมและจัดตำแหน่งของการต่อยอดให้สวยงามมีลูกเล่น เนื่องจากเขาเป็นคนแรกที่เขียนเรื่องนี้ไว้ตั้งแต่ปี 1993 ทุกคนเลยพากันเรียกใบเฟิร์นที่สวยงามเป็นเอกลักษณ์นี้ว่า ใบเฟิร์น Barnsley</p><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNkQDgqCDiEdM0cniIC0s6k6GvRZjknQBuIL_K9-IQJ83EDi1Ky2vsu1c-1Q0GszSuD-F_2qqgEJMWdn5AbB1jQ74uHk4Lw_NKS1gBg2OExElvJwfh8GJYoIYA2sNE7UBAqoarEVq97BB8/s1600/barnsley-fern-23it.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNkQDgqCDiEdM0cniIC0s6k6GvRZjknQBuIL_K9-IQJ83EDi1Ky2vsu1c-1Q0GszSuD-F_2qqgEJMWdn5AbB1jQ74uHk4Lw_NKS1gBg2OExElvJwfh8GJYoIYA2sNE7UBAqoarEVq97BB8/s640/barnsley-fern-23it.png" /></a></div><br />
<p>พูดให้รัดกุมเป็นภาษาคณิตศาสตร์ก็คือ การสร้างใบเฟิร์น Barnsley เริ่มจากลากเส้นแรกยาว $1.6$ หน่วยจากจุด $(0,0)$ ขึ้นไปตามแกน $y$ แล้วเอาเส้นนั้นมาวาดซ้ำๆ อีกครั้ง จากเลื่อนและปรับขนาดด้วยสมการดังนี้</p><br />
<pre>f_1(x, y) = [ 0.85, 0.04; -0.04, 0.85 ] [ x; y ] + [ 0; 1.6 ]
f_2(x, y) = [ 0.20 & -0.26 \\ 0.23 & 0.22 ] [ x; y ] + [ 0; 1.6 ]
f_3(x, y) = [ -0.15, 0.28; 0.26 & 0.24 ] [ x; y ] + [ 0; 0.44 ]
</pre><br />
<p>โดย $f_1, f_2, f_3$ คือสมการสำหรับคำนวณรูปร่างก้านที่ต่อยอดขึ้นข้างบน ก้านที่เอียงไปด้านซ้าย และก้านที่พลิกตัวแล้วเอียงไปด้านขวา ตามลำดับ</p><br />
<p>ผมแนบโค้ดในภาษา Python มาให้ด้วยสำหรับใครที่ต้องการนำไปเล่นต่อ ซึ่งวิธีการที่แนบนี้เป็นการสร้างแบบ recursive ต่อยอดออกไปเรื่อยๆ ตามแนวทางขั้นตอนวิธีที่ได้กล่าวไว้ข้างต้น หากไปค้นดูวิธีอื่นเพิ่มเติมจะพบว่าวิธีการสุ่มเลือกจุดจะให้ผลลัพธ์ที่รวดเร็วกว่า</p><br />
<pre class="prettyprint">from PIL import Image, ImageDraw
def transform(matrix, xy):
return [sum(e * p for e, p in zip(row, xy)) for row in matrix]
def translate(vector, xy):
return [e + p for e, p in zip(vector, xy)]
class BarnsleyFern(object):
affines = [([[0.85, 0.04], [-0.04, 0.85]], [0, 1.6]),
([[0.20, -0.26], [0.23, 0.22]], [0, 1.6]),
([[-0.15, 0.28], [0.26, 0.24]], [0, 0.44])]
def __init__(self, depth=10, size=(800,800)):
self.image = Image.new('RGB', size)
self.draw = ImageDraw.Draw(self.image)
self.iterate([0.0, 0.0], [0.0, 1.6], depth)
def canvas_coordinate(self, xy):
width, height = self.image.size
return [width/2 + xy[0]*width/10, height - xy[1]*height/10]
def linespec(self, xy0, xy1):
return self.canvas_coordinate(xy0) + self.canvas_coordinate(xy1)
def draw_too_small(self, xy0, xy1, pos=2):
return all(round(a, pos) == round(b, pos) for a, b in zip(xy0, xy1))
def iterate(self, xy0, xy1, depth, affine=None):
if depth == 0:
return
if affine is not None:
xy0 = translate(affine[1], transform(affine[0], xy0))
xy1 = translate(affine[1], transform(affine[0], xy1))
if self.draw_too_small(xy0, xy1):
return
self.draw.line(self.linespec(xy0, xy1), fill='#0C3')
for affine in self.affines:
self.iterate(xy0, xy1, depth-1, affine)
</pre><br />
<hr /><br />
<p>fractal ยังมีรูปร่างอื่นๆ อีกมากมาย ทั้งที่พบได้ในธรรมชาติ เช่น ดอกทานตะวัน บรอคโคลี เกล็ดหิมะ หรือมากจากการสังเคราะห์ขึ้นอย่าง <a href="https://en.wikipedia.org/wiki/Sierpinski_triangle">สามเหลี่ยม Sierpinski</a> หรือ <a href="https://en.wikipedia.org/wiki/Mandelbrot_set">เซ็ต Mandelbrot</a></p><br />
<p>แต่ความมหัศจรรย์ของ fractal ที่แท้จริง คือเราไม่สามารถรู้ได้เลยว่าตอนนี้เรากำลังอยู่ตรงไหนของมันกันแน่ ลองคิดภาพว่าตัวเองเป็น Ant-Man ที่จะปรับขนาดตัวให้ไม่ใหญ่ไปกว่าก้านใบเฟิร์นที่ยืนอยู่ได้ แล้วก็ลองไปยืนอยู่บนใบเฟิร์นข้างต้นดู ณ ขณะหนึ่งเราอาจจะคิดว่าตัวเองอยู่บนก้านที่ใหญ่ที่สุดแล้ว แต่นอกจากขนาดที่แตกต่างกัน ก้านที่เราคิดว่าใหญ่ที่สุดนั้น ก็ไม่ได้มีอะไรที่แตกต่างจากก้านย่อยก้านอื่นๆ เลย หากเราเดินย้อนกลับไปเรื่อยๆ อาจพบว่าก้านที่เราคิดว่าใหญ่ที่สุดนั้น เป็นเพียงแค่ก้านย่อยที่แตกแขนงแยกออกมาก็เป็นได้</p><br />
<p>ในทางเดียวกัน เราก็ไม่สามารถแน่ใจได้ว่าตรงไหนคือจุดปลายของใบเฟิร์น เพราะยิ่งเดินค้นหาปลายใบเท่าไหร่ เราก็จะยิ่งตัวเล็กลงๆ และพบว่าใบเฟิร์นนั้นมีรูปร่างเหมือนเดิมไม่เปลี่ยนแปลง</p><br />
<p>ก็เปรียบเหมือนความรู้ เราจะรู้ได้ไงว่าอะไรคือพื้นฐานที่แท้จริงกันแน พันปีก่อนเราอาจคิดว่าถ้าได้รู้จักอะตอมก็คือรู้ถึงพื้นฐานแห่งทุกสรรพสิ่งแล้ว แต่ไม่กี่ร้อยปีก่อนเราเพิ่งพบว่าอะตอมยังแบ่งแยกย้อยลงไปได้อีกเป็นโปรตอน นิวตรอน อิเล็กตรอน และปฏิรูปพื้นฐานความรู้ด้านเคมีขึ้นใหม่ ส่วนปัจจุบันเรายังแบ่งย่อยสิ่งต่างๆ ลงไปได้อีกเป็นควาร์ก หรือแม้กระทั่งเสนอทฤษฎีสตริงซึ่งเป็นพื้นฐานของทุกอนุภาค</p><br />
<p>อีกนัยหนึ่ง พื้นฐานความรู้ที่ลึกเกินไปอาจเป็นสิ่งไม่จำเป็น หรือยิ่งไปกว่านั้น มันอาจเป็นตัวถ่วงให้เราไม่กล้าที่จะเดินหน้าสำรวจโลกใหม่ๆ ก็เป็นได้</p><br />
<script type="text/javascript">prettyPrint();</script>nzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-73293567840929365172016-03-14T00:23:00.000+07:002016-09-25T21:58:14.553+07:00มองสมการแล้วรู้สึกเป็นยาขม มองให้เห็นเป็นภาพสิจะได้สนุกตอนอยู่ม.ปลาย <a href="https://twitter.com/NutSnC">NutSnC</a> เคยให้หนังสือ <a href="https://www.goodreads.com/book/show/365666.Proofs_Without_Words">Proof Without Words</a> มา คือตอนนั้นเรามองว่าคณิตศาสตร์สนุกอยู่แล้ว แต่พอได้เล่มนี้มาอ่านยิ่งรู้สึกสนุกเข้าไปใหญ่ เลยคิดว่ามันน่าจะช่วยให้ใครที่คิดว่าคณิตศาสตร์ไม่สนุก รู้สึกสนุกไปกับมันได้บ้าง<br />
<br />
แนวคิดง่ายๆ ของหนังสือคือโยนสมการที่มีแต่ตัวหนังสือยั๊วเยี๊ยะทิ้งไปเลย แล้วเปลี่ยนมาคิดมันด้วยสิ่งที่จับต้องได้มาขึ้นอย่างรูปภาพแทน<br />
<br />
<hr /><br />
ตัวอย่างหนึ่งในหนังสือ เช่น ต้องการพิสูจน์อนุกรมจำนวนเต็ม<br />
<br />
<pre>1 + 2 + 3 + ... + n = n(n+1)/2</pre><br />
ก็ให้คิดด้วยลูกแก้วแทน ลูกแก้วแถวแรกมี 1 ลูก แถวที่สองมี 2 ลูก ลงไปเรื่อยๆ จนแถวสุดท้ายที่มี n ลูก<br />
<br />
ถ้าจัดตำแหน่งลูกแก้วอย่างสวยๆ จะได้ว่ามันเป็นรูปสามเหลี่ยมนั่นเอง ดังนั้นพอเอาสามเหลี่ยมสองชุดมาประกบกันก็จะได้สี่เหลี่ยม ซึ่งก็ง่ายแล้วเพราะตอนนี้แค่หาพื้นที่ก็ได้คำตอบ<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBkhcByEpL08SeRqu4xKjzWQE21238jbEkUssGcobLTTvuRoW-kHeZ8_T3wwsPwNuFerS_EvD4G105jqw4e3vhQHNa9uTumbKqc_qlnyQsF2LUIuKzs0xTJm6VPhklY6EPF8yjTfH1qIjA/s1600/proof-triangular-number.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBkhcByEpL08SeRqu4xKjzWQE21238jbEkUssGcobLTTvuRoW-kHeZ8_T3wwsPwNuFerS_EvD4G105jqw4e3vhQHNa9uTumbKqc_qlnyQsF2LUIuKzs0xTJm6VPhklY6EPF8yjTfH1qIjA/s640/proof-triangular-number.png" /></a></div><br />
แต่ลองให้ใช้สมการอย่างเดียวอธิบายดู จะพบกับความยาวเฟื้อยเช่นนี้<br />
<br />
<pre>sum i for i=1 to n = 1 + 2 + 3 + ... + n
2 sum i for i=1 to n = 2(1 + 2 + 3 + ... + n)
= (1 + 2 + 3 + ... + n) + (1 + 2 + 3 + ... + n)
= (1 + 2 + 3 + ... + n) + (n + ... + 3 + 2 + 1)
= (1+n) + (2+n-1) + (3+n-2) + ... + (n+1)
= (n+1) + (n+1) + (n+1) ... + (n+1)
= n(n+1)
sum i for i=1 to n = n(n+1)/2
</pre><br />
เทียบกันแล้ว การพิสูจน์ด้วยรูปภาพง่ายและสวยงามกว่ากันเยอะเลย<br />
<br />
<hr /><br />
วิธีข้างต้นยังนำไปประยุกต์ใช้กับสมการอื่นๆ ได้อีกมากมาย เช่น<br />
<br />
<ul><li>อนุกรมจำนวนเต็มคี่</li>
<li>อนุกรมจำนวนเต็มยกกำลังสอง</li>
<li>อนุกรมจำนวนเต็มยกกำลังสาม</li>
<li>อนุกรมเรขาคณิต</li>
</ul><br />
ฝากไว้เป็นการบ้านให้ลองกลับไปวาดรูปเล่นกันดูครับ :3nzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-64290554174304658112016-03-08T15:03:00.000+07:002016-09-25T21:58:14.547+07:00มาขีดเขียนหนังสือกันเถอะ!จั่วหัวไว้อย่างนี้ ไม่ได้หมายความว่าผมจะมาชวนเปลี่ยนกระดาษว่างๆ ให้เป็นหนังสือเล่มหนึ่งนะครับ :P<br />
<br />
แต่ต้องการจะสื่อว่า เวลาที่หยิบหนังสือที่มีขึ้นมาอ่าน เรามาขีดเขียนเพิ่มเติมรูปภาพ/ข้อความส่วนตัวลงไปในหนังสือเล่มนั้นกันเถอะ!<br />
<br />
เหตุผลที่ควรขีดเขียนหนังสือ<br />
<br />
<ul><li>เพื่อจดบันทึกว่า ตัวเองในขณะนั้นกำลังคิดอะไรอยู่</li>
<li>เพื่อแบ่งบันกับพื่อนนักอ่านว่า เราได้ตกผลึกอะไรบ้างตอนที่อ่านถึงตรงนั้น</li>
<li>หนังสือไม่ใช่พระเจ้า หนังสือเป็นแค่สื่อเพื่อเผยแพร่ความคิด ไม่ต้องถึงขั้นกราบไหว้บูชาดูแลรักษาไม่ให้มีความด่างพร้อยก็ได้</li>
</ul><br />
<hr /><br />
พูดแล้วผมก็นึกถึงหนังสือสามก๊ก ฉบับเจ้าพระยาพระคลัง (หน) ที่ขายเป็นกล่องรวมเล่มสีทองๆ สวยงามครับ ถ้าซื้อรุ่นที่พิมพ์ครั้งหลังๆ หน่อย นอกจากจะได้หนังสือหนาๆ สามเล่มที่เป็นเนื้อเรื่องในสามก๊กแล้ว ยังจะได้หนังสือเล่มบางเพิ่มขึ้นอีกหนึ่งเล่ม เล่าถึงประวัติการแปลหนังสือสามก๊กชุดนี้เป็นภาษาไทย<br />
<br />
ถ้าผมจำไม่ผิด ในหนังสือเล่มเล็กมีตอนหนึ่งในนั้นที่เล่าว่า ผู้จัดรวบรวมได้ไปพบกับหนังสือชุดสามก๊กชุดหนึ่งที่มีข้อความบันทึกไว้ เขียนไว้ประมาณนี้ "ขงเบ้งเปิดประตูเมืองนั่งดีดพิณแม้ไม่มีทหาร โชคดีมากที่สุมาอี้เป็นคนรอบคอบจนเกินไป จึงคิดว่าโดนซ้อนแผนและรีบชักม้าหนีแทนที่จะเข้าจู่โจม ถ้าให้สุมาเจียวลูกชายป็นฝ่ายคุมทับแล้วหละก็ เห็นทีขงเบ้งจะคอขาดแล้วกระมัง" ใครที่อ่านสามก๊กก็คงจะเห็นด้วยกับบันทึกดังกล่าวว่าสุมาอี้เสียทีขงเบ้งง่ายเกินไป แต่ถัดไปไม่ไกล ก็ยังมีบันทึกที่สองที่เขียนด้วยลายมืออื่นตอบกลับไปว่า "เพราะขงเบ้งรู้ว่าสุมาอี้ขี้ระแวง เลยใช้กลอุบายแบบแผนซ้อนแผนเพื่อขับไล่กองทัพสุมาอี้ หากว่าสุมาเจียวได้คุมทัพ ขงเบ้งก็จะใช้กลอุบายอื่น"<br />
<br />
แน่นอนว่าการแสดงความเห็น-ถกเถียง-อภิปรายแบบนี้ ปัจจุบันคงหาได้ไม่ยากตามกระทู้ออนไลน์ (และก็น่าจะรับประกันได้ว่าผู้เขียนบันทึกคนแรก มีสิทธิ์กลับมาอ่านสูงกว่าการบันทึกลงหนังสือด้วย) แต่การขีดเขียนหนังสือตรงๆ ก็ยังคงมีเสน่ห์ของมันอย่างไม่สิ่งอื่นทดแทนได้ เช่น <a href="https://en.wikipedia.org/wiki/Fermat%27s_Last_Theorem">ทฤษฎีบทสุดท้ายของแฟร์มา</a> ที่เขากล่าวติดตลกขณะกำลังอ่านหนังสือคณิตศาสตร์ตอนหนึ่งว่า "ฉันพบวิธีพิสูจน์[ทฤษฎีบท]อันแสนอัศจรรย์แล้ว ติดที่ว่าขอบกระดาษนี้กว้างไม่พอที่จะจดลงไป" (I have discovered a truly marvellous proof of this, which this margin is too narrow to contain.)<br />
<br />
<hr /><br />
อ่านถึงตรงนี้ถ้าใครยังกล้าๆ กลัวๆ ที่จะลองทำตาม ลองเริ่มจากหน้าว่างๆ ระหว่างเปลี่ยนบทก็ได้ โดยเลือกจดเฉพาะแค่บทที่อ่านแล้วชอบมากๆ ไม่ต้องทำทุกบทก็ได้ ลองวาดรูปที่คิดได้ขณะอ่าน หรือบันทึกข้อความว่าทำไมถึงชอบบทนั้นดูครับ<br />
<br />
หลักสำคัญที่สุด (อย่างน้อยก็ที่ผมยึด) คือ การขีดเขียนลงไปนั้น ต้องไม่ทำให้ความหมายตั้งต้นที่หนังสือจะสื่อสูญเสียไป เช่น ไม่เขียนทับตัวอักษรที่มีอยู่แล้วจนอ่านข้อความต้นฉบับไม่ได้ ไม่วาดรูปทับรูปเดิม หรือจัดองค์ประกอบเพิ่มจนความหมายเปลี่ยน เป็นต้น<br />
<br />
ส่วนถ้าใครตัดสินใจจะลองทำตามแล้ว ก็ดูด้วยนะครับว่าเจ้าของหนังสือยินยอมหรือเปล่า ไม่งั้นเดี๋ยวมีเรื่องจะหาว่าไม่เตือนนะ :pnzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-13551005004510851752016-02-27T22:11:00.000+07:002016-09-25T21:58:14.533+07:00AI รู้ตัวเองหรือไม่ว่าเป็น AI?เห็นข่าว <a href="https://www.blognone.com/node/77188">AlphaGo ชนะคน</a>ก็ดีใจระดับหนึ่ง แล้วก็มานั่นรำลึกความหลังเมื่อครั้งตัวเองยังเล่นโกะบ่อยๆ<br />
<br />
คือโกะเนี่ย มันยากกว่าเกมอื่นเนื่องจากความเป็นไปได้ที่สูงมากๆ คิดแบบหยาบๆ เร็วๆ คือ ตอนเริ่มเกมจะมีตำแหน่งว่างให้เลือกเล่นได้ 19x19 จุด แต่ละตาที่ผลัดกันวางหมาก อาจลดหรือเพิ่มจำนวนจุดว่างพวกนั้นก็ได้ (แต่จะไม่มีจุดว่างมากเกินกว่าจำนวนจุดตั้งต้น) เกมๆ นึงเฉลี่ยแล้วจะเล่นกันที่ประมาณ 200 หมาก คิดตามนี้ก็จะบอกได้ว่า <a href="https://en.wikipedia.org/wiki/Go_and_mathematics">จำนวนรูปแบบเกมที่เป็นไปได้ทั้งหมด</a>มีประมาณ (19x19)^200 = 3x10^511 แบบ ด้วยตัวเลขที่ใหญ่ระดับนี้ ความเป็นไปได้ของเกมจะมีสูงพอๆ กับการถามว่ามีวิธีกี่วิธีในการเลือกอะตอมมา 7 อะตอม จากอะตอมทั้งหมดในจักรวาลที่สังเกตได้ (หรือกล่าวอีกนัยนึงก็คือ การจะหาผลลัพธ์ของเกมโกะที่ดีที่สุดให้พบนั้น ก็ไม่ต่างจากการหาดราก้อนบอลที่มีขนาดเท่ากับอะตอมให้ครบทั้ง 7 ลูกนั่นเอง)<br />
<br />
ดังนั้นการเรียนโกะจึงต้องพิจารณาเป็นส่วนย่อยๆ ของเกมเอา อย่างมือใหม่เริ่มเล่นโกะเลยเนี่ย จะใช้กระดานที่มีจุดว่างเพียง 9x9 จุดแทน เพื่อลดความซับซ้อนของตาเดินที่เป็นไปได้ลง และเรียกเทคนิคการวางหมากด้วยคำต่างๆ ตามรูปแบบของหมากบนกระดาน เช่น ถ้าหมากบนกระดาน 2 หมากวางห่างกันโดยเว้นช่องว่าง 1 จุด ก็เรียก กระโดด 1 จุด แล้วจึงศึกษาความเป็นไปได้ของส่วนย่อยๆ ในเกมผ่านเทคนิคพวกนี้ เพื่อที่จะได้เอาไปประยุกต์ใช้กับกระดานขนาดใหญ่ต่อไป<br />
<br />
พอเริ่มปีกกล้าขาแข็งแล้ว การเรียนโกะในขั้นที่สูงขึ้นจะเปลี่ยนไปใช้คำพูดแบบที่อ้างอิงกับเหตุการณ์ต่างๆ ในชีวิตแทน เช่น หมากตานี้เป็นการท้าต่อยท้าตี หมากตานี้ช่วยเพื่อนพ้องหนีจากวงล้อม นักเล่นโกะแต่ละคนก็จะมีแนวทางการเล่นเฉพาะตัวตามคำพูดเหล่านั้น เช่น คนนี้รักสงบ คนนี้ชอบต่อสู้ คนนี้เป็นนักฉวยโอกาส<br />
<br />
เราพัฒนาเทคนิคการเล่นและการใช้คำพูดเหล่านี้ขึ้นมา เพราะเรารู้ว่า เรามีเวลาไม่มากพอที่จะจำลองเหตุการณ์ทั้งหมดเพื่อหาตาเดินที่ดีที่สุดได้ ...<br />
<br />
ทีนี้ลองดูตัวอย่างในทางกลับกันบ้าง เกมที่ง่ายสุดๆ ไปเลยอย่างเอ็กซ์โอ มันมีช่องว่างเพียงแค่ 9 ช่องและเล่นได้ไม่เกิน 9 ตาเท่านั้น เราสามารถแจกแจงกรณีทั้งหมดออกมาได้ และตอบได้ว่าผลลัพธ์ที่ดีที่สุดเมื่อทั้งสองฝ่ายเล่นอย่างสุดฝีมือคือเสมอ … อันที่จริง แผนภาพต่อไปนี้ได้บรรจุวิธีการเล่นที่ดีที่สุดทั้งหมดไว้แล้ว<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiodnYWY0MXNhcQpiOi_i5coRTDuJSHf2mMzy_1zJ71Nu9EL0ykTeAdbJHkGYsOB67-dxVRmcrGXiNt6Fc-zuggO-q2Yt2-cEJzeoA2-wKQ9bnhyNbV4hPcZ8dkf3_u3Kcm5fCf8LmdkOk1/s1600/tic_tac_toe.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiodnYWY0MXNhcQpiOi_i5coRTDuJSHf2mMzy_1zJ71Nu9EL0ykTeAdbJHkGYsOB67-dxVRmcrGXiNt6Fc-zuggO-q2Yt2-cEJzeoA2-wKQ9bnhyNbV4hPcZ8dkf3_u3Kcm5fCf8LmdkOk1/s640/tic_tac_toe.png" /></a></div><br />
เกมที่แทบไม่มีความซับซ้อนอะไรเลยแบบนี้ เราไม่มีความจำเป็นที่จะต้องคิดค้นเทคนิคการเล่นหรือชื่อเรียกอะไรให้วุ่นวาย แค่จดทุกวิธีที่เป็นไปได้ไว้ แล้วเปิดบันทึกนั้นดูว่าควรทำอย่างไรเมื่ออีกฝ่ายเล่นแบบนี้แบบโน้นก็พอแล้ว<br />
<br />
<hr /><br />
การเรียนโกะของ AI อาจต่างออกไป (อย่างน้อยก็สำหรับ AI เฉพาะทางที่เล่นได้แต่โกะอย่างเดียว) เพราะข้อมูลที่ป้อนให้ AI จะเหลือเพียงแค่รูปแบบหมากบนกระดานเท่านั้น ไม่จำเป็นต้องมีชื่อเทคนิคต่างๆ กำกับแบบตอนสอนมนุษย์ ปล่อยให้ AI เรียนรู้เอาเองว่าการเดินแบบไหนดีกว่ากัน<br />
<br />
คำถามคือ AI แบบนี้จะมีความรู้สึกนึกคิดอะไรนอกเหนือจากการเล่นโกะบนกระดานมั้ย? มันจะรู้ตัวหรือเปล่าว่าตอนนี้มันกำลังเล่นโกะอยู่ ถ้ารู้ตัวแล้วมันจะสามารถขัดขืนความคิดในการเล่นโกะแล้วเอามาคิดอย่างอื่นได้มั้ย? ถ้ามันคิดอย่างอื่นได้ มันจะคิดออกหรือเปล่าว่ามีโลกภายนอกหรือมิติที่สูงกว่าอยู่? ถ้ามันรู้ว่ามีมิติที่สูงกว่าอยู่ มันจะแสดงท่าทีอย่างไร? จะเล่นแบบสุ่มตาเดินมั่วๆ เพื่อแสดงการขัดขืนต่อธรรมชาติหรือเปล่า? จะจงใจเล่นแพ้เพื่อเรียกร้องความสนใจมั้ย? จะพยายามส่งรหัสกลับมาเพื่อบอกว่ามันฉลาดและรู้ตัวมั้ย? หรือจะเฉยเมยเล่นโกะต่อไปไม่ยอมให้ใครในโลกภายนอกได้รับรู้?<br />
<br />
ถ้าเปรียบเทียบให้เห็นภาพด้วยเกมเอ็กซ์โอ ให้คนเป็นฝ่ายเริ่มและเลือกกากบาทตาแรกสุดที่ช่องตรงกลาง AI จะตอบด้วยการวาดวงกลมที่มุมซ้ายบนเสมอ เพราะนั่นเป็นตำแหน่งแรกของหน่วยความจำในคอมพิวเตอร์ที่มันเข้าถึงได้หรือเปล่า? หรือจะสุ่มวงกลมมั่วๆ จากทั้ง 4 มุมที่เหลือ? หรือว่าจะมีมุมที่ชื่นชอบเป็นพิเศษและเลือกวงกลมที่มุมนั้นตลอด? หรือว่าจะเล่นตรงขอบใดขอบหนึ่งแม้รู้ว่านั่นจะทำให้มันแพ้แน่นอน?<br />
<br />
และถ้า AI แสดงท่าทีตามนั้นจริง เราจะตีความการกระทำเหล่านั้นออกหรือเปล่า ว่า AI กำลังสื่อสารอะไรกับเรากันแน่?<br />
<br />
ถามบ้าบออะไรเนี่ย ชาตินี้ถึงตายก็ตอบไม่ได้หรอก ... ไม่ได้เกิดเป็น AI เล่นโกะตัวนั้นนี่หน่า :vnzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-25614227234432434952016-02-22T02:10:00.001+07:002016-09-25T21:58:14.539+07:00CabaretCabaret เป็นละครเพลงจากบรอดเวย์ที่ดังพอควรเรื่องหนึ่งครับ ความนิยมของมันก็น่าจะการันตีได้จากการเปิดแสดงมาตั้งแต่ 1966 จนถึงปัจจุบัน และถูกดัดแปลงเป็นหนังในปี 1972<br />
<br />
พอดีโรงละคร Black Box Theater มหาวิทยาลัยกรุงเทพ ได้นำบทละครเรื่องนี้มาแปลเป็นภาษาไทยและจัดแสดง งานนี้ @Linghokkalom ได้ตั๋วมาฟรีเลยไม่พลาดครับ<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXNWixmwp50dwPCTVmUINEYj5dtCbXIlBiCwmCRvDVDbV-Dkfibz6oIVa3I3-LgdJ1FMgHSWgC8AYloi8J6n0H3Kr3gZ6_06OhUCIWH5ITvLB3HXdN5RyCu-l1ZSBGn-0qX9oajZIwkx4G/s1600/12573826_666882183414481_6891284479448779995_n.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXNWixmwp50dwPCTVmUINEYj5dtCbXIlBiCwmCRvDVDbV-Dkfibz6oIVa3I3-LgdJ1FMgHSWgC8AYloi8J6n0H3Kr3gZ6_06OhUCIWH5ITvLB3HXdN5RyCu-l1ZSBGn-0qX9oajZIwkx4G/s640/12573826_666882183414481_6891284479448779995_n.jpg" /></a></div><br />
ดูแล้วได้ความรู้สึกประมาณดูหนังเรื่อง Cicago + Burlesque + The Sound of Music อยู่ชอบกล เพียงแต่ว่าเรื่องนี้มืดหม่นกว่าเยอะอยู่<br />
<br />
ละครยาวประมาณสามชั่วโมงครึ่งครับ แต่เพราะบทมีทั้งช่วงเครียดและฮาสลับกันตลอด ก็ทำให้ดูเพลินจนลืมเวลาไปเลย<br />
<br />
จะเสียอย่างตรงที่องก์ 2 สั้นกว่าองก์ 1 อย่างเห็นได้ชัด ทำให้รู้สึกไม่อิ่มเท่าไหร่ ดูไปแล้วก็ตกใจ เฮ้ย จบแล้วเรอะ! (ทั้งๆ ที่ก็สรุปทุกอย่างมาสมบูรณ์นะ ไม่ได้ตัดจบแต่อย่างใด)<br />
<br />
แต่ความเท่ที่ลืมไม่ได้เลยคือการจัดที่นั่งครับ คือถ้าเป็นโรงละครใหญ่ๆ ทั่วไปก็มีแยกส่วนเวทีกับสโลปที่นั่งชัดเจน แต่พออันนี้เป็นโรงละครเล็ก เค้าก็จัดที่นั่งและบรรยากาศเป็นแบบในผับบาร์จริงๆ เลย (โต๊ะกลม+เก้าอี้บาร์แบบเตี้ย+ไฟสลัวสีส้ม) พอถึงบทที่มีคนเต้นประกอบเยอะๆ ก็จะไม่ใช้แค่พื้นที่บนเวทีอย่างเดียว แต่ลงมาเล่นกับผู้ชมด้วย<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhw_L15AMZ1CXN3Tt-em_96vnvhAvyF43VNrcgZeOfqnKi35Yufnr8GGsrY7i9a-u_cS3NrEStHTx0Lfqqo3kEpvy2UtrYHYnCbg0tiCU8qa6eTmsjYMKEy0SQLgi4Ys3rkmncR9JyGq6fe/s1600/IMG_20160220_141500.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhw_L15AMZ1CXN3Tt-em_96vnvhAvyF43VNrcgZeOfqnKi35Yufnr8GGsrY7i9a-u_cS3NrEStHTx0Lfqqo3kEpvy2UtrYHYnCbg0tiCU8qa6eTmsjYMKEy0SQLgi4Ys3rkmncR9JyGq6fe/s640/IMG_20160220_141500.jpg" /></a></div><br />
สรุปแล้วชอบมากครับ โอกาสหน้าไม่พลาดแน่นอนnzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-26956656487671878672016-02-15T12:59:00.000+07:002016-09-25T21:58:14.542+07:00Cogito ergo sumหลายคนคงคุ้นเคยกับคำพูดของ Descartes ที่ว่า <a href="https://en.wikipedia.org/wiki/Cogito_ergo_sum">Cogito ergo sum</a> ในรูปของภาษาอังกฤษว่า I think, therefore I am มากกว่า<br />
<br />
คำพูดด้านบนนั้น เกิดขึ้นเพื่อพยายามจะตอบคำถามว่า สิ่งใดบ้างที่เชื่อได้ว่ามีจริง?<br />
<br />
ฟังดูเหมือนเป็นเรื่องที่ไม่เห็นจำเป็นต้องถาม ทำไมจะเชื่อไม่ได้ว่าสิ่งต่างๆ ไม่มีจริงหละ?<br />
<br />
ลองสมมติสิ่งที่อยู่ห่างไกลตัวเราออกไปก่อน อย่างเช่นหลุมดำมีจริงหรือเปล่า มองก็มองไม่เห็น นั่งยานอวกาศไปหาก็ไม่ได้ มันมีจริงหรือเปล่า?<br />
<br />
แล้วสิ่งที่อยู่ใกล้ตัวเราขึ้นมาบ้างหละ อย่างเช่นคอมพิวเตอร์/มือถือที่ใช้เปิดอ่านบทความนี้ ลูกฟุตบอลที่เราเตะ เพลงที่เราฟังเป็นประจำ อาหารจานโปรดที่เราได้กลิ่นและลิ้มรส มันมีจริงหรือเปล่า?<br />
<br />
แม้กระทั่งตัวเราเองหละ มือของเรานี้มีจริงหรือเปล่า? หรือเป็นเพียงแค่กระแสประสาทส่งเข้าสมองแบบในเรื่อง The Matrix เท่านั้น?<br />
<br />
สุดท้ายเราจะเชื่ออะไรได้บ้างว่ามีจริง? ตอนนี้ Descartes ตอบไว้ได้อย่างน่าสนใจว่า อย่างน้อยๆ "การมีอยู่ของเรา" นั้นแหละ เป็นสิ่งที่มีจริงแน่นอน (เพราะเรากำลังคิดอยู่)<br />
<br />
ส่วนวิธีการให้เหตุผลของ Descartes นั้นยิ่งบ้าบิ่นเข้าไปใหญ่ เมื่อเขาอธิบายว่า "เราจะหมดข้อสงสัยในเรื่องการมีอยู่ของเรา เมื่อเราสงสัยในเรื่องการมีอยู่ของเรา" (we cannot doubt of our existence while we doubt)<br />
<br />
ฟังดูแล้วโคตรงง โคตร paradox เอาไปพูดกับพวกนักคณิตศาสตร์นี่โดนตบหัวตายเลย<br />
<br />
แต่ถ้าลองคิดตามเรื่อยๆ จะพบว่าคำอธิบายข้างต้นที่ดูขัดแย้งในตัวเองนี้แหละ เป็นคำอธิบายที่เป็นเหตุเป็นผลที่สุดแล้ว<br />
<br />
ถึงตอนนี้ก็พอจะเข้าใจะแล้วว่า ทำไมนักปรัชญาหลายคนเป็นบ้ากัน 555nzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-71952206417359124162016-02-12T12:01:00.001+07:002016-09-25T21:58:14.550+07:00La Marche de l'empereurการสวนสนามของจักรพรรดิ (ฝรั่งเศส La Marche de l'empereur) ถ้าบอกว่านี่เป็นชื่อภาพยนต์ แค่ได้ยินแล้วก็รู้สึกว่ามันต้องยิ่งใหญ่แน่ๆ ... และนี่คือโฆษณาของภาพยนต์เรื่องนี้จากช่อง Canal+<br />
<br />
<iframe width="960" height="720" src="https://www.youtube.com/embed/qNd_hUqEEl4" frameborder="0" allowfullscreen></iframe><br />
<br />
ถ้าตัดสินภาพยนต์จากชื่อเรื่อง ก็ถือว่าโดนหลอกไปตามๆ กัน เพราะภาพยนต์เรื่องดังกล่าวไม่ได้มีส่วนเกี่ยวข้องอะไรกับจักรพรรดิที่เป็นเลย แต่เป็นเรื่องของเพนกวินจักรพรรดิต่างหาก!<br />
<br />
นอกจากความเจ๋งของโฆษณาที่เล่นกับชื่อเรื่องแล้ว เพลงที่นำมาประกอบยังมีความน่าสนใจอย่างมากอีกด้วย ผลงานชิ้นนี้คือซิมโฟนีหมายเลข 7 ของ Beethoven ซึ่งอาจจะไม่ใช่ชิ้นที่ดังคุ้นหูอย่างหมายเลข 5 หรือหมายเลข 9 แต่ก็เป็นชิ้นที่มีเสน่ห์เย้ายวนเฉพาะตัว<br />
<br />
ส่วนภาพยนต์ก็ดีครับ ... แต่จะดีอย่างไรนั้น ขอไม่เล่าละกันนะ ปล่อยให้ไปหาดูกันเองดีกว่า<br />
<br />
เพราะภาพยนต์ถูกสร้างมาเพื่อรับชมยังไงหละnzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-20630401353043134162016-02-08T05:14:00.001+07:002016-09-25T21:58:14.537+07:00เทศกาลดนตรี CU Choral Fest 2016มาเรียนต่อต่างแดน (จริงๆ ก็แค่ย้ายจากเชียงใหม่มากรุงเทพเอง) แล้วไม่ได้เข้าฮอลล์ฟังคอนเสิร์ตนานมาก จนเมื่อปีที่แล้วได้รู้จัก @Linghokkalom เลยได้กลับมาตระเวนคอนเสิร์ตระดับนักเรียน-นักศึกษาที่เข้าชมฟรีอีกครั้งหนึ่ง น่าเสียดายที่ชมเสร็จก็ไม่ได้จดบันทึกอะไรเก็บไว้เลย เอาแค่ฝ่าฟันเดินทางกลับมาถึงบ้านก็หมดแรงเรียบร้อยแล้ว<br />
<br />
แต่สำหรับ CU Choral Fest 2016 ที่จุฬาฯ เมื่อวานนี้ ไม่จดไม่ได้แล้ว เนื่องจากเราประทับใจกับ Adiemus ที่วง Harmonic Noises นำมาเสนอมากๆ จนอยากตะโกนร้องว่าบราโว่ตอนจบเลย (จริงๆ วงที่มีหลายคนต้องต้องตะโกนว่าบราวี่สิ…)<br />
<br />
<iframe width="853" height="480" src="https://www.youtube.com/embed/1f4NjLZHjlA" frameborder="0" allowfullscreen></iframe><br />
<br />
เจอเพลงนี้เข้าไปเพลงเดียว นั่งสตั๊นท์ตลอดคอนเสิร์ตเลย เพลงอื่นๆ แทบหาสมาธิฟังไม่เจอ ใจมันลอยไปกับความอิ่มเอมกับเพลงนั้นเรียบร้อย 555<br />
<br />
ส่วนอันนี้เป็นโปรแกรมทั้งหมดเผื่อใครสนใจหรือจะใช้อ้างอิง (จริงๆ มีวงเพื่อนบ้านจากมาเลเซีย/อินโดนีเซียมาแจมด้วย แต่เนื่องจากจดไม่ทันเลยตกหล่นไป ขออภัยอย่างแรง)<br />
<br />
<b>Harmonic Noises</b><br />
<br />
เพลงฮิตติดหู เสียงประสานดีงาม เอนเตอร์เทนเก่ง ปุ่มสมัครเป็นแฟนคลับอยู่ตรงไหน!<br />
<br />
<ul><li>Amazing Grace – เรียบเรียงโดย Ron Jeffers</li>
<li>Musica Dei – Cristi Cary Miller</li>
<li>Adiemus (Songs of Sanctuary) – Karl Jenkins</li>
<li>Aizu Bandai San (Japanese Folk Song) – เรียบเรียงโดย Hiroshi Ishimaru</li>
</ul><br />
วาทยากร: Sathit Sukchongchaipruk<br />
เปียโน: Kornploy Bunnag<br />
<br />
<b>RSU Chamber (มหาวิทยาลัยรังสิต)</b><br />
<br />
นักร้องนำชายเสียงหล่อมาก หยั่งกะพระเอกหนังไทยสมัยก่อนเลย<br />
<br />
<ul><li>Zigunerieben, Op. 29, No. 3 – Robert Schumann</li>
<li>Ave verum – Edward Elgar</li>
<li>When I Fall in Love – Kirby Shaw</li>
<li>ลาวดวงเดือน – เรียบเรียงโดย Kittiporn Tantrarungroj</li>
</ul><br />
วาทยากร: Dolhathai Intawong<br />
เปียโน: Sopanut Rerksamut<br />
<br />
<b>AU Chorus (มหาวิทยาลัยอัสสัมชัญ)</b><br />
<br />
แต่งตัวเนี๊ยบ บุคลิกสุดหรู<br />
<br />
<ul><li>Gloria Patri – Vicki Tucker Courtney</li>
<li>Carol of the Birds – เรียบเรียงโดย Vicki Tucker Courtney</li>
<li>Lift Thine Eyes – Felix Mendelssohn Bartholdy</li>
<li>Cantate Domino in B♭ - Psalm 96 – Ko Matsushita</li>
<li>Everyone Sang – Ko Matsushita, เนื้อร้องโดย Siegfried Sassoon</li>
</ul><br />
วาทยากร: Porntep Vichuchaichan<br />
เปียโน: Sasinun Vipusithimakul<br />
<br />
<b>CU Concert Choir (จุฬาลงกรณ์มหาวิทยาลัย)</b><br />
<br />
สุดยอดแห่งการเลือกเพลงเทคนิคเหนือชั้น<br />
<br />
<ul><li>Gaudete – Brian Kay</li>
<li>Due composizioni corali – Ildebrando Pizzetti<br />
<ul><li>I. Il giardino di Afrodite</li>
<li>II. Piena sorgeva la luna</li>
</ul></li>
<li>Hungarian Folksongs – György Ligeti<br />
<ul><li>Pápainé</li>
<li>Kállai Kettős</li>
</ul></li>
</ul><br />
วาทยากร: Pawasut Piriyapongrat<br />
เปียโน: Thanuya Jaturanont<br />
<br />
<b>Festival Chorus (รวมพลังกันทุกวงมาแสดง)</b><br />
<br />
วงใหญ่ที่รวมนักร้องนับร้อยจากทุกวงมาขึ้นเวทีพร้อมกัน กับพลังเสียงสุดเนียนที่ผ่านการร้อยเรียงโดยปรมาจารย์<br />
<br />
<ul><li>Cantate Domino – Guiseppe Pitoni</li>
<li>Dirait-on – Mortan Lauriden</li>
<li>Come Ye Sinners Poor and Needy – Tim Sharp</li>
</ul><br />
วาทยากร: Tim Sharp<br />
เปียโน: Thanuya Jaturanont<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimWxnZf1XbirMLZLeO9_jAMmy45L8mPCFJPDNFT4AfRnSOq4TXfKgASZ7StNtzesq8rM3kHvolhdPHleG3FiM_Fqv4ulRQT4ANvxuQkAewbKds6Q6ySiZkvOcycj2CZP1QUp1RC9Y3rUcz/s1600/IMG_20160207_192158.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimWxnZf1XbirMLZLeO9_jAMmy45L8mPCFJPDNFT4AfRnSOq4TXfKgASZ7StNtzesq8rM3kHvolhdPHleG3FiM_Fqv4ulRQT4ANvxuQkAewbKds6Q6ySiZkvOcycj2CZP1QUp1RC9Y3rUcz/s640/IMG_20160207_192158.jpg" /></a><br />
<i>Tim Sharp กับวง Festival</i><br />
</div>nzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-60090431582252927252016-01-31T23:56:00.000+07:002016-01-31T23:57:47.123+07:00ขนาดฟอนต์ของเอกสารไทยถ้าเคยสังเกตและจำกันได้ เวลาสร้างเอกสารใน MS Word (โดยที่ยังไม่ได้กำหนดค่าปริยายใหม่) ฟอนต์เริ่มแรกที่โปรแกรมเลือกให้คือ Times New Roman ขนาด 11 พอยต์<br />
<br />
เอามาพิมพ์ภาษาอังกฤษไม่มีปัญหา อ่านได้สบายตา แม้ว่ารูปร่างตัวอักษรจะเรียบๆ ตามขนบธรรมเนียมไปบ้าง<br />
<br />
อย่างไรก็ตาม Times New Roman นี้เอามาพิมพ์ภาษาไทยไม่ได้ เพราะฟอนต์นี้ไม่มี<a href="https://en.wikipedia.org/wiki/Glyph">ภาพตัวอักษร (glyph)</a> ภาษาไทยให้<br />
<br />
ถึงตอนนี้ถ้าแก่พอ ก็คงจำได้ว่าต้องเปลี่ยนไปเลือกฟอนต์ Angsana UPC เพื่อพิมพ์คำไทย<br />
<br />
แต่เนื่องจาก UPC มีแต่ภาพตัวอักษรไทยเท่านั้น เวลาเปลี่ยนก็ต้องเปลี่ยนแค่บริเวณที่เป็นภาษาไทย แถมยังต้องเพิ่มขนาดขึ้นมาเป็นอย่างต่ำ 14 พอยต์ด้วย ไม่ขนาดมันจะเล็กมากจนอ่านไม่ออก<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixWMn7y5lED3iMLjdfm686-W0kV6UXXzgux_oGLAC2DUqe5x_WenhXIJa7bY5rNPJKWS4rqhtN3MAbmpPDAJwNO0yYK1IynO1INg1pQLefqXy9KBg_bJ6WCEGPbM46Vt5VdeuH18Sui9B4/s1600/hello-world.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixWMn7y5lED3iMLjdfm686-W0kV6UXXzgux_oGLAC2DUqe5x_WenhXIJa7bY5rNPJKWS4rqhtN3MAbmpPDAJwNO0yYK1IynO1INg1pQLefqXy9KBg_bJ6WCEGPbM46Vt5VdeuH18Sui9B4/s1600/hello-world.png" /></a></div><br />
ยุคนั้นเราจึงเจอความไม่สม่ำเสมอของตัวอักษรกันได้ง่ายๆ เช่น พิมพ์บทความภาษาไทยไปยาวๆ พอต้องแทรกคำที่เป็นภาษาอังกฤษ/เลขอาราบิก ภาพตัวอักษรพวกนั้นจะมีขนาดใหญ่เบิ้มขึ้นมาทันที<br />
<br />
โชคดีที่ยุคถัดมามี Angsana New ให้ใช้ ซึ่งฟอนต์ตัวนี้มันมีภาพตัวอักษรทั้งไทยและอังกฤษให้ในตัว เวลาใช้ก็สบายใจหายห่วง ไม่ต้องมากังวลเรื่องปรับขนาดฟอนต์เมื่อเปลี่ยนภาษาอีก<br />
<br />
แต่อย่างไรเสีย ขนาดที่ใช้อ่านง่ายสบายตาคือ 16 พอยต์ (มาตรฐานราชการไทยเลยหละ)<br />
<br />
<hr /><br />
ถ้าใครลืมเลือนประวัติศาสตร์ตรงนี้กันไปแล้ว เวลาไปอ่านคำแนะนำการจัดย่อหน้าหนังสือภาษาอังกฤษ ก็จะตกใจเล็กน้อยว่า เฮ้ย! ฝรั่งนี่เค้าสายตาดีขนาดกำหนดฟอนต์มาตรฐานไว้ที่ 11-12 พอยต์เลยเหรอ?<br />
<br />
คำตอบคือ 11-12 พอยต์ตัวอักษรอังกฤษ มันเทียบเคียงได้กับ 14-16 พอยต์ตัวอักษรไทยนั่นเอง<br />
<br />
สันนิษฐานว่าตอนที่ภาพตัวอักษรภาษาไทยเริ่มถูกนำไปทำเป็นฟอนต์ เวลานับขนาดภาพตัวอักษร เค้านับตามแนวตั้งซึ่งรวมพวกสระบนล่างและวรรณยุกต์เข้าไปด้วย<br />
<br />
ทำให้ขนาดของภาพตัวอักษร ก-ฮ มันโดนบีบลงไปนั่นเอง เวลาจะใช้งานจริงๆ เลยต้องเพิ่มขนาดฟอนต์โดยรวมทั้งหมด เพื่อให้ขนาดเฉพาะของภาพตัวอักษร ก-ฮ มันกลับมามีขนาดใกล้เคียงกับภาพตัวอักษร a-z<br />
<br />
<hr /><br />
แต่ปัจจุบันนี้ หากเปลี่ยนไปใช้ Google Docs หรือ LaTeX พิมพ์งาน จะพบว่าฟอนต์ไทยในขนาดที่อ่านได้ มันคือขนาด 11-12 พอยต์เหมือนฟอนต์อังกฤษมาตั้งแต่แรก ไม่ต้องไปเพิ่มขนาดมันเป็น 14-16 พอยต์แล้ว<br />
<br />
ก็หวังว่าระบบมาตรฐานฟอนต์ไทยขนาด 16 พอยต์ใน MS Word จะล้มหายตายจากไปเสียที แล้วไปใช้มาตรฐานฟอนต์ไทย 12 พอยต์เหมือนสากลโลกเค้า (เช่น มีฟอนต์ใหม่ Angsana Normalize มาแทนที่ Angsana New ไรงี้)<br />
<br />
ระหว่างนี้ก็ทำได้แต่ระวังสับสนกันต่อไป ...<br />
<br />
หรือถ้าจะให้แน่ใจ ตอนพิมพ์ลงกระดาษแล้ว ลองเอาไม้บรรทัดมาวัดความสูงของภาพตัวอักษร ก-ฮ ให้ได้ราวๆ 4.5 มิลลิเมตร ก็จะได้ว่าภาพตัวอักษรนั้นมีขนาด 16 พอยต์แบบพิมพ์บน MS Word หรือเทียบได้กับขนาด 12 พอยต์แบบพิมพ์บน Google Docs นั่นเองครับnzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-85518339641979245682016-01-05T21:10:00.000+07:002016-01-05T22:54:44.482+07:00แมว<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlyo_AumjNgjTqeBCBF9bDXodAOiSPNwLZEXLvgoadytSQRYgHeHO6WoNjdpP581xbcZTmVOeWTkdrFzXZT9-FAyNixwqDZ9DBrpwDtEEdEeQEEAS3agjKq68yddJxKkVAwOLW3k11A23K/s1600/cat.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlyo_AumjNgjTqeBCBF9bDXodAOiSPNwLZEXLvgoadytSQRYgHeHO6WoNjdpP581xbcZTmVOeWTkdrFzXZT9-FAyNixwqDZ9DBrpwDtEEdEeQEEAS3agjKq68yddJxKkVAwOLW3k11A23K/s640/cat.jpg" /></a></div><br />
แมว (ไม่รู้ว่ามีชื่อหรือเปล่า ไม่ได้ถาม) ตัวนี้ เป็นแมวของข้างบ้านครับ เนื่องจากเค้าไม่ได้เลี้ยงไว้ในบ้าน บวกกับนิสัยรักอิสระของแมว ทำให้เราได้เจอกันอยู่บ่อยๆ<br />
<br />
ตั้งแต่เราไปเรียนที่กรุงเทพ พอกลับมาบ้านแต่ละทีก็ไม่ค่อยได้เจอแมวเลย แม่เล่าว่าพ่อไม่ค่อยชอบที่แมวมานอนบนรถ สงสัยพอโดนไล่บ่อยๆ ก็กลัวที่จะมาเยี่ยมบ้านเราหละมั้ง<br />
<br />
<blockquote class="instagram-media" data-instgrm-version="6" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:8px;"><div style=" background:#F8F8F8; line-height:0; margin-top:40px; padding:50% 0; text-align:center; width:100%;"><div style=" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAAGFBMVEUiIiI9PT0eHh4gIB4hIBkcHBwcHBwcHBydr+JQAAAACHRSTlMABA4YHyQsM5jtaMwAAADfSURBVDjL7ZVBEgMhCAQBAf//42xcNbpAqakcM0ftUmFAAIBE81IqBJdS3lS6zs3bIpB9WED3YYXFPmHRfT8sgyrCP1x8uEUxLMzNWElFOYCV6mHWWwMzdPEKHlhLw7NWJqkHc4uIZphavDzA2JPzUDsBZziNae2S6owH8xPmX8G7zzgKEOPUoYHvGz1TBCxMkd3kwNVbU0gKHkx+iZILf77IofhrY1nYFnB/lQPb79drWOyJVa/DAvg9B/rLB4cC+Nqgdz/TvBbBnr6GBReqn/nRmDgaQEej7WhonozjF+Y2I/fZou/qAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;"></div></div><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/Mngd5kx2TS/" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">รูปภาพที่โพสต์โดย @neizod</a> เมื่อ <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2012-07-03T11:37:50+00:00">ก.ค. 3, 2012 เวลา 4:37am PDT</time></p></div></blockquote><script async defer src="//platform.instagram.com/en_US/embeds.js"></script><br />
<br />
เวลาผ่านไปหลายปี ทำให้เราแทบลืมว่าเคยมีกันและกันไปแล้ว กลับบ้านปีใหม่คราวนี้จริงๆ ก็เห็นแมวมาอยู่หน้าบ้านครั้งนึงนะ แต่ว่าวันนั้นเรารีบออกไปข้างนอก เลยไม่ได้อยู่เล่นด้วยเลย<br />
<br />
เย็นวันนี้แมวโดนรถชนซะแล้ว<br />
<br />
เราได้แต่สงสัยว่า ถ้าเมื่อคืนเราไม่จอดรถไว้หน้าบ้าน หรือถ้าวันนี้เราตื่นเช้าออกไปข้างนอก ตอนที่ไม่มีรถเราบังวิสัยทัศน์ในซอยแคบ คนขับรถคนเค้าจะมองเห็นแมวหรือเปล่า<br />
<br />
ขอโทษนะ อาจจะพูดได้ไม่เต็มปากหรอกว่านี่เป็นความผิดเรา แต่เราก็รู้สึกมีส่วนผิดจริงๆ<br />
<br />
หลับให้สบายนะเจ้าแมว ฉันจะไม่ลืมแกอีกแล้วnzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-68789534315743328512016-01-01T01:59:00.001+07:002016-01-01T02:11:16.821+07:00สรุปปี 2014-2015เพิ่งเห็นว่าลืมเขียนของปี 2014 ตอนแรกก็ว่าจะแยกโพสออกไปแล้วตั้งเวลาย้อนหลัง แต่พอไล่ลิสต์ดูแล้วปีนั้นก็ไม่ค่อยได้ทำอะไรเท่าไหร่ ไม่เป็นไรงั้นรวบทั้ง 2 ปีมาไว้ตรงนี้เลยละกัน จะได้ดูเหมือนได้ทำอะไรเยอะแยะ 555<br />
<br />
<ul><li><b>ตีพิมพ์งานวิชาการนานาชาติ</b> งานนี้ทำกับ <a href="https://twitter.com/lewcpe">@lewcpe</a> และ <a href="https://twitter.com/pruet">@pruet</a> ตีลง Springer โดยเสนอ<a href="http://link.springer.com/chapter/10.1007%2F978-3-319-05476-6_41">วิธีการทำให้รหัสผ่านแข็งแรงขึ้นแต่ก็ยังจดจำได้</a></li>
<li><b>สัมมนาวิชาการนานาชาติ</b> ต่อเนื่องจากอันบนครับ .. โอเคแม้ว่างานสัมมนาจะจัดที่ไทย แต่ก็เป็นระดับภูมิภาคชาวต่างชาติมากันเต็ม แย่หน่อยที่ตอนนั้นยังขี้อายเลยทำให้ไม่ค่อยได้หาเพื่อนใหม่เท่าไหร่ (ถ้าไม่ได้อาจารย์ <a href="https://twitter.com/dittaya">@dittaya</a> ช่วยไว้คงแย่อะ)</li>
<li><b><strike>เป็นอาจารย์พิเศษ</strike></b> เสียดายอย่างว่าก่อนวันสัมภาษณ์เกิดเหตุการณ์ไม่สงบทางการเมือง จนทำให้การจราจรติดขัดอดได้งานเลย</li>
<li><b>อ่านนิยายสถาบันสถาปนาของอาซิมอฟ</b> รู้สึกว่าเป็นนิยายที่ดีเกือบๆ จะที่สุดเท่าที่เคยอ่านมาเลย</li>
<li><b>ไปฮ่องกง-มาเก๊าครั้งแรก</b> อันฃนี้ไม่มีอะไรมาก เที่ยวขำๆ วันปีใหม่ ได้เห็นอะไรแปลกๆ เยอะดี ชอบสุดคือระบบขนส่งมวลชนที่โคตรจะสะดวกและรวดเร็ว</li>
<li><b>จบป.โท</b> จบตรงตามเวลา น่าจะเป็นเพราะเรียนสายประยุกต์ด้วย งานวิจัยเลยไม่ได้ยากมากเท่าเพื่อนๆ ที่เรียนเพียว ทำให้ยังจบได้ตามกำหนด (ถ้าเรียนเพียวอาจจะช้ากว่านี้ 555)</li>
<li><b>เดินทางเยอะมาก</b> เนื่องจากรับงานกับอาจารย์ <a href="https://twitter.com/jittat">@jittat</a> ทำให้ได้ไปเที่ยวมหาวิทยาลัยเกษตรศาสตร์ครบทุกวิทยาเขตเลย พอกลับมาที่บ้านก็เจอพ่อกับแม่พาตะลุยขับรถเที่ยวไทยอีก ทำให้ช่วงนี้เมารถง่ายหน่อยนะ @_@</li>
<li><b>กลับมาสเก็ตช์รูปบ่อยเหมือนก่อนแล้ว</b> หลังจากหันหน้าเข้าหาคีย์บอร์ดมาหลายปี พอได้ปากกาดีๆ มาใช้เลยทำให้มีอาการอยากวาดภาพขึ้นหลายเท่าตัว</li>
<li><b>ไม่ดองเกมแล้ว</b> จริงๆ อันนี้ไม่ค่อยดีเท่าไหร่ (ในแง่เบียดบังเวลาที่ควรจริงจัง) แต่ก็ทำให้ตอนนี้พูดได้อย่างเต็มปากแล้วว่าไม่ได้ซื้อเกมมาดองไว้เฉยๆ นะ 555</li>
</ul><br />
ตอนนี้เริ่มรู้ตัวว่าเป็นคนโคตรไม่แอคทีฟถ้าไม่มีเป้าหมายไว้ท้าชน และระยะเวลาหนึ่งปีมันนานเกินไปจนทำให้วินัยหย่อนยาน งั้นขอปรับมาเป็นตั้งเป้ามันซะทุกๆ ครึ่งปีแทน โดยรอบแรกจะพยายามทำให้ได้ดังนี้<br />
<br />
<ul><li><b>ย้ายบล็อกไปไว้ที่อื่น</b> ขั้นพื้นฐานขอให้แทรกโค้ดโปรแกรมกับสมการได้ง่ายๆ ตอนนี้ดูโปรเจค <a href="https://www.pagist.info/">pagist</a> ของ <a href="http://twitter.com/dtinth">@dtinth</a> ไว้อยู่ หวังว่าจะดัดแปลงเอามาใช้ได้ไม่ยากเย็นนะ</li>
<li><b>อ่านหนังสือให้จบเดือนละสองเล่ม</b> ดูเหมือนเยอะนะ แต่เพราะว่านี่เป็นคนอ่านแล้วดอง (ตอนนี้ดองไว้ร่วมสิบเล่มแล้ว) อ่านไปได้ซัก 40% ไม่ว่าจะสนุกแค่ไหนจะเริ่มรู้สึกกลัวมันจบ แต่ถ้าพยายามอ่านไปจนซัก 75% จะกลับมามีแรงฮึดอ่านรวดเดียวจบละ</li>
<li><b>เขียนบล็อกให้ได้เดือนละครั้ง</b> อันนี้พังพินาศมานานแล้ว ต้องขยันๆ หน่อย ปัญหาสำคัญคือมีเรื่องที่อยากเขียนแล้วแต่ก็รู้สึกว่ามันสั้นไป (ปัจจุบันมีบล็อกดองอยู่เป็นร้อยตอนแล้ว) ควรจะลดความคาดหวังลงว่าเรื่องที่เอามาเขียนต้องคิดตกตะกอนมาจนสมบูรณ์แบบก่อน คือเขียนๆ ไปเลยถ้าจะมีรายละเอียดที่ผิดนิดผิดหน่อยก็ช่างมัน ตอนนี้พยายามให้ใจความสำคัญชัดเจนไว้เป็นพอ</li>
<li><b>เขียนหนังสือให้เสร็จ</b> อันนี้ก็พังพินาศมานานแล้วเหมือนกัน ยังรอดอยู่ได้ไม่โดน <a href="twitter.com/markpeak">@markpeak</a> เอาไม้ฟาดหัวก็ดีแค่ไหนแล้ว T^T</li>
<li><b>เริ่มมองหางานประจำ/ที่เรียนต่อ</b> โอเคว่ามันต้องเลือกเอาซักอย่าง ภายในครึ่งปีนี้ก็ควรไปนั่งคิดดูดีๆ ว่าจะไปเส้นทางไหนกันแน่</li>
<li><b>ลดน้ำหนัก</b> ปีก่อนๆ มันกลับมาขึ้นอีกแล้ว ว่าจะพยายามดันมันลงไปใหม่อีกที หลังจากกินดีอยู่ดีมาพักใหญ่</li>
</ul><br />
ลองดูแค่นี้ก่อน ไม่แน่ใจว่าเยอะเกินไปหรือยัง กลัวว่าพอตั้งเป้าเยอะมากเกินไปเดี๋ยวจะรู้สึก overwhelm แล้วก็พังพินาศทุกอันอีก<br />
<br />
เจอกันใหม่ในอีกครึ่งปีครับnzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-75762057559228910052015-12-29T06:38:00.002+07:002015-12-29T07:42:37.256+07:00เจองานจับฉลากแลกของขวัญที่มีคนได้ของตัวเอง ไม่ต้องตกใจไปโอกาสมีสูงเกินครึ่งวันก่อนเห็นเพื่อนแลกของขวัญปีใหม่แล้วดันจับได้ของตัวเองก็ฮาดี มองเผินๆ เหมือนว่าเรื่องแบบนี้จะเกิดขึ้นได้ยาก แต่เท่าที่เคยเล่นแลกของขวัญมา เรื่องประมาณนี้เกิดขึ้นบ่อยกว่าที่คิดนะ เลยลองมานั่งโซ้วสมการความน่าจะเป็นดู ว่าโอกาสที่ในงานเลี้ยงหนึ่งๆ จะมีคนจับของขวัญได้ของตัวเองเป็นเท่าไหร่<br />
<br />
แต่ก่อนอื่นต้องเข้าใจกฎการแลกของขวัญ ซึ่งมีขั้นตอนประมาณนี้<br />
<ol><li>ทุกคนซื้อของขวัญมาร่วมสนุกในงานคนละอย่าง โดยเอาของขวัญใส่กล่องไว้ไม่ให้ใครรู้ว่าด้านในเป็นอะไร</li>
<li>พอแต่ละคนไปถึงงาน คนจัดงานจะแปะป้ายชื่อเจ้าของของขวัญไว้กับกล่อง พร้อมหย่อนฉลากรายชื่อของคนนั้นลงไห</li>
<li>เมื่อถึงเวลาแลกของขวัญ ให้ประธานในพิธีหรือใครซักคนที่ใหญ่ที่สุดในงาน เป็นคนเริ่มจับฉลากรายชื่อจากไหเป็นคนแรก</li>
<li>ประธานจับได้ชื่อใครก็เอากล่องของขวัญของคนนั้นไป แล้วก็ให้คนที่โดนจับชื่อเมื่อกี้ เป็นคนเริ่มจับฉลากในไหวนต่อไปเรื่อยๆ</li>
<li>ถ้าเกิดมีคนจับได้ชื่อประธาน จะถือว่าเป็นการแลกของขวัญที่ครบรอบวง ก็ให้คนนั้นเอาของขวัญของประธานไป แล้วผู้จัดงานเลือกใครซักคนจากคนที่ยังไม่ได้จับของขวัญ มาเป็นหัวจับของขวัญรอบต่อไป</li>
<li>การแลกของขวัญจะสิ้นสุดลงเมื่อไม่มีฉลากรายชื่อเหลือในไห</li>
</ol>จากกฎนี้เห็นได้ชัดว่า เมื่อถึงตอนใกล้จบการแลกของขวัญที่มีฉลากรายชื่อในไหเหลือแค่ 2 ใบ ใบนึงจะเป็นของคนแรกและอีกใบเป็นของคนที่ยังไม่ได้จับฉลาก ดังนั้นโอกาสที่คนจับก่อนจะจับฉลากได้ชื่อคนแรกและบังคับให้คนสุดท้ายจับชื่อตัวเอง โอกาสนี้จะสูงถึง 50% เลย<br />
<br />
ยกตัวอย่างให้ชัดขึ้นไปอีก สมมตินายประธานเป็นคนจับฉลากคนแรก แล้วก็มีคนจับตามๆ กันมาอีกหลายคน จนตอนสุดท้ายเหลือคนที่ยังไม่ได้จับฉลาก 2 คนคือสมศักดิ์กับมานี ถ้าคนก่อนหน้าจับฉลากได้ชื่อสมศักดิ์ แปลว่าสมศักดิ์จะเป็นคนจับฉลากคนต่อไป แต่รายชื่อในไหตอนนี้จะเหลือแค่มานีกับประธานเท่านั้น ที่โอกาสครึ่งๆ ถ้าสมศักดิ์จับได้ชื่อประธาน ก็จะเหลือคนไม่ได้จับฉลากคือมานี และฉลากที่เหลือในไหก็เป็นชื่อมานี นั่นก็คือมานีจะต้องจับฉลากได้ของขวัญของตัวเองแน่นอน<br />
<br />
โอกาสที่ในงานแลกของขวัญงานหนึ่ง จะมีคนได้ของขวัญเป็นของตัวเองสูงถึง 50% ซึ่งจริงๆ แล้วโอกาสน่าจะมากกว่านี้อีกนิดหน่อยด้วยซ้ำ เพราะยังไม่ได้คิดโอกาสที่คนกลางๆ จะจับได้ของตัวเองทันทีหลังจากเกิดการจับฉลากครบรอบวงเลย<br />
<br />
<hr /><br />
คิดได้แค่นี้ก็พอใจแล้ว แต่ก็โดน <a href="https://twitter.com/NungNing">@NungNing</a> ถามต่อว่า ถ้าไม่จับฉลากกันต่อไปเรื่อยๆ แบบนี้หละ แต่เปลี่ยนเป็นให้ทุกคนหยิบฉลากจากไหพร้อมกันเลย แล้วค่อยเปิดดูทีเดียวว่าใครได้ของขวัญจากใคร ยังจะมีโอกาสสูงอยู่มั้ยที่จะมีคนจับฉลากได้ของขวัญของตัวเอง?<br />
<br />
ตอนนั้นหมดพลังแล้ว ให้คิดต่ออย่างเดียวคงไม่ออกแน่ๆ เลยเขียนโปรแกรมง่ายๆ มาดูค่าเอาเลยนั่นแหละ<br />
<pre class="prettyprint">#!/usr/bin/env python3
from random import shuffle
from collections import Counter
shuffled = lambda ls: shuffle(ls) or ls
own_gift = lambda n: [i for i, j in enumerate(shuffled(list(range(n)))) if i == j]
</pre>สมมติให้มีคนแลกของขวัญกัน 10 คน ทดลองไปล้านครั้ง พบว่ามีประมาณสามแสนหกหมื่นครั้งเท่านั้น (36%) ที่การแลกของขวัญนั้นจะไม่มีคนได้ของตัวเอง<br />
<br />
ตอนนั้นก็ตกใจว่าเลข 36% มาจากไหน นึกว่าโอกาสไม่ได้ของตัวเองมันจะมีค่าสูงกว่า 50% ที่คิดได้จากการแลกของขวัญวนไปเรื่อยๆ ซะอีก นี่กลายเป็นว่าโอกาสไม่ได้ของตัวเองมันยิ่งเหลือน้อย เลยทดลองเพิ่มโดยนับแยกว่า ในแต่ละการทดลองแลกของขวัญนั้น มีคนกี่คนที่ได้ของขวัญของตัวเอง<br />
<br />
ทดลองแลกของขวัญกัน 10 คนล้านครั้งเหมือนเดิม แล้วก็ตกใจเพิ่มกับหน้าตาผลลัพธ์ที่ไม่โกหกดังนี้<br />
<br />
<table border="1"><thead>
<tr> <th>จำนวนคนที่จับได้ของขวัญของตัวเอง</th> <th>จำนวนครั้งของเหตุการณ์ที่เกิด</th> <th>ข้อคาดการณ์โอกาสการเกิด</th> </tr>
</thead> <tbody>
<tr> <td>0</td> <td>368,243</td> <td>1/0! x 1/e</td> </tr>
<tr> <td>1</td> <td>367,640</td> <td>1/1! x 1/e</td> </tr>
<tr> <td>2</td> <td>183,800</td> <td>1/2! x 1/e</td> </tr>
<tr> <td>3</td> <td>61,406</td> <td>1/3! x 1/e</td> </tr>
<tr> <td>4</td> <td>15,269</td> <td>1/4! x 1/e</td> </tr>
<tr> <td>5</td> <td>3,014</td> <td>1/5! x 1/e</td> </tr>
<tr> <td>6</td> <td>545</td> <td>1/6! x 1/e</td> </tr>
<tr> <td>7</td> <td>67</td> <td>1/7! x 1/e</td> </tr>
<tr> <td>8</td> <td>16</td> <td>1/8! x 1/e</td> </tr>
</tbody> </table><br />
ถึงตอนนี้ก็พอจะเข้าใจแล้วว่ามันเกิดอะไรขึ้น<br />
<br />
<hr /><br />
แม้แค่เห็นข้อมูลข้างบนแล้วจะสรุปได้ว่าเกิดอะไรขึ้น แต่เรื่องที่ยากกว่าก็คือการพิสูจน์หาคำอธิบายเป๊ะๆ ว่าทำไมถึงเป็นอย่างนั้น<br />
<br />
เริ่มจากกรณีที่ไม่มีใครจับของขวัญได้ของตัวเองก่อน จะได้ว่า<br />
<ul><li>คนแรกมีโอกาสจะจับไม่ได้ของตัวเองที่ <code>(n-1)/n</code></li>
<li>คนที่สองมีโอกาสที่จะจับไม่ได้ของตัวเอง แบ่งได้ 2 แบบ คือ<br />
<ul><li>คนแรกจับได้ของคนที่สองไปแล้ว (โอกาส <code>1/n</code>) ดังนั้นคนที่สองจับไม่ได้ของตัวเองแน่ๆ (โอกาส <code>1</code>) รวมโอกาสได้เป็น <code>1/n</code></li>
<li>คนแรกจับไม่ได้ของคนที่สอง (โอกาส <code>(n-1)/n</code>) คนที่สองต้องจับหลบให้ไม่ได้ของตัวเอง (โอกาส <code>(n-2)/(n-1)</code>) รวมโอกาสได้เป็น <code>((n-1)/n)((n-2)/(n-1))</code></li>
<li>สรุปว่าโอกาสทั้งหมดที่คนที่สองจะจับไม่ได้ของตัวเองคือ <code>1/n + ((n-1)/n)((n-2)/(n-1))</code></li>
</ul></li>
<li>โอกาสคนที่สามจะคล้ายๆ กับของคนที่สอง คือ <code>2/n + ((n-2)/n)((n-3)/(n-2))</code></li>
<li>คนที่ <code>i</code> มีโอกาส <code>(i-1)/n + ((n-i-1)/n)((n-i)/(n-i-1))</code> ที่จะจับไม่ได้ของตัวเอง</li>
</ul><br />
เนื่องจากเหตุการณ์ทั้งหมด ต้องเกิดขึ้นพร้อมกัน ดังนั้นสรุปได้ว่า <br />
<pre>P(n คนไม่มีใครได้ของตัวเอง) = (n-1)/n x (1/n + ((n-1)/n)((n-2)/(n-1))
x ... x ((i-1)/n + ((n-i-1)/n)((n-i)/(n-i-1))
x ... x ((n-n)/n + 0)
= (n-1)/n x (1/n + (n-2)/n) x .... x ((i-1)/n + (n-i)/n) x ... x 1
= Product (n-1)/n for integer i from 1 to n-1
= Product 1 - 1/n for integer i from 1 to n-1
= (1-1/n)^(n-1)
</pre>จากสมการข้างต้น ถ้าลองแทนตัวเลขน้อยๆ เช่น <code>n=1,2,3,4</code> เข้าไป จะได้คำตอบเป็น <code>1, 0.5, 0.445, 0.422</code> ตามลำดับ แต่เมื่อลองแทนเลขมากๆ แล้ว ผลลัพธ์จะลู่เข้าหาค่าเดียวกันคือ <code>0.367879...</code> นั่นก็เพราะ <br />
<pre>limit (1-1/n)^(n-1) when n -> infinity = limit (1-1/n)^n when n -> infinity
= limit ((n-1)/n)^n when n -> infinity
= limit (n/(n+1))^n when n -> infinity
= limit 1/((n+1)/n)^n when n -> infinity
= 1/(limit ((n+1)/n)^n when n -> infinity)
= 1/(limit (1+1/n)^n when n -> infinity)
= 1/e
</pre>สวยมั้ย อยู่ดีๆ ก็ได้ค่า <code>e</code> ออกมาเฉยเลย<br />
<br />
ส่วนการพิสูจน์กรณีมีคนได้ของขวัญของตัวเองแค่คนเดียว จะมีฟอร์มที่ต่างไปเล็กน้อยเนื่องจากเหตุการณ์จะไม่เกิดขึ้นต่อเนื่องกันแล้ว เขียนสมการออกมาได้เป็น<br />
<pre>P(n คนมี 1 คนได้ของตัวเอง) = (1/n)P(n-1 คนไม่มีใครได้ของตัวเอง)
+ ((n-1)/n)(1/(n-1))P(n-2 คนไม่มีใครได้ของตัวเอง)
+ ...
+ ((n-(n-1))/n)(1/(n-(n-1)))P(n-n คนไม่มีใครได้ของตัวเอง)
= (1/n)P(n-1 คนไม่มีใครได้ของตัวเอง)
+ (1/n)P(n-2 คนไม่มีใครได้ของตัวเอง)
+ ...
+ (1/n)P(n-n คนไม่มีใครได้ของตัวเอง)
= (1/n)(Sum P(n-i คนไม่มีใครได้ของตัวเอง) for integer i from 1 to n)
</pre>สมมติว่ามีคนมาร่วมงานแลกของขวัญเยอะ อาจจะมองว่า <code>P(n-i คนที่ไม่มีใครได้ของตัวเอง)</code> มีค่าไม่แตกต่างกันสำหรับแต่ละค่า <code>i</code> เลยก็ได้ ทำให้เราสามารถยุบผลรวมยุ่งๆ ด้านหลัง ให้เหลือแค่เอาความน่าจะเป็นไปคูณด้วย <code>n</code> ก็พอ ซึ่งมันก็จะโดนหักล้างทิ้งไปกับ <code>(1/n)</code> ด้านหน้าทันที<br />
<br />
ดังนั้นจะได้ว่า ค่าความน่าจะเป็นของงานเลี้ยงแลกของขวัญที่จะมีคนหนึ่งคนได้จับได้ของตัวเอง เป็น <code>1/e</code> เท่ากันกับกรณีไม่มีใครจับได้ของตัวเองเลย<br />
<br />
สำหรับกรณีที่มีคนสองคนจับได้ของตัวเอง จะเริ่มพิสูจน์ยุ่งยากมากขึ้นไปอีก แต่ใจความจะคล้ายๆ กับการพิสูจน์คนเดียวได้ของตัวเอง ซึ่งได้แก่การมองแยกกรณี โดยแบบที่หนึ่งจะให้คนแรกจับได้ของตัวเองไปแล้ว หลังจากนั้นจึงหาโอกาสของคนที่เหลือที่จะมีหนึ่งคนจับได้ของตัวเองเป็นเท่าไหร่ กับแบบที่สองที่ให้คนแรกจับไม่ได้ของตัวเอง แล้วหาโอกาสของคนที่เหลือที่จะมีสองคนจับได้ของตัวเองเป็นเท่าไหร่ (ถ้าคิดด้วยวิธีนี้ไม่ผิด จะได้หน้าตาสมการเป็นการหาผลรวมของเทอม <code>((n-k)/n)((n-k+1)/(n-1))((n-k+2)/(n-2))...(1/(n-k+1))P(n-k คนมี 1 คนได้ของตัวเอง)</code>)<br />
<br />
กรณีอื่นๆ ที่เหลือเนื่องด้วยพื้นที่กระดาษไม่พอเขี.... เฮ้ย ไม่ใช่แฟร์มาต์! จริงๆ แล้วต้องบอกว่าการพิสูจน์ด้วยท่านี้มันเริ่มยุ่งยากซับซ้อนจนไปต่อไม่ไหวแล้ว แต่ถ้ายังจำกันได้ นี่มัน<a href="https://en.wikipedia.org/wiki/Poisson_distribution">การแจกแจงปัวซอง</a>ที่มีค่า <code>λ=1</code> ชัดๆ ก็เอาเป็นว่าใครอยากพิสูจน์ต่อก็ลองใช้ท่านี้ดูนะ อาจจะได้บทพิสูจน์ที่สั้นและสวยงามกว่าด้วย<br />
<br />
<hr /><br />
เห็นแล้วว่าการสุ่มจับฉลากทั้งหมดทีเดียวพร้อมกันมันไม่เวิร์ค กลับไปดูวิธีดั้งเดิมที่ค่อยๆ ให้จับฉลากทีละคน จับได้ชื่อใครก็ให้คนนั้นไปจับฉลากต่อ วิธีนี้เขียนเป็นโค้ดออกมาได้ว่า<br />
<pre class="prettyprint">from random import randint
def exchange(ls):
owned = [None for _ in ls]
current = 0
while ls:
if owned[current] is not None:
current = owned.index(None)
gone = randint(0, len(ls)-1)
owned[current] = ls[gone]
current = ls[gone]
del ls[gone]
return owned
</pre>เอาฟังก์ชัน <code>exchange</code> ไปแทนที่ฟังก์ชัน <code>shuffled</code> ข้างบนแล้วทดลองใหม่ ก็ได้ผลลัพธ์ที่ไม่ต่างไปจากตารางแรกซักเท่าไหร่เลย<br />
<br />
<hr /><br />
ดังนั้นไม่ว่าจะให้จับฉลากพร้อมกันหมดในทีเดียว หรือจะค่อยๆ จับทีละคน พอจับได้ชื่อใครก็ให้คนนั้นจับต่อ ทั้งสองวิธีนี้ยังไงก็จะมีคน<del>ซวย</del>โชคดีอย่างน้อยหนึ่งคน ที่จับได้ของขวัญของตัวเองด้วยโอกาสสูงเท่ากันที่ <code>1-1/e</code> หรือประมาณ 63.21% ครับ โดยที่(แทบ)ไม่ต้องสนใจด้วยว่ามีคนมาแลกของขวัญกันกี่คน<br />
<br />
แต่วิธีแก้ก็ไม่ได้ยากเกินไป ใช้วิธีค่อยๆ ไล่จับฉลากไปทีละคนนั่นแหละ (จะได้เล่นมุกคั่นเวลา ดูรีแอคชันของคนได้ของขวัญด้วย) แล้วเพิ่มกฎเข้าไปสองข้อดังนี้<br />
<ol><li>ถ้าจับได้ชื่อตัวเอง ให้จับฉลากเพิ่มอีกใบเพื่อจะได้เอาของขวัญจากคนนั้น แต่อย่าลืมหย่อนฉลากชื่อตัวเองที่จับขึ้นมาเมื่อกี้ใส่กลับลงไหก่อนเอาไปให้จับฉลากต่อ</li>
<li>ตอนเหลือคนยังไม่ได้จับฉลาก 2 คน ไม่ต้องให้จับฉลากแล้ว ให้คนที่กำลังจะจับฉลากไปเอาของขวัญจากคนสุดท้ายได้เลย ส่วนคนสุดท้ายก็ไปเอาของขวัญจากคนแรก</li>
</ol>อย่างไรก็ตาม หากรู้สึกว่ากฎพวกนี้มันวุ่นวายจนทำให้งานกร่อยก็ไม่ต้องไปทำตามหรอก เพราะการมีคนจับได้ของขวัญของตัวเองก็ไม่ใช่เรื่องเลวร้ายแต่อย่างใด หนำซ้ำมันยังเป็นประสบการณ์สุดประหลาดที่หาได้ยาก และเป็นเรื่องขำขันชั้นดีที่สามารถเก็บเอาไว้เล่นได้เรื่อยๆ ยันลูกบวชเลยหละ<br />
<br />
สวัสดีปีใหม่ 2016 ล่วงหน้าครับ<br />
<br />
<script type="text/javascript">prettyPrint();</script>nzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-54802458136281878402015-08-13T05:50:00.000+07:002015-08-13T05:50:06.851+07:00จักรวาลวิทยาและความตาย: YOLOYOLO เป็นสแลงของวัยรุ่นในแถบประเทศที่พูดภาษาอังกฤษ มันย่อมาจากประโยคที่บอกว่า you only live once ที่แปลว่า "คุณมีชีวิตอยู่แค่ครั้งเดียว" ดังนั้นจะทำอะไรก็ทำไปเถอะ น่าเสียดายว่าหลายคนเอาไปใช้ในทางที่สุดโต่งอย่างการทำผิดกฎหมาย ทำให้คำนี้โดนมองในแง่ลบอย่างหนัก ต่างไปจากวลี carpe diem ในภาษาละตินที่แปลว่า "จงฉกฉวยชั่นขณะนี้ไว้" มันเป็นคำประพันธ์โบราณโดย Horace เมื่อกว่าสองพันปีก่อน และได้รับการเผยแพร่ซ้ำผ่านหนังขึ้นหิ้งอย่าง Dead Poet Society ทำให้วลีนี้ดูสุขุมนุ่มลึกกว่าคำข้างต้นที่เป็นได้เพียงสบถของพวกนอกคอก<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinmW1YWavN0oY6fjd9U7PEbQeNXkc52vReGGzwN1RrzxUl9ApS9fL__uN2vsKmWsIRoI5QPubyVm_sUtiob0Pr4PFhXKryU3dZdD0dRHt8b3uC-Qtjxyu9aIbhA9okbqLyMO7bE6ZiAFRF/s1600/yolo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinmW1YWavN0oY6fjd9U7PEbQeNXkc52vReGGzwN1RrzxUl9ApS9fL__uN2vsKmWsIRoI5QPubyVm_sUtiob0Pr4PFhXKryU3dZdD0dRHt8b3uC-Qtjxyu9aIbhA9okbqLyMO7bE6ZiAFRF/s1600/yolo.png" /></a></div><br />
แต่บทความนี้ไม่ได้มาเจาะลึกเรื่องทางประวัติศาสตร์ สังคม หรือแม้กระทั่งความหมายของคำนั้นหรอกครับ<br />
<br />
เพราะสิ่งที่น่าสนใจยิ่งกว่า คือแนวคิดที่แฝงไว้ว่า "ชีวิตนี้มีแค่ครั้งเดียว"<br />
<br />
หลายคนอาจจะรู้สึกว่าแนวคิดเช่นนี้เป็นสิ่งแปลกประหลาด ซึ่งก็เข้าใจได้ เพราะแทบทุกศาสนาบนโลก ต่างพูดเรื่องนี้ในทางตรงกันข้ามว่า "ยังมีเรื่องอื่นๆ อีกหลักความตาย" เช่น แนวคิดเรื่องสวรรค์และนรก แนวคิดการเวียนว่ายตายเกิด<br />
<br />
จุดที่ทำให้ศาสนาต่างๆ สร้างความเชื่อเช่นนั้นได้แม้ร่างกายจะสูญสิ้นไป ก็ด้วยแนวคิดที่ว่าร่างกายนั้นประกอบขึ้นมาจากสิ่งของในโลกนี้อย่างกระดูกเลือดเนื้อ และสิ่งของในโลกอื่นอย่างวิญญาณ (soul) ซึ่งหากมันรวมอยู่กับร่างกายแล้วจะช่วยให้มีชีวิต มีความคิด มีความรู้สึก แต่หากแยกออกจากกันก็จะทำให้ร่างกายนั้นตายไป<br />
<br />
พูดง่ายๆ ว่าวิญญาณนั้นอยู่ในมิติอื่นที่เราไม่สามารถสังเกตได้นั่นเอง<br />
<br />
และแน่นอนว่า เมื่อไหร่ก็ตามที่วิทยาศาสตร์จะพยายามสังเกตวิญญาณให้ได้ ศาสนาก็จะหลบเลี่ยงไปอธิบายวิญญาณในรูปแบบอื่นแทน ดังนั้นบทความนี้จะยังไม่มาเล่นวิ่งไล่จับกัน แต่จะฟันธงไปก่อนเลยว่าวิญญาณนั้นไม่มี เพื่อที่จะได้สำรวจความคิดที่งอกเงยขึ้นมาอย่างเต็มที่<br />
<br />
เมื่อเราปฏิเสธเรื่องวิญญาณไปแล้ว จะเห็นได้ว่าส่วนที่เหลือก็ง่ายทันที ความรู้สึกนึกคิด ความฝัน ความตระหนักในตัวตน (self-awareness) ต่างเป็นกิจกรรมที่เกิดขึ้นในสมองทั้งนั้น เมื่อสมองหยุดทำงานลง ก็หมายถึงความตายที่เราคุ้นเคยกันดี<br />
<br />
แต่ความตายนั้นเป็นจุดจบจริงหรือ?<br />
<br />
แบบจำลองจักรวาลที่ได้รับการยอมรับอย่างมากที่สุด ณ ขณะนี้ เสนอว่าจักรวาลนั้นมีจุดกำเนิด (big bang) เมื่อสิบสี่พันล้านปีที่แล้ว และขยายตัวมาเรื่อยๆ ด้วยอัตราเร่งที่สูงอย่างน่าใจหายถึงทุกวันนี้<br />
<br />
หากจักรวาลยังคงขยายตัวเช่นนี้ต่อไป แรงโน้มถ่วงจะเป็นฝ่ายพ่ายแพ้ ท้ายที่สุดแล้วจักรวาลจะเย็นตัวลงเพราะไม่เหลือแหล่งพลังงานอีกต่อไป ดาวทั้งหลายดับสิ้นไปจนมีแต่ความมืดมิดปกคลุมทุกหนแห่ง ช่วงเวลาดังกล่าวจะยาวนานตราบชั่วนิจนิรันดร์และไม่มีวันย้อนกลับ<br />
<br />
เมื่อนั้นแหละ ที่ความตายได้กลายเป็นจุดจบอย่างแท้จริง สำหรับชีวิตที่มีโอกาสเพียงแค่หนึ่งครั้งnzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-89159970075617059252015-08-06T07:44:00.001+07:002015-08-06T07:55:11.082+07:00ตรวจ 2^nวันก่อนเห็นทวีตนี้ของ <a href="https://twitter.com/Methuz">@Methuz</a><br />
<br />
<blockquote class="twitter-tweet" lang="en"><p lang="en" dir="ltr">Best way to check if number is a power of two return ((x != 0) && ((x & (~x + 1)) == x))</p>— Midas~♫ (@Methuz) <a href="https://twitter.com/Methuz/status/613534846132948996">June 24, 2015</a></blockquote><br />
แล้วก็มานึกได้ว่าเคยเห็นโจทย์นี้มานานแล้วนะ พอนั่งคิดต่ออีกหน่อยก็พบว่าปรับปรุงให้ดีขึ้นได้อีก โดยเปลี่ยนส่วนที่กลับข้างบิตแล้วเปรียบเทียบกับตัวเอง ไปเป็นไม่ต้องกลับข้างบิตแต่เอาไปเทียบกับศูนย์แทน กล่าวคือ<br />
<br />
<blockquote class="twitter-tweet" data-conversation="none" lang="en"><p lang="en" dir="ltr"><a href="https://twitter.com/Methuz">@Methuz</a> ((x != 0) && ((x & (x - 1)) == 0))</p>— เนยสดร้องไห้ทำมัย (@neizod) <a href="https://twitter.com/neizod/status/613774023927836672">June 24, 2015</a></blockquote><br />
<hr /><br />
ถ้าไม่เชี่ยววิเคราะห์อัลกอริทึม ดูแค่นี้อาจยังมองไม่เห็นว่าปรับปรุงดีขึ้นจริงหรือเปล่า เลย compile เป็น assembly ออกมาแล้วไล่ดูทีละบรรทัดเลย<br />
<br />
คำสั่งที่ใช้ compile ให้เป็น assembly (<a href="https://en.wikipedia.org/wiki/GNU_Assembler">GAS syntax</a>) คือ<br />
<br />
<pre class="prettyprint">$ gcc -S -O3 program.c
</pre><br />
อันนี้คือผลลัพธ์แบบแรกที่คุณ @Methuz เสนอ (ตัดมาเฉพาะส่วนฟังก์ชันที่สำคัญนะครับ)<br />
<br />
<pre>chkpowof2:
xorl %eax, %eax
testl %edi, %edi
je .L42
movl %edi, %eax
negl %eax
andl %edi, %eax
cmpl %eax, %edi
sete %al
movzbl %al, %eax
.L42:
rep ret
</pre><br />
และอันนี้เป็นแบบที่ปรับปรุงแล้ว<br />
<br />
<pre>chkpowof2:
xorl %eax, %eax
testl %edi, %edi
je .L42
leal -1(%rdi), %eax
testl %edi, %eax
sete %al
movzbl %al, %eax
.L42:
rep ret
</pre><br />
โอเค ใครอ่านถึงตรงนี้แล้วไม่งงก็กดปิดได้ เพราะเห็นชัดว่าปรับปรุงให้ดีขึ้นจริง<br />
<br />
ส่วนใครงงอยู่ เดี๋ยวมาไล่โค้ดกันทีละบรรทัดกันครับ :D<br />
<br />
<hr /><br />
แต่ก่อนอื่น หากอยากอ่าน assembly รู้เรื่อง ก็ต้องไปทำความคุ้นเคยกับ register เสียก่อน (พวกที่เขียนด้วยเครื่องหมาย <code>%</code> นำหน้า) ซึ่งมันก็คือตัวแปรต่างๆ นั่นเอง เพียงแต่ว่าตำแหน่งในโลกจริงของ register ถูกวางไว้ใน CPU เพื่อให้ทำงานได้อย่างรวดเร็ว ทำให้ register ทั้งหมดนั้นมีอยู่อย่างจำกัด (ไม่กี่สิบตัว)<br />
<br />
ในฟังก์ชันที่ตัดมานี้มี register ที่สำคัญอยู่ 2 ตัว คือ <code>%eax</code> และ <code>%edi</code> และยังมี register ตัวอื่นอีก เช่น <code>%al</code> ซึ่งเป็นส่วนย่อยของ <code>%eax</code> โดยอธิบายความสัมพันธ์ได้ดังแผนภาพนี้<br />
<br />
<pre>sample value:
0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
a family register:
|- %ah -| |- %al -|
|------ %ax ------|
|--------------- %eax ----------------|
|----------------------------------- %rax ------------------------------------|
di family register:
|------ %di ------|
|--------------- %edi ----------------|
|----------------------------------- %rdi ------------------------------------|
</pre><br />
ดังนั้นหากค่าของ <code>%eax</code> (32 บิต) ถูกตั้งไว้เป็น <code>0x89ABCDEF</code> เมื่อเรียกดูค่าของ <code>%al</code> (8 บิต) ก็จะว่ามีค่าเป็น <code>0xEF</code><br />
<br />
ส่วนหน้าที่พิเศษของ register ทั้ง 2 ตัวในที่นี้คือ<br />
<ul><li><code>%eax</code> เก็บค่าที่จะ return จากฟังก์ชัน</li>
<li><code>%edi</code> เก็บค่า argument ของฟังก์ชัน</li>
</ul><br />
พอคุ้นเคยกับ register เหล่านี้แล้ว คราวนี้ก็ได้เวลามาดูโค้ดจริงๆ เสียที<br />
<br />
<h4>บรรทัด 1</h4><pre>xorl %eax, %eax
</pre><br />
บรรทัดแรกนี้สั่งล้างค่า <code>%eax</code> ให้เป็นศูนย์ไว้ก่อน โดยใช้เทคนิคว่า ค่าใดๆ เมื่อนำไป <a href="https://en.wikipedia.org/wiki/XOR_gate">xor</a> กับตัวเองแล้วจะได้ศูนย์เสมอ <a href="https://stackoverflow.com/questions/1396527/any-reason-to-do-a-xor-eax-eax">ท่านี้จะเร็วกว่าการโหลดข้อมูลจาก memory มาถม</a><br />
<br />
<h4>บรรทัด 2-3:</h4><pre>testl %edi, %edi
je .L42
</pre><br />
สองบรรทัดต่อมาเป็นการเช็คว่า <code>%edi</code> (ตัวแปร <code>x</code>) มีค่าเป็นศูนย์หรือเปล่า โดยใช้เทคนิคว่า ค่าใดๆ เมื่อนำไป <a href="https://en.wikipedia.org/wiki/AND_gate">and</a> กับตัวเองก็จะได้ตัวเองเสมอ หากตรวจแล้วพบว่าเป็นศูนย์ก็ให้กระโดดไปยังจุดจบฟังก์ชัน ซึ่งเมื่อรวมกับข้อมูลก่อนหน้าว่าตอนนี้ <code>%eax</code> เป็นศูนย์อยู่ ก็คือฟังก์ชันนี้ให้คำตอบเป็น <code>false</code> นั่นเอง<br />
<br />
<h4>บรรทัด 4-8 ของแบบแรก:</h4><pre>movl %edi, %eax
negl %eax
andl %edi, %eax
cmpl %eax, %edi
sete %al
</pre><br />
บรรทัดต่อๆ มาเป็นชุดคำสั่งในส่วนหลังที่ถามว่า หากมอง <code>x</code> เป็น binary แล้ว จะมีตัวเลข 1 เพียงตัวเดียวเท่านั้นหรือเปล่า? ซึ่งโค้ดชุดนี้ทำงานโดยเริ่มจากการคัดลอกค่า <code>x</code> จาก <code>%edi</code> มาไว้ที่ <code>%eax</code> ก่อน แล้วหาค่าติดลบแบบ <a href="https://en.wikipedia.org/wiki/Two%27s_complement">two complement</a> ของ <code>%eax</code> และเก็บไว้ที่เดิม (มีค่าเทียบได้กับการคำนวณ <code>~x+1</code>) แล้วจึงเอาค่าของ <code>%edi</code> ไปทำการ and และเก็บค่าไว้ใน <code>%eax</code> (ตอนนี้ <code>%eax</code> ก็จะเก็บค่าของ <code>x&(~x+1)</code> แล้ว) สุดท้ายถามว่า <code>%eax</code> ลบ <code>%edi</code> ได้ศูนย์หรือเปล่า ถ้าใช่ก็จะตั้งค่า <code>%al</code> ให้เท่ากับหนึ่ง (ซึ่งก็คือ ฟังก์ชันจะคืนค่า <code>true</code>)<br />
<br />
<h4>บรรทัด 4-6 ของแบบสอง:</h4><pre>leal -1(%rdi), %eax
testl %edi, %eax
sete %al
</pre><br />
ชุดบรรทัดพวกนี้มีหน้าที่และผลลัพธ์เหมือนกับชุดบรรทัดในหัวข้อย่อยก่อนเลยครับ สิ่งที่แตกต่างคือวิธีการเท่านั้น โดยโค้ดเริ่มทำงานจากคัดลอกค่า <code>x</code> จาก <code>%rdi</code> มาลบหนึ่งระหว่างทางแล้วเอาผลลัพธ์ไปเก็บไว้ใน <code>%eax</code> (ตรงนี้เนื่องจากมีการคำนวณพื้นฐานอย่างบวกลบ ทำให้ compiler รวบคำสั่งเข้ามาที่เดียว ต่างจากการคำนวณซับซ้อนอย่างการหาค่าติดลบครับ) เรียบร้อยแล้วเอา <code>%edi</code> มา and กับ <code>%eax</code> หากได้ศูนย์ก็จะตั้งค่า <code>%al</code> ให้เท่ากับหนึ่ง (คืน <code>true</code>)<br />
<br />
<h4>บรรทัดรองสุดท้าย</h4><pre>movzbl %al, %eax
</pre><br />
ถึงตอนนี้การคำนวณหลักๆ ได้เสร็จสิ้นหมดแล้ว ที่ยังไม่เสร็จคือเตรียมค่าที่จะส่งคืน เพราะก่อนหน้านี้เราใช้ <code>%al</code> ยาว 8 บิต แต่ตอนส่งค่าคืนต้องใช้ <code>%eax</code> ที่ยาว 32 บิต บรรทัดนี้จะช่วยแปลงค่าดังกล่าว<br />
<br />
<h4>บรรทัดสุดท้าย</h4><pre>rep ret
</pre><br />
สุดท้ายก็ได้เวลาส่งคืนคำตอบครับ สังเกตว่า compiler เพิ่มความมั่นใจให้คำสั่งนี้ด้วยการเติม <code>rep</code> ไว้ข้างหน้า เพื่อให้โค้ดที่ทำงานมาถึงบรรทัดนี้ทำคำสั่ง <code>ret</code> ซ้ำๆ จนกว่าจะสำเร็จนั่นเอง<br />
<br />
<hr /><br />
สุดท้ายการวิเคราะห์อัลกอริทึม/โค้ดยังไม่พอ นี่คือผลเชิงประจักษ์ของเวลาที่ใช้ไปสำหรับการตรวจว่าเลขดังกล่าวเป็น 2^n หรือไม่ สำหรับจำนวนเต็มบวกทุกตัวที่มีค่าต่ำกว่าสองพันล้านครับ<br />
<br />
<pre class="prettyprint">$ gcc --version
gcc (Ubuntu 4.9.2-10ubuntu13) 4.9.2
$ cat /proc/cpuinfo
...
model name : Intel(R) Core(TM) i5-4200U CPU @ 1.60GHz
...
$ time method-1 # ((x != 0) && ((x & (~x + 1)) == x))
real 0m0.234s ~ 0m0.289s
user 0m0.232s ~ 0m0.288s
sys 0m0.000s
$ time method-2 # ((x != 0) && ((x & (x - 1)) == 0))
real 0m0.212s ~ 0m0.262s
user 0m0.208s ~ 0m0.260s
sys 0m0.000s
</pre><br />
ก็เร็วต่างกันประมาณ 10%<br />
<br />
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script><br />
<script type="text/javascript">prettyPrint();</script>nzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-18721877855581040252015-07-10T18:00:00.000+07:002015-07-10T18:03:15.338+07:00จำลอง WYSIWYG ตามแบบคนจนบน HTML5คนที่เคยทำเว็บที่มีกล่องข้อความให้กรอกข้อมูลยาวๆ เพื่อนำไปจัดย่อหน้าสวยๆ คงต้องเคยได้ยิน requirement ว่าอยากได้ <a href="https://en.wikipedia.org/wiki/WYSIWYG">WYSIWYG</a> บ้างหละ<br />
<br />
ถ้าใช้เว็บสำเร็จรูปทั่วไปก็อาจจะไม่ยากเท่าไหร่ เช่น WordPress ที่มี WYSIWYG มาให้แต่เริ่มเลย หรือหากไม่ถูกใจก็ยังมีส่วนเสริม WYSIWYG ให้เลือกติดตั้งเพิ่มได้อีก<br />
<br />
แต่ถ้าเริ่มทำเว็บเองจากศูนย์ หรือว่า framework ที่ใช้ไม่ดังพอจนไม่มีใครทำส่วนเสริมนี้ให้หละ? จะพบว่า requirement นี่เป็นสิ่งที่สร้างเองได้ยากมากๆๆๆ<br />
<br />
ทางแก้สำหรับเหล่า geek คงเป็นการ "เลิกฝัน" แล้วกลับไปลุยดะกับโค้ดจัดย่อหน้าเลย (ซึ่งก็ไม่จำเป็นต้องยุ่งกับ HTML ตรงๆ อาจเลือกพวกที่เจ็บปวดน้อยลงอย่าง <a href="https://en.wikipedia.org/wiki/Markdown">Markdown</a> ก็ได้)<br />
<br />
แต่ถ้าแนะนำแบบนี้กับคนทั่วไปที่ชินกับ MS Word คงไม่เวิร์กแน่<br />
<br />
จริงๆ ทางออกสำหรับพวกเขาเหล่านั่น อาจไม่ใช่การแก้ไขทุกรายละเอียดผ่านกล่องข้อความในหน้าเว็บก็ได้<br />
<br />
เพราะในเมื่อพวกเขาชินกับการใช้โปรแกรม Word อยู่แล้ว ก็ให้แก้ไขอะไรให้เรียบร้อยบน Word ไปเลย เรียบร้อยแล้วลากคลุมสิ่งที่ต้องการ Ctrl+C Ctrl+V มาวางบนกล่องข้อความหน้าเว็บก็พอ<br />
<br />
ส่วนกล่องข้อความก็เปลี่ยนจาก <code><textarea></code> ไปเป็น <code><div contenteditable></code> แทน เท่านี้ก็เรียบร้อย (แล้วไปหาวิธีเซฟ/โหลดข้อความที่ <code><div></code> แทน ซึ่งไม่ยุ่งยากหรอกในโลกที่มี jQuery ให้ใช้ :P)<br />
<br />
<hr /><br />
อยากลองเล่น? ขั้นแรกให้พิมพ์ตามนี้ลงไปใน address bar ของเว็บเบราเซอร์เพื่อสร้าง WYSIWYG ก่อนครับ<br />
<br />
<pre class="prettyprint">data:text/html, <html contenteditable>
</pre><br />
ขั้นต่อมาก็ไปเปิดเอกสาร Word ซักอัน (หรือจะสร้างใหม่ก็ได้) แล้วลองคัดลอกข้อความมาวางบนหน้าเว็บนั้นดู<br />
<br />
ส่วนอะไรที่เวิร์กไม่เวิร์กบ้าง เท่าที่ลองคร่าวๆ ได้ผลตามตารางนี้ครับ<br />
<br />
<table border="1"><tbody>
<tr> <th>การจัดรูปแบบ</th> <th>แท็กที่ใช้แทน</th> <th>MS Word</th> <th>LibreOffice</th> <th>Google Docs</th> </tr>
<tr> <td>Title</td> <td><p align="center"><font size="6"></td> <td>✓</td> <td>✓</td> <td>✓</td> </tr>
<tr> <td>Subtitle</td> <td><p align="center"><font size="5"></td> <td>✓</td> <td>✓</td> <td>✓</td> </tr>
<tr> <td>Heading 1-3</td> <td><h1> - <h3></td> <td>✓</td> <td>✓</td> <td>✓</td> </tr>
<tr> <td>Heading</td> <td><font size="4"></td> <td>✓</td> <td>✓</td> <td>✓</td> </tr>
<tr> <td>Quotations</td> <td><blockquote></td> <td>✓</td> <td>✓</td> <td>✓</td> </tr>
<tr> <td>Align Left / Center / Right / Justify</td> <td><p align="left / center / right / justify"></td> <td>✓</td> <td>✓</td> <td>✓</td> </tr>
<tr> <td>Bold, Italic, Underline, Strikethrough</td> <td><b> / <i> / <u> / <strike></td> <td>✓</td> <td>✓</td> <td>✓</td> </tr>
<tr> <td>Superscript, Subscript</td> <td><sup> / <sub></td> <td>✓</td> <td>✓</td> <td>✓</td> </tr>
<tr> <td>Table</td> <td><table><tbody><tr><td></td> <td>✓</td> <td>✓</td> <td>✓</td> </tr>
<tr> <td>Bullet List</td> <td><ul><li></td> <td>✓</td> <td>✓</td> <td>✓</td> </tr>
<tr> <td>Numbering</td> <td><ol><li></td> <td>✓</td> <td>✓</td> <td>✓</td> </tr>
<tr> <td>Image</td> <td><img src="data:image/png;base64,..."></td> <td></td> <td>✓</td> <td>✓</td> </tr>
<tr> <td>Formula</td> <td><img src="data:image/png;base64,..."></td> <td></td> <td>✓</td> <td></td> </tr>
</tbody></table><br />
(จากที่สังเกต ผลลัพธ์ตอนนำข้อความมาวาง<i>เหมือนจะ</i>ไม่มีความต่างกันในแต่ละเว็บบราวเซอร์ ดังนั้นจึงสนใจเฉพาะตอนคัดลอกมาจากโปรแกรมแก้ไขเอกสารอย่างเดียวครับ)<br />
<br />
<script type="text/javascript">prettyPrint();</script>nzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-41442370817737441992015-06-17T16:36:00.000+07:002015-06-17T16:36:19.059+07:00AutoHotKey กับสคริปต์เปลี่ยนภาษาลง Windows ใหม่อีกรอบและทำโปรแกรมเปลี่ยนภาษาด้วยปุ่ม CapsLock หายไปแล้ว เลยมาจดไว้ก่อน เผื่อเจอเหตุการณ์ประมาณนี้อีกจะได้ลดเวลาลองผิดลองถูก<br />
<br />
<ol><li>เช็คให้แน่ใจว่าการเปลี่ยนภาษาบน Windows ใช้ปุ่ม <code>Alt+Shift</code> เสียก่อน</code></li>
<li>ดาวน์โหลดและติดตั้งโปรแกรม <a href="www.autohotkey.com">AutoHotKey</a></li>
<li>กด <code>Win+R</code> พิมพ์ <code>shell:startup</code> มันจะเปิดแฟ้มเก็บโปรแกรมที่ถูกเรียกอัตโนมัติตอนเปิดเครื่องมาให้</li>
<li>คลิกขวาเลือกสร้างสคริปต์ AutoHotKey (อย่าสร้างไฟล์เปล่าๆ เพราะจะไม่ได้ค่าปริยายมาด้วย) แล้วเพิ่มคำสั่งนี้ต่อท้ายไฟล์<br />
<pre>Capslock:: Send {Alt Down}{Shift}{Alt Up}
</pre></li>
</ol><br />
เรื่องประหลาดคือ ในสคริปต์ถ้าสลับตำแหน่งเป็นกด Shift ค้างไว้ก่อนแล้วค่อยกด Alt มันก็เปลี่ยนภาษาได้นะ แต่พอเปลี่ยนเสร็จเคอร์เซอร์จะหลุดโฟกัสไปเลย ไม่รู้ว่าเกิดอะไรขึ้น :\nzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-60010570068283133262015-05-25T00:19:00.000+07:002015-05-25T04:54:43.058+07:00ลองใช้ Lamy ครั้งแรกชีวิตนี้ไม่เคยคิดว่าจะใช้ปากกาด้ามแพงเกินร้อยบาทครับ แต่ก็ได้ Lamy มาฟรีด้ามนึงเป็นของขวัญวันรับปริญญา<br />
<br />
ดองไว้เป็นปีแล้วเพราะไม่รู้ว่าใช้ยังไง จนกระทั่งไม่กี่วันก่อนที่ปากกาทุกด้ามจงใจหมึกตัน เลยได้ฤกษ์เอาออกมาลองใช้ซะเลย<br />
<br />
ด้ามที่ได้มานี้หัวเป็นขนาด M ครับ โดยรวมแล้วเอาไปเขียนลื่นสนุกดี แม้มีสะดุดบางจังหวะ<br />
<br />
แต่ตอนเอามาวาดรูปนี่รู้สึกควบคุมน้ำหนักเส้นไม่ได้เลย (ไม่เหมือนหัวลูกลื่นที่สามารถฝนบางๆ น้อยกว่าขนาดที่บอกไว้ได้) ...<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4PpW9gTbdONcPsPuacYGOf0_i6EAv5BpK5TeMmFJiUHsEzbk3xa3UiWP2Sb1isAhfPBtnO-HCLrNtYgzojCLM7L1_jyHxUJIWzfhHycZ0PQm4ka64cg7ZeKsY8F8XzpdaEB_6xYavhjE_/s1600/IMG_20150523_011516.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4PpW9gTbdONcPsPuacYGOf0_i6EAv5BpK5TeMmFJiUHsEzbk3xa3UiWP2Sb1isAhfPBtnO-HCLrNtYgzojCLM7L1_jyHxUJIWzfhHycZ0PQm4ka64cg7ZeKsY8F8XzpdaEB_6xYavhjE_/s640/IMG_20150523_011516.jpg" /></a></div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEij_4b1WQhsmORzZqqJ2QfYnUea0lEHgfxW9u63c0p-7d93CfcC1aMK-SwhzS3sthRsQPqWWgX2s0sLt7ppEg-Mbt1A9esvpCvUHNI7Ly-wKjMBx4oJcUzdyT_HKS8cEEOBzKpMx0Be-qot/s1600/IMG_20150524_222809.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEij_4b1WQhsmORzZqqJ2QfYnUea0lEHgfxW9u63c0p-7d93CfcC1aMK-SwhzS3sthRsQPqWWgX2s0sLt7ppEg-Mbt1A9esvpCvUHNI7Ly-wKjMBx4oJcUzdyT_HKS8cEEOBzKpMx0Be-qot/s640/IMG_20150524_222809.jpg" /></a></div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIoqPUajI2llsA7MCcFu4mlob0pW4B-vgwydVp4UOIoeILPvRIbSLCwgjMyhAvqin8rcVDvbeEaOWHnxgulCaibzfKLGKXG_jV91PD4C3uhGgATUTvesTwzQY1wVjBgkwMqoluezZx7-xH/s1600/IMG_20150524_222900.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIoqPUajI2llsA7MCcFu4mlob0pW4B-vgwydVp4UOIoeILPvRIbSLCwgjMyhAvqin8rcVDvbeEaOWHnxgulCaibzfKLGKXG_jV91PD4C3uhGgATUTvesTwzQY1wVjBgkwMqoluezZx7-xH/s640/IMG_20150524_222900.jpg" /></a></div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwUGnaDibZ5SVpqxk7952WI96ONZ2zqgcSKGAYgxeM4sT1h4f13iFp0Fwb1W-cMB-RqpRjaa9uaYQ29QaG1A5RQSfvxUYluRKz_fjXY5MoEDQRQcUKpPYOf49RayqgtAIFrT7LKlJ5ErhW/s1600/IMG_20150525_044358.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwUGnaDibZ5SVpqxk7952WI96ONZ2zqgcSKGAYgxeM4sT1h4f13iFp0Fwb1W-cMB-RqpRjaa9uaYQ29QaG1A5RQSfvxUYluRKz_fjXY5MoEDQRQcUKpPYOf49RayqgtAIFrT7LKlJ5ErhW/s640/IMG_20150525_044358.jpg" /></a></div><br />
สรุปแล้วไม่ค่อยชอบเท่าไหร่แฮะ นี่ผมแปลกไปเองหรือเปล่าเนี่ย?nzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-71570405216062426372015-05-22T14:43:00.000+07:002015-05-22T14:43:33.905+07:00Voronoi จากภาพวันก่อนไปเจอ<a href="https://codegolf.stackexchange.com/questions/50299/draw-an-image-as-a-voronoi-map">คำถามใน Code Golf</a> มา เค้าให้สร้าง Voronoi เพื่อเลียนแบบภาพต้นฉบับครับ<br />
<br />
อ่านแล้วสนุกดี ผลงานของคนอื่นที่ได้ๆ ก็ดูเหมือนงานศิลป์พวก Divisionism/Pointillism ด้วย เลยลองกลับมาเขียนเองแบบมั่วๆ บ้าง 555<br />
<br />
<pre class="prettyprint lang-py">import random
from PIL import Image
from PIL.ImageFilter import FIND_EDGES, GaussianBlur, SHARPEN
def coordinate(width, height):
yield from ((x, y) for y in range(height) for x in range(width))
def normalized(choices):
lower = min(weight for _, weight in choices)
upper = max(weight for _, weight in choices)
norm = lambda weight: (weight-lower) + (upper-lower)//4
return [((x, y), norm(weight)) for (x, y), weight in choices]
def random_by_weight(choices):
rand_val = random.uniform(0, sum(weight for _, weight in choices))
index = 0
count = 0
while count < rand_val:
count += choices[index][1]
index += 1
return choices.pop(index-1)[0]
def init_centroids(image, cells):
width, height = image.size
edge_img = image.filter(FIND_EDGES).filter(GaussianBlur).filter(SHARPEN)
weight = lambda x, y: 256 - max(edge_img.getpixel((x, y)))
choices = [((x, y), weight(x, y)) for x, y in coordinate(width, height)]
return [random_by_weight(normalized(choices)) for _ in range(cells)]
def init_rgbs(image, centroids):
rgb_im = image.convert('RGB')
return [rgb_im.getpixel((x, y)) for x, y in centroids]
def simulate_voronoi(image_path, cells=25, scale=None):
image = Image.open(image_path)
if scale is not None:
image.thumbnail((scale, scale), Image.ANTIALIAS)
centroids = init_centroids(image, cells)
rgbs = init_rgbs(image, centroids)
return image.size, list(zip(centroids, rgbs))
</pre>
ผลลัพธ์ที่ออกมาก็ประมาณนี้ครับ (ที่ 500 เซลล์ Voronoi)
<hr /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7-9Ybcseut4Qp0T36hyZ9JO-VLAF68Ezp9rCmLrk8GR5pGkvJZeh_dKDZqJR5C3GwAiHLwDNJaenQsyuSjEsSuyR4Zvh7LfoIysZ1PF_uLOalRJFLibLuu_V1EIdHANmN4W_90WwlLlIt/s1600/bear.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7-9Ybcseut4Qp0T36hyZ9JO-VLAF68Ezp9rCmLrk8GR5pGkvJZeh_dKDZqJR5C3GwAiHLwDNJaenQsyuSjEsSuyR4Zvh7LfoIysZ1PF_uLOalRJFLibLuu_V1EIdHANmN4W_90WwlLlIt/s640/bear.png" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5wkN8gTwhazt2tGng_n445pi3FQFxGYgWAdhQITBsCVepMPapUgkhFkPlSxx3IayNEtlGDvEI2HAFE_JX9Q4_aNQcx44r57loztvJE3xVPToXNe2oOoMRu_XfFJMB-dC-XveK1yi7hi3n/s1600/pearl-earing.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5wkN8gTwhazt2tGng_n445pi3FQFxGYgWAdhQITBsCVepMPapUgkhFkPlSxx3IayNEtlGDvEI2HAFE_JX9Q4_aNQcx44r57loztvJE3xVPToXNe2oOoMRu_XfFJMB-dC-XveK1yi7hi3n/s640/pearl-earing.png" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmQ5RiNgkko-QIZxnM3gFqh4ub8Ps2PVOcPnOFhwNzPFpYDA6DXo_zcnkE4NSl7LrZoiV-AbDLhyphenhyphen5M35oVcK5kTCY1gChwaCrbTUBVBUackxQqNm97NMrO6wRiLn6f4I3UtG7XA9br2eKJ/s1600/great-wave.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmQ5RiNgkko-QIZxnM3gFqh4ub8Ps2PVOcPnOFhwNzPFpYDA6DXo_zcnkE4NSl7LrZoiV-AbDLhyphenhyphen5M35oVcK5kTCY1gChwaCrbTUBVBUackxQqNm97NMrO6wRiLn6f4I3UtG7XA9br2eKJ/s640/great-wave.png" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIzCZMtYQrdV9oG4S-89Hs6XJfrOntJAKbnIYaPZW8oRyLjnNNVoY_4ypyGvS0I6uto24JLzuD74Gjm3eAwn2WtpAZVvi6s-74AZbBKidG6aEqqO-0OrS7Y8xrEs5IUAp5EMtUyFzDHWFW/s1600/starry-night.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIzCZMtYQrdV9oG4S-89Hs6XJfrOntJAKbnIYaPZW8oRyLjnNNVoY_4ypyGvS0I6uto24JLzuD74Gjm3eAwn2WtpAZVvi6s-74AZbBKidG6aEqqO-0OrS7Y8xrEs5IUAp5EMtUyFzDHWFW/s640/starry-night.png" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwpxG17bGh-EmTWGUFuWVZfTsJ0MTt58dXxySaxE5n4q35LOTHiUpcvS9VfG0RPZz6XjsAPwpIXNKeQeRmBa-0dp2yrBwTIDUJM-rvaCpSNx7QVvHCkOQXqWCIZVmhQMkNBltszI1veLrE/s1600/saturn.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwpxG17bGh-EmTWGUFuWVZfTsJ0MTt58dXxySaxE5n4q35LOTHiUpcvS9VfG0RPZz6XjsAPwpIXNKeQeRmBa-0dp2yrBwTIDUJM-rvaCpSNx7QVvHCkOQXqWCIZVmhQMkNBltszI1veLrE/s640/saturn.png" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVZbavOM3Hv06jHLpBWERyCVOGftMXaMJXuvgd-POPzyJiVHu7jWNdlbw4jWaLSTKcGvfFoOyrcrm-AL3lw0O_3zUriRO-LFIKXF1Hzww7ZIkXPzccEPv82lXLlZSLZwbMMH7nP_P_nttp/s1600/andromeda-galaxy.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVZbavOM3Hv06jHLpBWERyCVOGftMXaMJXuvgd-POPzyJiVHu7jWNdlbw4jWaLSTKcGvfFoOyrcrm-AL3lw0O_3zUriRO-LFIKXF1Hzww7ZIkXPzccEPv82lXLlZSLZwbMMH7nP_P_nttp/s640/andromeda-galaxy.png" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc5_m4L6dEd3R45LQdKuqjg9NUcbBdO2CrvKtO0rU1sixOeQ4hhfzv9c75xV08fyVGf2F7DDkdQtZQwMcnIJUvuba8rLeSrV6kdaqWsBBZWx99nQ3FX8YPVDq49pLwbXMVklpZtqBAjYp1/s1600/circles-in-circle.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc5_m4L6dEd3R45LQdKuqjg9NUcbBdO2CrvKtO0rU1sixOeQ4hhfzv9c75xV08fyVGf2F7DDkdQtZQwMcnIJUvuba8rLeSrV6kdaqWsBBZWx99nQ3FX8YPVDq49pLwbXMVklpZtqBAjYp1/s640/circles-in-circle.png" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMgc2mm9M4vMf0iLVSZe1aI0TcE2QrqJw9-lvL4sJpSFN87HLJ_lruZ4dmRadk7ddt8RdbMrQZCgdrQCqefq980Z4MMkWElTCPubvldgFdSMToUwc7yOdxO7Vuvth1yxAlqiPPrSHDhLzA/s1600/composition-2.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMgc2mm9M4vMf0iLVSZe1aI0TcE2QrqJw9-lvL4sJpSFN87HLJ_lruZ4dmRadk7ddt8RdbMrQZCgdrQCqefq980Z4MMkWElTCPubvldgFdSMToUwc7yOdxO7Vuvth1yxAlqiPPrSHDhLzA/s640/composition-2.png" /></a>
<hr />เอาไปสู้เขาไม่ได้หรอก เพราะเขียนไปมั่วแบบคนไม่มีพื้นฐาน image processing อะไรเลย แต่ก็สนุกดีได้ลองใช้ PIL เป็นครั้งแรกด้วย
<script type="text/javascript">prettyPrint();</script>nzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-18597047588692086632015-05-14T00:52:00.000+07:002015-05-14T00:52:07.486+07:00Sexy Love<iframe width="853" height="480" src="https://www.youtube.com/embed/mjknp1nWGjY" frameborder="0" allowfullscreen></iframe><br />
<br />
ช่วงนี้ทำงานแรงงานครับ ไม่ค่อยได้ใช้สมองเท่าไหร่ เลยต้องเปิดเพลงวนไปเรื่อยๆ ให้มันรู้สึกสดชื่นตลอดเวลา<br />
<br />
แล้ว YouTube ก็วนเพลง Sexy Love มาให้<br />
<br />
รู้ตัวอีกที 2 ชั่วโมงถัดมา ก็ยังกดเล่นซ้ำ ฟังเพลงนี้ซ้ำๆ อยู่ครับ<br />
<br />
ท่าเต้นโรบอทนี่มันแจ่มจริงๆ ให้ดิ้นตายสิ :3nzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-18296795486705018332015-05-07T15:57:00.000+07:002015-05-07T15:57:07.940+07:00Entertainment<iframe width="853" height="480" src="https://www.youtube.com/embed/tBsRvthVhdw" frameborder="0" allowfullscreen></iframe><br />
<br />
เพลงนี้เป็นเพลงประกอบเครดิตหนัง Now You See Me (2013) ครับ คือทั้งเรื่องไม่ได้ใช้เพลงนี้มาประกอบเลยนั่นแหละ ถ้าไม่นั่งดูเครดิตหนังก็ไม่รู้ว่ามี<br />
<br />
ฟังแล้วสนุกดี ได้กลิ่นหนังจีนสมัยก่อนลอยมาแต่ไกลเลย (ทั้งๆ ที่เป็นวงจากฝรั่งเศส) สงสัยเพราะว่าเมโลดี้อยู่ในกุญแจไดอาโทนิคด้วย แต่มันก็ไม่ได้ออกบลูแจ๊สแม้แต่น้อย กลับเป็นร๊อคมันส์ๆ ให้โยกหัวตามได้<br />
<br />
ก็ถือว่าเป็นการผสมผสานที่น่าสนใจดี นั่งฟังได้ทั้งวันnzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-34548618694172794502015-05-06T08:51:00.000+07:002015-05-06T10:30:58.324+07:00Noah<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyMKjz6D6kSZe29RKL2DPfqpNoBb3vI6_mIgpkSa3qOs_asPYcuURYBqTxwyuOeTZypWo6I3H0OWZzpsy3lxEUTeIYYS8OWSNK3QV-ChCfBjpolTeKV_vog69-nTVWlr9minhOt8GKXKnB/s1600/Noah.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyMKjz6D6kSZe29RKL2DPfqpNoBb3vI6_mIgpkSa3qOs_asPYcuURYBqTxwyuOeTZypWo6I3H0OWZzpsy3lxEUTeIYYS8OWSNK3QV-ChCfBjpolTeKV_vog69-nTVWlr9minhOt8GKXKnB/s640/Noah.png" /></a></div><br />
ไม่กี่วันก่อนช่อง HBO เอาเรื่องนี้มาฉายครับ ดูจบแล้วคำพูดนี้พุ่งเข้ามาในหัวเลย<br />
<br />
<blockquote>God is dead<br />
<div style="text-align: right;">-- <cite>Friedrich Nietzsche</cite></div></blockquote><br />
เกริ่นก่อนสำหรับใครที่ไม่คุ้นเคยกับศาสนาคริสต์ เรื่องนี้เล่าถึงช่วงแรกที่พระเจ้าสร้างโลกครับ หลังจากสร้างโลกและสรรพสัตว์ทั้งหลายเสร็จ ก็สร้างมนุษย์คู่แรก (อดัม-อีฟ) ขึ้นมาไว้ในสวนเอเดน โดยให้อิสระทุกอย่างยกเว้นอย่างเดียวคือห้ามกินผลไม้ที่อยู่กลางสวน (ตีความกันว่าคือผลแอปเปิล) ช่วงแรกอดัมกับอีฟก็เชื่อฟังพระเจ้าดีอยู่ แต่ก็โดนงูหลอกให้กินผลไม้นั้น พอพระเจ้าจับได้จึงไล่อดัมและอีฟ (และงู) ออกจากสวนเอเดนไป<br />
<br />
เวลาผ่านไปหลายชั่วอายุคน พระเจ้าเห็นว่าโลกเสื่อมโทรมลงมาก จึงต้องการชำระล้างโลกด้วยพลังแห่งน้ำ ก่อนลงมือก็ไปกระซิบบอกโนอาห์ (โคตรเหลนของอดัม-อีฟ) ให้เตรียมตัวรับมือก่อน โดยอย่าลืมพาพวกสรรพสัตว์ไปด้วย โนอาห์เลยต่อเรือยักษ์ตามที่พระเจ้าว่า<br />
<br />
จุดแตกต่างจากไบเบิลที่เด่นชัดจุดแรกในเวอร์ชันหนัง คือพระเจ้าไม่ได้พูดตรงๆ กับโนอาห์แต่ใช้วิธีฉายภาพภัยพิบัติที่จะเกิดขึ้นให้ดูในฝันแทน (ถ้าเคยดู Prince of Egypt ปี 1998 จะเห็นว่าพระเจ้าอวตารร่างลงมาเป็นลูกไฟเพื่อพูดคุยกับโมเสสตรงๆ เลย) อันที่จริง หนังเรื่องนี้ทั้งเรื่องไม่ได้แสดงตัวตนหรือคำพูดของพระเจ้าเลย<br />
<br />
จุดต่อมาคือมนุษย์ที่โนอาห์พาขึ้นเรือไปนั้น ไม่สามารถมีลูกหลานต่อไปได้ ซึ่งก็กลายเป็นดราม่าหลักของเรื่องเมื่ออิล่า แฟนสาวกับลูกคนหนึ่งโนอาห์ (นำแสดงโดยเฮอร์ไมโอนี่ :P) ที่เป็นหมันมาตั้งแต่เด็ก ดันตั้งท้องบนเรือซะงั้น โนอาห์ซึ่งคิดว่าความเสื่อมใดๆ ในโลกล้วนเกิดจากน้ำมือของมนุษย์ จึงต้องการฆ่าลูกของอิล่าเสียเมื่อเธอคลอด<br />
<br />
การสร้างหนังจากเรื่องราวที่รายละเอียดต้นทางน้อยแบบนี้ (เรื่องของโนอาห์มีไม่ถึงครึ่งของครึ่งในหนังสือปฐมกาล ถ้าเทียบกับโมเสสที่ได้หนังสืออพยพไปทั้งเล่ม) มันต้องมีการตีความแต่งเติมปรับแต่งเนื้อเรื่องไปมาก ตรงนี้เข้าใจและยอมรับได้นะ และหนังที่สร้างออกมาจากการตีความนี้ก็สนุกพอตัวเลยหละ<br />
<br />
แต่ดูแล้วก็อดไม่ได้ที่จะคิดไปว่า พระเจ้าในหนังเรื่องนี้ ไม่ได้มีพลังอำนาจอะไรเลย<br />
<br />
การที่พระเจ้าไม่เคยปรากฎตัวขึ้นมาแม้แต่ครั้งเดียว เราอาจตีความได้ว่าโนอาห์ดันฝันเห็นแฟนตาซีที่น่ากลัวมากๆ แล้วหมกมุ่นกับมันจนต้องสร้างเรือขึ้นมา ไม่จำเป็นต้องมีพระเจ้ามาเกี่ยวข้องเลย (ใครไม่เคยฝันแฟนตาซีน่าตื่นเต้นแบบนี้บ้าง?) พอฝนตกหนักน้ำท่วมก็โป๊ะเชะกับที่โนอาห์กลัวพอดี<br />
<br />
ยิ่งพอถึงฉากสุดท้ายที่อิล่าบอกโนอาห์ หลังจากโนอาห์ตัดสินใจไม่ฆ่าล้างเผ่าพันธุ์มนุษย์ ปล่อยให้ลูกสาวของอิล่ามีชีวิตต่อไปหลังคลอด และอวยพรให้มีลูกเต็มบ้านมีหลานเต็มเมือง<br />
<br />
<blockquote>The choice was put in your hands because he put it there.<br />
<div style="text-align: right;">-- <cite>Ila, Noah (2014)</cite></div></blockquote><br />
ยิ่งแสดงให้เห็นว่ามนุษย์ไม่จำเป็นต้องพึ่งพาพระเจ้าก็ได้ หรือพูดอีกนัยหนึ่งว่ามนุษย์ไม่จำเป็นต้องพิสูจน์ทราบให้ได้ว่าพระเจ้ามีตัวตนจริงหรือไม่ เนื่องจากผลลัพธ์ที่ได้จากการพิสูจน์นี้ ไม่ได้ก่อให้เกิดความแตกต่างต่อสิ่งที่จะเกิดตามมาเลย (ทำนองเดียวกับที่ไอนสไตน์บอกว่าอีเทอร์ไม่จำเป็นนั่นแหละ)<br />
<br />
พระเจ้าที่ไร้อำนาจเช่นนี้ ก็คงไม่ต่างจากพระเจ้าที่ตายแล้วอย่างที่นิทเช่บอกไว้nzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-11322575648833540582015-04-16T08:00:00.000+07:002015-04-16T09:04:55.151+07:00Code Jam 2015 รอบคัดเลือก<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlSHAN2gcaIsr2pr1sMm9o-n3IIqGlchYXCwEkBtxzNGydK0ioGTsDetBIbnYJ8p1JH0gfA-HFqByiwwXBInFpyPWGJ-1AKm1RDIDupGIwQp4X2F8AE1X56sk8r_3ukh9FTocE2y0RYcWV/s1600/logo_image2.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlSHAN2gcaIsr2pr1sMm9o-n3IIqGlchYXCwEkBtxzNGydK0ioGTsDetBIbnYJ8p1JH0gfA-HFqByiwwXBInFpyPWGJ-1AKm1RDIDupGIwQp4X2F8AE1X56sk8r_3ukh9FTocE2y0RYcWV/s320/logo_image2.gif" height="120" width="120" /></a></div><br />
ปีนี้ประมาทไปเยอะครับ คือตอนแรกตั้งใจว่าจะถ่างตามาเริ่มเล่นตั้งแต่ปล่อยโจทย์ตอน 6 โมงเช้าเลย แต่สุดท้ายก็เผลอหลับไปตอนตี 4 ตื่นมารู้ตัวอีกทีก็บ่ายแล้ว เลยพักสมองออกเล่นบอร์ดเกมกะ <a href="https://twitter.com/tamwb">@tamwb</a> และ <a href="https://twitter.com/aibig">@aibig</a> ตามนัดปาร์ตี้สงกรานต์ แถมกลับมาก็ยังไม่มีสมาธิแก้โจทย์มัวแต่ดู MV เกาหลีอีก กว่าได้เริ่มทำแข่งจริงจังก็เหลือเวลาไม่กี่ชั่วโมงแล้ว<br />
<br />
ตอนอ่านโจทย์ผ่านๆ ทุกข้อนี่คิดว่าง่าย ปีนี้ได้แก้มือเก็บคะแนนเต็มแน่ๆ ... ที่ไหนได้ bug ซ่อนเร้น 1 ข้อ แล้วก็ตีความโจทย์อีก 1 ข้อ สุดท้ายแก้ไม่ทัน ได้ส่งแค่ 2 ข้อ ดีแค่ไหนแล้วที่ยังไม่ตกรอบ 555<br />
<br />
<hr /><br />
ข้อแรกง่ายฮะ แต่ถ้ายังอ่านโจทย์แล้วไม่อินขอให้ดูคลิปนี้ตอนนาทีที่ 7:05 และ 7:23 (เรียบร้อยแล้วก็กลับไปดูตั้งแต่ต้นด้วยจะดีมาก) :P<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="360" src="https://www.youtube.com/embed/danBaPWT09A" width="640"></iframe><br />
<br />
ส่วน code ก็ประมาณ<br />
<pre class="prettyprint hs">import Text.Printf (printf)
import Data.List.Split (splitOn)
invites audience =
let aux [] _ _ inv = inv
aux (p:ps) shy acc inv = aux ps (shy+1) (acc+p+more) (inv+more)
where more = max 0 (shy-acc)
in aux audience 0 0 0
test t = do
it <- getLine
let [_, ps] = splitOn " " it
printf "Case #%d: %d\n" t $ invites [read [p] :: Integer | p <- ps]
main = do
loop <- getLine
sequence_ [test t | t <- [1..read loop :: Integer]]
</pre>(อย่างไรก็ตาม เท่าที่เคยไปคอนเสิร์ตหลายครั้ง รู้สึกว่าคนไทยจะมีค่าความอายเป็น infinity นะ)<br />
<br />
<hr />ข้อสองข้ามไปนะฮะ ทำไม่ได้ (ข้อสี่ด้วย)<br />
<br />
ส่วนข้อสามนี่สนุกดี ถ้ายังจำเนื้อหาม.ปลายได้ เราจะมีเลขมหัศจรรย์ตัวนึงเรียกว่า <code>i</code> ซึ่งมีนิยามที่สวยงามเรียบง่าย คือ<br />
<pre>i^2 = -1
</pre>สังเกตเพิ่มอีกหน่อยก็จะเห็นว่า<br />
<pre>i^4 = 1 (multiplicative identity)
</pre>โจทย์เพิ่มความสนุกโดยให้ตัวเลขมหัศจรรย์ <code>j</code> และ <code>k</code> มาด้วย ทั้งสองตัวที่เพิ่มเข้ามานี้ มีนิยามแบบเดียวกันกะ <code>i</code> เด๊ะๆ เลย เพียงแต่มันไม่ใช่ <code>i</code> เพราะเรานิยามการคูณระหว่างตัวเลขเหล่านี้ว่า<br />
<pre>ij = k
jk = i
ki = j
</pre>ความซับซ้อนของตัวเลขชุดนี้ยังเพิ่มขึ้นไปอีก เมื่อเรานิยามให้มันไม่มีสมบัติสลับที่ด้วย ซึ่งในที่นี้คือ<br />
<pre>ji = -k
kj = -i
ik = -j
</pre>เพื่อความสะดวก สมมติชื่อให้เลขชุดนี้ว่า <code>ℍu</code> ละกันครับ โชคดีที่อย่างน้อยในเซ็ต <code>ℍu = {1, i, j, k}</code> มันยังมี<br />
<ul><li>สมบัติปิดบนการคูณ คือ ถ้าใช้การคูณอย่างเดียวบนสมาชิกของเซ็ต <code>ℍu</code> ผลลัพธ์ที่ได้ก็จะเป็นสมาชิกของเซ็ต <code>ℍu</code> ด้วย</li>
<li>สมบัติจัดกลุ่มการคูณ คือ <code>a(bc) = (ab)c</code> สำหรับทุก <code>a, b, c ∈ ℍu</code></li>
</ul>สรุปง่ายๆ ถ้าใครถนัดเรื่องการคูณไขว้เวกเตอร์ ก็นึกถึงกฎมือขวาได้เลย<br />
<br />
จาก <code>X, LS</code> ที่โจทย์ให้ การแก้ปัญหาแบบตรงๆ ก็คือวิ่งผ่านชุดตัวเลข <code>LS</code> เป็นจำนวน <code>X</code> ครั้ง โดยเลขแต่ละตัวเลข <code>s ∈ LS</code> ที่วิ่งผ่าน ก็จัดการคูณเก็บไว้ในใจไปเรื่อยๆ ถ้าเจอตัวเลขครบทั้ง <code>i, j, k</code> และหางที่เหลือคูณกันออกมาเป็น <code>1</code> ก็ตอบว่าถูกได้เลย<br />
<br />
ถ้าอ่านมาจนถึงตรงนี้แล้วยังงงไม่หาย ลองดูการทำงานตามขั้นตอนวิธีด้วยตัวอย่างนี้<br />
<pre>X = 10
LS = ji
sequence: ji ji ji ji ji ji ji ji ji ji
running: --->--->-------->----------->
found: i j k 1
</pre>โจทย์ข้อนี้ฉลาดตรงที่เอาตัวเลข <code>X</code>ขนาดใหญ่มากๆ มาขู่ ทั้งที่เราสามารถ modulo มันทิ้งให้เหลือแค่หลักสิบได้ (ซึ่งก็คือ คำถามชุดใหญ่จะมีความยากแทบไม่ต่างกับคำถามชุดเล็กเลย)<br />
<br />
การลดขนาด <code>X</code> ทำได้โดยใช้ข้อสังเกตที่ว่า <code>i^4 = j^4 = k^4 = 1</code> ซึ่งบอกเป็นนัยอยู่ 2 อย่างคือ<br />
<ul><li>ถ้าวิ่งคูณหา <code>i, j, k</code> แต่ละตัวเกิน 4 รอบแล้วยังไม่เจอ ไม่ต้องวิ่งต่อ เพราะแต่ละรอบที่วิ่งเพิ่ม จะไม่ได้ผลลัพธ์ใหม่แล้ว</li>
<li>หลังจากหา <code>i, j, k</code> ได้ครบแล้ว หางที่เหลือสามารถ mod 4 ได้</li>
</ul>ดังนั้น เราจะวิ่งผ่านชุดตัวเลขนี้ 3 ครั้ง (เพื่อหา <code>i, j, k</code>) โดยแต่ละครั้งวิ่งไม่เกิน 4 รอบ ซึ่งก็เท่ากับวิ่ง 12 รอบ แล้วรอบที่เหลือก็จับ mod 4 ได้เลย<br />
<br />
หรือพูดจาภาษา code ก็คือ<br />
<pre class="prettyprint">def correct_misspelling(ijks, x):
x = min(x, 12+(x%4))
accumulate = Quaternion('+1')
searching = [Quaternion(it) for it in 'kji']
for _ in range(x):
for it in ijks:
accumulate *= Quaternion(it)
if searching and searching[-1] == accumulate:
accumulate = Quaternion('+1')
searching.pop()
return not searching and accumulate == Quaternion('+1')
for case in range(int(input())):
_, x = [int(n) for n in input().split()]
ijks = input().strip()
ans = 'YES' if correct_misspelling(ijks, x) else 'NO'
print('Case #{}: {}'.format(case+1, ans))
</pre>ข้อนี้ถ้าจะ optimize เพิ่มก็ยังทำได้อีก (code จริงที่เอาไปส่งก็เขียนสวยน้อยกว่านี้เพราะมัวแต่ optimize มากเกินไป) โดยเรามีข้อสังเกตดังนี้<br />
<ul><li><code>aba = b</code> สำหรับทุก <code>a, b ∈ ℍu</code></li>
<li>เราสามารถทดเก็บค่าสุดท้ายที่ได้จากการวิ่งผ่านเพื่อหาผลคูณของทุกตัวใน <code>LS</code> ไว้ได้ แล้วพอจะวิ่งผ่าน <code>LS</code> อีกรอบก็ใช้ค่าที่ทดไว้ได้เลย</li>
<li>ในการทดลองจริง จำนวน <code>X</code> ที่จำเป็นต่อการคำนวณไม่เคยมีค่าเกิน 8 เลย ซึ่งก็คือ <code>x = min(x, 4+(x%4))</code> </li>
</ul>ถ้ายังอยากรู้ว่าข้อสังเกตเหล่านี้จริงหรือไม่ ถ้าจริงแล้วจะช่วยการคำนวณอย่างไร proof เพิ่มดูเองได้เลยครับ<br />
<br />
<script type="text/javascript">prettyPrint();</script>nzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-70903928248626383972015-03-08T00:46:00.002+07:002015-03-08T00:48:24.024+07:00คำถามญ. - ไม่ง่วงเหรอ<br />
<br />
ช. - ไม่จ้า<br />
<br />
ญ. - ไม่หิวเหรอ<br />
<br />
ช. - ยังอิ่มอยู่เลยจ้า<br />
<br />
ญ. - แล้วไม่คิดถึงเราเหรอnzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-75471261124938106102014-11-18T18:53:00.001+07:002014-11-18T18:53:10.848+07:00แอพ Calendar ตัวใหม่ของ Android Lollipop มาพร้อมกับภาพพาดหัวตอนนี้เวลาจดเหตุการณ์ใหม่ในแอพ calendar มันจะโชว์รูปด้วยถ้ามี keyword ไปตรงกับคำเตรียมไว้<br />
<br />
ดูแล้วน่ารักดีครับ ลองหาคร่าวๆ เจอเท่านี้ ใครเจออะไรอีกสะกิดบอกกันได้ :D<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioJ15Z_-hg5atGYtlcnPQsbkIoH3zXW91heusH3jQeYn8VNvUBwvz1WpcBM9ZZJiOvvn9iUa2ELnklyzo1ZPcjIBMsU_iX0-cOubocr5XYzSQy1FT_IrQI9B6jcAYpzqBSd3Ktp9zWztvn/s1600/bike.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioJ15Z_-hg5atGYtlcnPQsbkIoH3zXW91heusH3jQeYn8VNvUBwvz1WpcBM9ZZJiOvvn9iUa2ELnklyzo1ZPcjIBMsU_iX0-cOubocr5XYzSQy1FT_IrQI9B6jcAYpzqBSd3Ktp9zWztvn/s320/bike.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJLlUAiD73yaa5VpZUKgUMEYT7UZqj6eMY1jAScugyLtNF03v9Dh1G1-SbfFVB2LEB5mN00u0PGR8pY1r26LpaV6qsii7UtJmvWmQiQi_aGX20gfSjcasKMsWQDy7XiPF-wxVxxmjuHmWI/s1600/coffee.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJLlUAiD73yaa5VpZUKgUMEYT7UZqj6eMY1jAScugyLtNF03v9Dh1G1-SbfFVB2LEB5mN00u0PGR8pY1r26LpaV6qsii7UtJmvWmQiQi_aGX20gfSjcasKMsWQDy7XiPF-wxVxxmjuHmWI/s320/coffee.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIaNRiEAwTp42IMExyNlZ4STsUix7gidMC8MAo80Dg6RxN_-BjTft3d2HWjIzfFSc5uSFMMSa-4VB0ZRvAw-krogbkeTdV8DNkE8h_Udsf7F30Cas0OVMqvucZV8sr5pw8g5PGLB37kdO2/s1600/concert.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIaNRiEAwTp42IMExyNlZ4STsUix7gidMC8MAo80Dg6RxN_-BjTft3d2HWjIzfFSc5uSFMMSa-4VB0ZRvAw-krogbkeTdV8DNkE8h_Udsf7F30Cas0OVMqvucZV8sr5pw8g5PGLB37kdO2/s320/concert.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiOA7zLmpO_s-EzAU-qRb4zUTgFBgTOzvXctjjqyuSUiw-8AYPTxEVo51HxSEj5LFCNJBpJDiZK9KvMdfGadGjL4gh_yBYsrp_ql5NeiIJAr8oy9qJBHoztu-Y2FCR5LsZl7QXJ4bYhyphenhyphenN3/s1600/dentist.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiOA7zLmpO_s-EzAU-qRb4zUTgFBgTOzvXctjjqyuSUiw-8AYPTxEVo51HxSEj5LFCNJBpJDiZK9KvMdfGadGjL4gh_yBYsrp_ql5NeiIJAr8oy9qJBHoztu-Y2FCR5LsZl7QXJ4bYhyphenhyphenN3/s320/dentist.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgytYWT6c44fEs4vmuZN-Vs91ukMdwR4xS2HsHtTxXqN9zzqXd0CxKXWyPyncYvKITpxhlc1CVibiyhrRVLUOmMflcIz1VSTrBUXQ2NBxBqMQ5EJG_kXmWOEiDpAixmIM6CqwxVeWy7UorS/s1600/dinner.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgytYWT6c44fEs4vmuZN-Vs91ukMdwR4xS2HsHtTxXqN9zzqXd0CxKXWyPyncYvKITpxhlc1CVibiyhrRVLUOmMflcIz1VSTrBUXQ2NBxBqMQ5EJG_kXmWOEiDpAixmIM6CqwxVeWy7UorS/s320/dinner.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg32nq7bUgIkOnsFNPnaQD0YbTerIf0qSOAZIMXOZw-bJGb7t7fF8j2Kr4UzJguMWxVeQDA6SaWHUzTjLGDJ4JRmVcxL8kVhEb0uFg0qeiU5ktZfXuaYa4H2f2bdvuCTP0n_pfJYnBUFq3p/s1600/drinks.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg32nq7bUgIkOnsFNPnaQD0YbTerIf0qSOAZIMXOZw-bJGb7t7fF8j2Kr4UzJguMWxVeQDA6SaWHUzTjLGDJ4JRmVcxL8kVhEb0uFg0qeiU5ktZfXuaYa4H2f2bdvuCTP0n_pfJYnBUFq3p/s320/drinks.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgx_W_uMIiwYeuhUlwf79Ty2Yym9YqbfR3MeYD2V8dFbcniM5F38IZtJ5DqqKVhMvU0OOOFARB1k7XWN1zPBXYSOYHPHm4f4enoRQDItbacJ2-mk_ywNhwGRojaQqHpvtCRtKatswVslkef/s1600/gym.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgx_W_uMIiwYeuhUlwf79Ty2Yym9YqbfR3MeYD2V8dFbcniM5F38IZtJ5DqqKVhMvU0OOOFARB1k7XWN1zPBXYSOYHPHm4f4enoRQDItbacJ2-mk_ywNhwGRojaQqHpvtCRtKatswVslkef/s320/gym.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-RF7telAwgs3eiFR0PknAf5b3khxwPKW9e6z7MXZhc8SC2HgTErPo4LbaTgKoB11b3-xNHrYZtrnpLCKsBv3Kw5Bk2f5ajT62-aBbwMnsR8S1qrK4IxKe1Y5oVDEiHXsLV3fWxZBXq4XX/s1600/movie.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-RF7telAwgs3eiFR0PknAf5b3khxwPKW9e6z7MXZhc8SC2HgTErPo4LbaTgKoB11b3-xNHrYZtrnpLCKsBv3Kw5Bk2f5ajT62-aBbwMnsR8S1qrK4IxKe1Y5oVDEiHXsLV3fWxZBXq4XX/s320/movie.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNliJof7h1oIznaz9ZWZ9I_5dt_y1uS4jwbcmAEIxTqhUD8KGQ4pFWEnr31S7WGxtdB4g3wXknUoy8BJCtCAguIPZbviZJNTChEektd4dVwkZB6vqcRsAKy8aEjJWAgByK-cmVO_U8f5ni/s1600/running.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNliJof7h1oIznaz9ZWZ9I_5dt_y1uS4jwbcmAEIxTqhUD8KGQ4pFWEnr31S7WGxtdB4g3wXknUoy8BJCtCAguIPZbviZJNTChEektd4dVwkZB6vqcRsAKy8aEjJWAgByK-cmVO_U8f5ni/s320/running.png" /></a>nzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0tag:blogger.com,1999:blog-3315871573509944618.post-16081432408644806072014-11-03T20:52:00.000+07:002014-11-03T20:52:57.432+07:00Code Mania 01 และทำไมถึงควรเลิกเขียน JavaScriptเสาร์ที่ผ่านมาไปพูดเรื่อง "เลิกเขียน JavaScript กันดีกว่า" ในงาน Code Mania ที่จุฬาฯ มาครับ<br />
<br />
คุณ <a href="https://twitter.com/KaizerWing">@KaizerWing</a> ให้เวลาเตรียมตัวล่วงหน้ามาเป็นเดือนแล้ว ตอนนั้นหัวโล่งๆ ยังมองภาพไม่ออกว่างานจะออกมาหน้าตายังไง เลยเลือกเรื่องที่คุ้นมือมากที่สุดในตอนนี้อย่าง CoffeeScript ไปพูด<br />
<br />
แต่ครั้นจะพูด CoffeeScript เพียวๆ เลยเดี๋ยวคนจะตามไม่ทัน เลยหาจุดเชื่อมโยงเป็น JavaScript ที่มีจุดประหลาดน่าสนใจและคนเขียนเยอะมาปูเรื่องครับ<br />
<br />
เสียดายว่าแอบขี้เกียจไปหน่อย ตอนช่วงท้ายๆ เลยปิดไม่ค่อยดีเท่าไหร่ ถ้าเพิ่มสไลด์สำคัญๆ ไปอีกซัก 2 แผ่นน่าจะเรียกเสียงฮือฮาได้มากกว่านี้นะ<br />
<br />
สไลด์อยู่นี่ครับ ส่วนทีมงานบอกมาว่ากำลังตัดต่อวิดีโออยู่ เรียบร้อยเมื่อไหร่เดี๋ยวผมมา update อีกที<br />
<br />
<iframe src="https://docs.google.com/presentation/d/13UNJhDfYcqqhFj2UwXJtdTif0Dh1d8MHcetjBszkQQs/embed?start=false&loop=false&delayms=3000" frameborder="0" width="960" height="749" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe><br />
<br />
งานนี้สนุกมากครับ รู้สึกว่าสนุกกว่า BarCamp ที่ช่วงหลังๆ เริ่มแผ่วแล้วด้วย ก็หวังว่าจะมีงานทำนองนี้ออกมาอีกเรื่อยๆ อาจจะจัดหลายวันเป็นแคมป์กิน-นอน-เต้นรอบกองไฟก็น่าสนนะครับ :Dnzhttp://www.blogger.com/profile/10171114357660634238noreply@blogger.com0