![]() ![]() |
Mar 8 2009, 12:45 AM
Post
#1
|
|
![]() Committee Group: Committee Posts: 6995 Joined: 1-April 03 From: Chicago, IL Member No.: 226 |
ผมอยากให้กระทู้นี้เป็นกระทู้ที่สมาชิกทุกคนสามารถลองหัดเขียนโปรแกรมแก้ปัญหาสั้นๆ และฟังความคิดเห็นของคนอื่นว่าควรจะปรับปรุงโค้ดอย่างไร โดย *ไม่ระบุ* ภาษาที่เขียน จะใช้ภาษาไหนก็ได้ตามแต่ถนัด โดยมีจุดประสงค์ให้เห็นว่าปัญหาเดียวกัน แต่ละภาษาจะเขียนออกมาในรูปแบบใด และเราสามารถปรับปรุงโค้ดให้ดีขึ้นได้อย่างไร
โจทย์ครั้งนี้คือ เรามีไฟล์ input.txt ที่มีข้อมูลเรคอร์ดละหนึ่งบรรทัด แต่ละเรคอร์ดมีฟิวด์แยกด้วยเครื่องหมาย | เป้าหมายคือ เราต้องการให้แสดงผลลัพธ์ออกจอ ให้เรียงข้อมูลเรคอร์ดจากตัวเลขในฟิวด์แรกเริ่มจากน้อยไปมาก และในแต่ละเรคอร์ดที่แสดง แต่ละฟิวด์จะเรียงจากน้อยไปมากแยกด้วยช่องว่าง เช่นตัวอย่างข้างล่าง ข้อมูลอินพุท ไฟล์ input.txt 3|hello|world|bangkok 4|monkey|ant|dog|cow|cat 2|pink|yellow|red|magenta 1|earth|sun|jupiter|pluto ผลลัพธ์ที่ต้องการ พิมพ์ออกจอ 1 earth jupiter pluto sun 2 magenta pink red yellow 3 bangkok hello world 4 ant cat cow dog monkey ผมคิดว่าตัวอย่างนี้สั้นพอที่จะใช้เวลาเขียนภายในสิบห้านาที และผมอยากให้สมาชิกทุกคนลองคิดและใช้เวลาเขียนแก้ปัญหาด้วยภาษาที่ตนถนัด หรืออยากลองใช้ โดยมีกติกาดังนี้ - ใส่ซอร์สโค้ดด้วยการตอบกระทู้นี้ และ copy & paste ซอร์สโค้ดไว้ใน code tag - โค้ดที่เขียนควรกระชับ อ่านง่าย ไม่จำเป็นต้องคอมเมนต์ ยกเว้นส่วนที่คิดว่าจะมีประโยชน์ในการไล่โค้ด - โค้ดไม่จำเป็นต้องเพอร์เฟค ขอให้ทำงานได้ ถ้ามีจุดที่น่าปรับปรุง สมาชิกท่านอื่นสามารถวิจารณ์เชิงสร้างสรรค์ให้ได้ - ช่วยระบุชื่อไฟล์ซอร์สโค้ดและภาษาที่ใช้ เผื่อคนอื่นจะสามารถ copy ไปทดลองรันได้ - อยากให้มีตัวอย่างหลายๆภาษา ใครอยากลองเขียนภาษาไหน ลองใช้โจทย์นี้เป็นแบบฝึกหัด และจะเป็นการเปิดหูเปิดตาให้สมาชิกที่ไม่คุ้นเคยกับภาษาอื่น ดูว่าหน้าตาภาษาอื่นเป็นอย่างไร - ทุกคนสามารถวิจารณ์เชิงสร้างสรรค์โค้ดที่คนอื่นโพสต์ไว้ เพื่อเป็นประโยชน์ต่อการปรับปรุงการเขียนโปรแกรม ผมอยากให้สมาชิกทั้งเก่าทั้งใหม่ ทั้งที่โพสต์บ่อยๆ หรือกลุ่มอ่านอย่างเดียว มีโอกาสได้ร่วมมือกันโพสต์โค้ดกันเยอะๆ ลองคิดและหัดเขียนกัน ดูสิว่างานนี้จะมีคนร่วมมือกันมากแค่ไหน และจะมีภาษาไหนให้ดูกันบ้าง QUOTE *ป.ล. ข้อมูลเพิ่ม* ขอเพิ่มความชัดเจนให้กับโจทย์ สองกรณี
- การเรียงเรคอร์ดจากคอลัมน์แรก ต้องเรียงตามค่าตัวเลข เช่น 10 ตามหลัง 9 จะเรียงตามสตริงไม่ได้ - ในแต่ละเรคอร์ด จะคงค่าตัวเลขในคอลัมน์แรกไว้ และเรียงค่าในคอลัมน์ที่สองเป็นต้นไป This post has been edited by นายข้าวโพดหวาน: Mar 9 2009, 01:48 PM |
|
|
|
Mar 8 2009, 01:58 AM
Post
#2
|
|
![]() Star Group: Star Posts: 1537 Joined: 11-October 03 From: Bangkok Member No.: 850 |
Python 3.0.1 - [name อะไรก็ได้]
CODE __author__="nuboat" __date__ ="$8 มี.ค. 2552" filename = "test.txt" if __name__ == "__main__": try: infile = open(filename,"r") lines = infile.readlines() lines.sort() for line in lines: attr = line.strip().split("|") attr.sort() print(attr) finally: infile.close() โค้ดง่ายๆแต่ไม่ได้เขียนนานมากลืมหมด ผมนี่เวลาเขียนพวกภาษา script แบบนี้พอไม่ได้ใช้สักพักจะจำอะไรไม่ได้เลย แบบเขียนใหม่ก็เปิด document กันใหม่ แถม py3 เปลี่ยน print attr เป็น print(attr) อีกหานานมากว่า systam error ที่ไหน ทั้งที่มันก็แดงกันเห็นๆ CODE __author__="nuboat" __date__ ="$8 มี.ค. 2552" filename = "test.txt" if __name__ == "__main__": for line in sorted( open(filename,"r").readlines() ): print( sorted(line.strip().split("|")) ) รู้สึกโค้ดแรกยาวไปอ่านยากมากเลยทำให้สั้นๆ ปล. สำหรับคนที่อยากโหลดมาลองครับ Python 3.0.1 This post has been edited by aiboat: Mar 8 2009, 11:26 AM |
|
|
|
Mar 8 2009, 02:17 AM
Post
#3
|
|
|
Senior member ![]() ![]() ![]() Group: Members Posts: 575 Joined: 24-March 05 From: Bangkok Member No.: 3355 |
CODE using System; using System.Collections.Generic; class FunCode { static void Main(string[] args) { string[] inputs = System.IO.File.ReadAllLines("input.txt"); SortedList<int, List<string>> list = new SortedList<int, List<string>>(); foreach (string input in inputs) { List<string> items = new List<string>(input.Split('|')); items.Sort(1, items.Count-1, Comparer<string>.Default); list.Add(int.Parse(items[0]), items); } foreach (int key in list.Keys) { foreach (string item in list[key]) { Console.Write(item + " "); } Console.WriteLine(); } } } C# ครับ |
|
|
|
Mar 8 2009, 02:26 AM
Post
#4
|
|
![]() Star Group: Star Posts: 652 Joined: 23-July 04 From: Nowhere Member No.: 2060 |
Groovy 1.6 ครับ
CODE def result=new TreeMap() new File("input.txt").eachLine { def l = it.split("\\|") result[l[0]] = l[1..-1].sort() } result.each { k, v -> print "${k}"; v.each{ print " ${it}" } println() } ผมอธิบายละเอียดไว้บน gist: http://gist.github.com/75419 ปล. ใบ้ให้ว่ามี bug ด้วยครับ This post has been edited by cblue: Mar 8 2009, 03:09 AM |
|
|
|
Mar 8 2009, 02:36 AM
Post
#5
|
|
|
Member ![]() ![]() Group: Members Posts: 238 Joined: 11-July 06 Member No.: 7700 |
Groovy เหมือนกันครับ เขียนไม่ทันคน cblue
CODE def arrayString = []; def file = new File('input.txt') file.eachLine { arrayString << it } arrayString.sort { a, b -> def alist = a.split("\\|") def blist = b.split("\\|") new Integer(alist[0]) <=> new Integer(blist[0]) // <=> it mean compareTo() in java } arrayString.each { line -> def ls = line.split("\\|") ls.sort() println ls.join(" ") } รอบที่ 5 This post has been edited by SouLsKI: Mar 8 2009, 03:26 AM |
|
|
|
Mar 8 2009, 03:11 AM
Post
#6
|
|
|
Senior member ![]() ![]() ![]() Group: Members Posts: 575 Joined: 24-March 05 From: Bangkok Member No.: 3355 |
ผมไม่เคยเขียน Python มาก่อนแต่ก็อดสงสัย code ของคุณ aiboat ไม่ได้
lines.sort() และ attr.sort() อันนี้น่าจะหมายถึง Sort ด้วย String ธรรมดาหรือเปล่าครับ หรือว่า Python ฉลาดกว่านั้น ถ้าเป็นเช่นนั้นหากเรามี input เป็น 13|hello|world|bangkok 4|1monkey|ant|dog|cow|cat 2|pink|yellow|red|magenta 1|earth|sun|jupiter|pluto จะได้ผลเป็น 13 bangkok hello world 1 earth jupiter pluto sun 2 magenta pink red yellow 1monkey 4 ant cat cow dog ซึ่งมันน่าจะไม่ตรงกับโจทย์หรือเปล่าครับ ? |
|
|
|
Mar 8 2009, 03:12 AM
Post
#7
|
|
|
Member ![]() ![]() Group: Members Posts: 238 Joined: 11-July 06 Member No.: 7700 |
ผมแก้ code ไป 4 รอบละคืนนี้กว่าจะออกมาได้ถูก
|
|
|
|
Mar 8 2009, 03:16 AM
Post
#8
|
|
|
Senior member ![]() ![]() ![]() Group: Members Posts: 575 Joined: 24-March 05 From: Bangkok Member No.: 3355 |
ผมไม่เคยเขียน Groovy เหมือนกัน
จึงได้แต่แอบสงสัยในความสามารถพวกภาษา Script ว่ามันฉลาดขนาดนั้นเลยหรือ ? เคยจับ Ruby อยู่แป๊บนึง แต่ก็คิดว่ามันไม่น่าจะทำได้ ดังนั้นพอตาม link คุณ cblue เข้าไปอ่าน comment ก็พอรู้ล่ะครับ |
|
|
|
Mar 8 2009, 03:32 AM
Post
#9
|
|
|
Member ![]() ![]() Group: Members Posts: 238 Joined: 11-July 06 Member No.: 7700 |
คุณ cblue ครับช่วยอธิบายหน่อยครับว่าค่า v นี้ groovy มันจะรู้เองเลยหรือครับว่าเป็น array index ที่ 1 จนถึงตัวสุดท้ายและ มันเอามาจากไหนครับงง
พอดีเพิ่งเริ่ม เขียน groovy ยังไม่เคยเค้าใจ |
|
|
|
Mar 8 2009, 03:48 AM
Post
#10
|
|
|
Senior member ![]() ![]() ![]() Group: Members Posts: 575 Joined: 24-March 05 From: Bangkok Member No.: 3355 |
คุณ cblue ครับช่วยอธิบายหน่อยครับว่าค่า v นี้ groovy มันจะรู้เองเลยหรือครับว่าเป็น array index ที่ 1 จนถึงตัวสุดท้ายและ มันเอามาจากไหนครับงง พอดีเพิ่งเริ่ม เขียน groovy ยังไม่เคยเค้าใจ ถึงผมจะไม่เคยเขียน Groovy แต่ก็พอจะเข้าใจ code นี้อยู่บ้างครับ คือ result ไม่ใช่ array นะครับ แต่เป็น Tree Map ซึ่งเก็บค่า Key และ Value(ที่เป็น List อีกทีหนึ่ง) คุณ SouLsKI น่าจะเข้าใจว่ามันเป็น array ชุดเดียวกันอย่าง [1, earth, jupiter, pluto, sun] เมื่อวนลูปแล้ว k=1, ส่วน v=earth จากนั้นวนลูป v ก็จะวิ่งไปจนถึง v=sun ซึ่งไม่ใช่นะครับ (ถ้าผมอนุมานคสามเข้าใจของคุณ SouLsKI ผิดก็ขออภัย) แต่โครงสร้างใน Tree Map หลังจาก Sort แล้วเป็นดังนี้ k=1, v= [earth, jupiter, pluto, sun] k=2, v= [magenta, pink, red, yellow] k=3, v= [bangkok, hello, world] k=4, v= [ant, cat, cow, dog, monkey] result.each { k, v -> จึงหมายถึงการวนแต่ละลูป โดยให้ค่า k=Key และ v=Value เนื่องจาก Value ที่เก็บใน Tree Map เป็น List ของ String จึงนำมาวนลูปได้อีกเป็น v.each{ print " ${it}" This post has been edited by Bleak: Mar 8 2009, 03:58 AM |
|
|
|
Mar 8 2009, 03:49 AM
Post
#11
|
|
![]() Star Group: Star Posts: 652 Joined: 23-July 04 From: Nowhere Member No.: 2060 |
QUOTE v นี้ groovy มันจะรู้เองเลยหรือครับว่าเป็น array index ที่ 1 จนถึงตัวสุดท้ายและ มันเอามาจากไหนครับ map.each { k, v -> } each ตัวนี้เป็น each บน java.list.Map ครับ มันใช้ iterator ของ set ที่คืนมาจาก Map.entrySet() ครับ ใน entry ก็จะมี getKey() กับ getValue() ที่จะโดนดึงค่าเอามา bind ให้กับ k และ v http://java.sun.com/j2se/1.5.0/docs/api/ja...#entrySet%28%29 |
|
|
|
Mar 8 2009, 05:09 AM
Post
#12
|
|
|
Junior Member ![]() Group: Members Posts: 57 Joined: 29-October 04 Member No.: 2576 |
C# 3.0 with LINQ
หลายๆ อย่างลอกมาจากของคุณ Bleak ครับ CODE using System;
using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; namespace NarisaFunCode { class Program { static void Main(string[] args) { string[] records = File.ReadAllLines("input.txt"); var rs = from r in records let ia = r.Split('|') let ca = ia.Skip(1).OrderBy(x => x) let ra = ia.Take(1).Concat(ca).ToArray() orderby ia[0] select string.Join(" ", ra); foreach (var r in rs) { Console.WriteLine(r); } Console.ReadKey(); } } } This post has been edited by tuckclub: Mar 8 2009, 05:21 AM |
|
|
|
Mar 8 2009, 05:19 AM
Post
#13
|
|
![]() Committee Group: Committee Posts: 6995 Joined: 1-April 03 From: Chicago, IL Member No.: 226 |
ไม่คิดว่าจะมีคนตอบเร็วขนาดนี้ มือปืนกันจริงๆ
โจทย์ไม่ละเอียดจริงๆครับ เพราะไม่ได้ระบุว่าฟิวด์แรกที่เป็นตัวเลขจะ sort ตามค่าหมายเลขหรือมองเป็นสตริง ยกประโยชน์ให้จำเลย จะ sort แบบไหนก็ได้ครับ ถ้าเขียนด้วยรูบี้ จะเขียนเป็นแบบ script หรือ OO ก็ได้ ผมยกตัวอย่างทั้งสองแบบ 1. แบบ script CODE lines = IO.readlines('input.txt').map { |line| line.chomp.split('|').sort } lines.sort.each { |line| puts line.join(' ') } 2. แบบ OO CODE class Sorty def initialize(file_name) @file_name = file_name end def show_sort lines = IO.readlines(@file_name).map { |line| line.chomp.split('|').sort } lines.sort.each { |line| puts line.join(' ') } end end Sorty.new('input.txt').show_sort กำลังรอตัวอย่างภาษาจาวา. Haskell, Scala, shell script, Clojure, Erlang มีใครอาสาเขียนบ้างครับ This post has been edited by นายข้าวโพดหวาน: Mar 8 2009, 05:32 AM |
|
|
|
Mar 8 2009, 05:56 AM
Post
#14
|
|
|
Junior Member ![]() Group: Members Posts: 57 Joined: 29-October 04 Member No.: 2576 |
Java
มีข้อจำกัดครับ ห้ามเกิน 9 เรคคอร์ด ไม่เช่นนั้นจะได้พบกับสิ่งที่เรียกว่า บั๊ก CODE import java.io.BufferedReader;
import java.io.FileReader; import java.io.Reader; import java.util.Arrays; import java.util.SortedSet; import java.util.TreeSet; public class NarisaFunCode { public static void main(String[] args) throws Exception { Reader r = new FileReader("input.txt"); BufferedReader br = new BufferedReader(r); SortedSet<String> ss = new TreeSet<String>(); String line; while ((line = br.readLine()) != null) { String[] ia = line.split("\\|"); Arrays.sort(ia, 1, ia.length); ss.add(join(" ", ia)); } for (String s : ss) { System.out.println(s); } } private static String join(String sp, String[] sa) { StringBuilder sb = new StringBuilder(); for (String s : sa) { sb.append(s); sb.append(sp); } return sb.toString(); } } This post has been edited by tuckclub: Mar 8 2009, 06:05 AM |
|
|
|
Mar 8 2009, 05:59 AM
Post
#15
|
|
![]() Committee Group: Committee Posts: 6995 Joined: 1-April 03 From: Chicago, IL Member No.: 226 |
สำหรับกรณีที่คุณ cblue เขียน ดักเพิ่มสองกรณี
1. sort ด้วยค่าตัวเลขจากฟิวด์แรกแทนที่จะมองเป็นสตริง (เลข 10 ควรอยู่หลังเลข 9 แม้ว่า 10 จะมีตัวเลขแรกคือ 1) CODE lines = IO.readlines('input.txt').map { |line| line.chomp.split('|').sort } lines.sort { |one, another| one[0].to_i <=> another[0].to_i }.each do |line| puts line.join(' ') end ในรูบี้สามารถปรับแต่งการ sort โดยการเปรียบเทียบแต่ละคู่ที่จะเรียงด้วยเครื่องหมาย <=> (เหมือนกับ Groovy และเมธอด compareTo() ในจาวา) โดยกรณีนี้เลือกเรียงจากฟิวด์แรก (index ที่ 0) โดยแปลงเป็นตัวเลขด้วย to_i 2. เพิ่มจากข้อ 1 ในแต่ละแถว จะเรียงฟิวด์เริ่มจากตัวที่ 2 จนถึงตัวสุดท้าย นั่นคือไม่เอาฟิวด์แรกที่เป็นตัวเลขมา sort ด้วย CODE lines = IO.readlines('input.txt').map do |line| items = line.chomp.split('|') head = items.shift items.sort.unshift(head) end lines.sort { |one, another| one[0].to_i <=> another[0].to_i }.each do |line| puts line.join(' ') end ผมเลือกใช้ตัวอย่างที่ไม่ใช้ TreeMap แต่ใช้วิธีถอดฟิวด์แรกออกมาจากแอร์เรย์ แล้ว sort ฟิวด์ที่เหลือ ก่อนที่จะปะหัวกลับไปแทน กรณีที่สองนี้ ถ้าเรารู้ว่าข้อมูลไม่ใช่ตัวเลข ก็ไม่จำเป็นต้องใช้วิธีนี้ โซลูชั่นจากวิธีในข้อแรก ก็เพียงพอแล้วครับ This post has been edited by นายข้าวโพดหวาน: Mar 8 2009, 06:03 AM |
|
|
|
![]() ![]() |
|
Lo-Fi Version | Time is now: 9th February 2010 - 08:11 PM |