IPB

Welcome Guest ( Log In | Register )

6 Pages V   1 2 3 > »   
Reply to this topicStart new topic
> มาฝึกหัดเขียนโปรแกรมแก้ปัญหาสั้นๆกัน, เขียนด้วยภาษาไหนก็ได้ มาประชันกัน
นายข้าวโพดหวาน
post Mar 8 2009, 12:45 AM
Post #1


Committee
Group Icon

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
Go to the top of the page
 
+Quote Post
nuboat
post Mar 8 2009, 01:58 AM
Post #2


Star
Group Icon

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 กันใหม่ tongue.gif
แถม 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
Go to the top of the page
 
+Quote Post
Bleak
post 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# ครับ
Go to the top of the page
 
+Quote Post
cblue
post Mar 8 2009, 02:26 AM
Post #4


Star
Group Icon

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
Go to the top of the page
 
+Quote Post
SouLsKI
post Mar 8 2009, 02:36 AM
Post #5


Member
**

Group: Members
Posts: 238
Joined: 11-July 06
Member No.: 7700



Groovy เหมือนกันครับ เขียนไม่ทันคน cblue biggrin.gif

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 wacko.gif

This post has been edited by SouLsKI: Mar 8 2009, 03:26 AM
Go to the top of the page
 
+Quote Post
Bleak
post 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

ซึ่งมันน่าจะไม่ตรงกับโจทย์หรือเปล่าครับ ?
Go to the top of the page
 
+Quote Post
SouLsKI
post Mar 8 2009, 03:12 AM
Post #7


Member
**

Group: Members
Posts: 238
Joined: 11-July 06
Member No.: 7700



ผมแก้ code ไป 4 รอบละคืนนี้กว่าจะออกมาได้ถูก sleep.gif"
Go to the top of the page
 
+Quote Post
Bleak
post 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 ก็พอรู้ล่ะครับ

biggrin.gif
Go to the top of the page
 
+Quote Post
SouLsKI
post 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 ยังไม่เคยเค้าใจ
Go to the top of the page
 
+Quote Post
Bleak
post Mar 8 2009, 03:48 AM
Post #10


Senior member
***

Group: Members
Posts: 575
Joined: 24-March 05
From: Bangkok
Member No.: 3355



QUOTE (SouLsKI @ Mar 8 2009, 03:32 AM) *
คุณ 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
Go to the top of the page
 
+Quote Post
cblue
post Mar 8 2009, 03:49 AM
Post #11


Star
Group Icon

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
Go to the top of the page
 
+Quote Post
tuckclub
post 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
Go to the top of the page
 
+Quote Post
นายข้าวโพดหวาน
post Mar 8 2009, 05:19 AM
Post #13


Committee
Group Icon

Group: Committee
Posts: 6995
Joined: 1-April 03
From: Chicago, IL
Member No.: 226



ไม่คิดว่าจะมีคนตอบเร็วขนาดนี้ มือปืนกันจริงๆ biggrin.gif ตอนนี้มีตัวอย่างภาษา Groovy, Python, C#, C# with LINQ (คาดไม่ถึงว่าเอา LINQ มาใช้กับปัญหานี้ได้ด้วย - น่าสนใจ) ล่ะ เอ แล้วจาวาหายไหน

โจทย์ไม่ละเอียดจริงๆครับ เพราะไม่ได้ระบุว่าฟิวด์แรกที่เป็นตัวเลขจะ 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
Go to the top of the page
 
+Quote Post
tuckclub
post 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
Go to the top of the page
 
+Quote Post
นายข้าวโพดหวาน
post Mar 8 2009, 05:59 AM
Post #15


Committee
Group Icon

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
Go to the top of the page
 
+Quote Post

6 Pages V   1 2 3 > » 
Reply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 



RSS Lo-Fi Version Time is now: 9th February 2010 - 08:11 PM