Alien Numbers ไม่ได้เขียน blog มานานมาก แต่ว่าตอนนี้มีองค์ประกอบดีๆ 3 อย่างคือ 1. เพิ่งพลาดไม่ได้ join codejam เลยต้องฝึกฝีมือเผื่อปีหน้า 2. กำลังหัดเขียน f# 3. ช่วงนี้งานค่อนข้างโอเค ไม่ยุ่งมาก เลยตั้งเป้าว่า solve codejam ไปเรื่อย ๆ ด้วย f# และเขียน blog ไปด้วย เริ่มที่ข้อแรก Alien Numbers โจทย์คือ จะมีตัวเลขภาษาต่างดาวมา 2 ชุด ให้แปลจากตัวเลขภาษานึงไปอีกภาษานึง สมมติมนุษย์ใช้เลขอารบิก 0123456789 มนุษย์ต่างดาวใช้เลข hex 0123456789abcdef ดังนั้นเลข 10 จะเท่ากับ a มนุษย์ต่างดาวไม่ได้ใช้ภาษาเหมือนเรา 0-9 ของเขาอาจจะเป็น )!@#$%^&*( แต่หลักการนับเหมือนเลขของมนุษย์ทุกอย่าง อ่านรายละเอียดเพิ่ม ที่นี่ครับ โจทย์ข้อนี้ถือว่าง่ายมาก ถ้ารู้จักเลขฐานก็สบายเลย วิธีคิดคือให้แปลจากภาษาแรกเป็น int ก่อน แล้วจาก int ค่อยแปลเป็นภาษาที่สอง เริ่มจาก function หลัก let solve value txt1 txt2 = function ชื่อ solve value คือ เลขที่ต้องแปล เช่น foo txt1 คือ ชุดตัวเลขของเลขที่ต้องแปล เช่น of8 txt2 คือ ชุดตัวเลขอีกภาษานึง ที่เราต้องการแปลเป็นภาษานี้ เช่น 0123456789 value type เป็น string ส่วน txt1 กับ txt2 เป็น char[] function การแปลจาก txt1 เป็น int คือ let txtToNum txt v = baseN คือ จำนวนเลขฐาน เช่น of8 เป็นเลขฐาน 3 foldFn คือ สูตรการคำนวนเลขฐานอื่นๆ เป็น int โดยเอาเลขก่อนหน้า (a) x เลขฐาน (baseN) + ค่าของตัวอักษรนั้น เช่นเลข foo จาก of8 โดยถ้านับตามตำแหน่ง f เท่ากับ 1 ส่วน o เท่ากับ 0 f = 1 fo = 1 * 3 + 0 = 3 foo = 3 * 3 + 0 = 9 ดังนั้น foo = 9 function การแปลจาก int เป็น txt2 คือ let numToTxt txt v = unfoldFn คือ function แปลเลข int เป็นเลขฐานใด ๆ สมมติเป็นเลข 454 และต้องการแปลเป็นเลขฐาน 6 454 / 6 ได้ 75 เศษ 4 75 / 6 ได้ 12 เศษ 3 12 / 6 ได้ 2 เศษ 0 2 / 6 ได้ 0 เศษ 2 เราจะได้ 4,3,0,2 ผลลัพธ์ที่ได้ต้องอ่านย้อนหลัง เราเลยต้อง call Enumerable.Reverse เป็น 2,0,3,4 Seq.map (Array.get txt) คือการ map กับอีกชุดอักษร เช่น 2,0,3,4 map กับ A?JM!. ก็จะกลายเป็น J,A,M,! แล้ว Seq.map string กับ String.Concat คือ แปลงเป็น string จาก J,A,M,! เป็น JAM! เวลาเรียก function ก็ง่าย value |> txtToNum txt1 โยน value เข้าไป txtToNum และเอาผลลัพธ์ไป numToTxt จบ |