Narisa.com: มาฝึกหัดเขียนโปรแกรมแก้ปัญหาสั้นๆกัน - Narisa.com

Jump to content

  • (6 Pages)
  • +
  • 1
  • 2
  • 3
  • Last »
  • You cannot start a new topic
  • You cannot reply to this topic

มาฝึกหัดเขียนโปรแกรมแก้ปัญหาสั้นๆกัน เขียนด้วยภาษาไหนก็ได้ มาประชันกัน Rate Topic: -----

#1 User is offline   นายข้าวโพดหวาน 

  • Committee
  • View blog
  • Group: Committee
  • Posts: 7075
  • Joined: 01-April 03

Posted 08 March 2009 - 12:45 AM

ผมอยากให้กระทู้นี้เป็นกระทู้ที่สมาชิกทุกคนสามารถลองหัดเขียนโปรแกรมแก้ปัญหาสั้นๆ และฟังความคิดเห็นของคนอื่นว่าควรจะปรับปรุงโค้ดอย่างไร โดย *ไม่ระบุ* ภาษาที่เขียน จะใช้ภาษาไหนก็ได้ตามแต่ถนัด โดยมีจุดประสงค์ให้เห็นว่าปัญหาเดียวกัน แต่ละภาษาจะเขียนออกมาในรูปแบบใด และเราสามารถปรับปรุงโค้ดให้ดีขึ้นได้อย่างไร

โจทย์ครั้งนี้คือ เรามีไฟล์ 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 นายข้าวโพดหวาน: 09 March 2009 - 01:48 PM

0

#2 User is offline   nuboat 

  • Star
  • Group: Star
  • Posts: 1654
  • Joined: 11-October 03

Posted 08 March 2009 - 01:58 AM

Python 3.0.1 - [name อะไรก็ได้]
__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 กันใหม่ :P
แถม py3 เปลี่ยน print attr เป็น print(attr) อีกหานานมากว่า systam error ที่ไหน ทั้งที่มันก็แดงกันเห็นๆ

__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: 08 March 2009 - 11:26 AM

0

#3 User is offline   Bleak 

  • Senior member
  • PipPipPip
  • Group: Members
  • Posts: 575
  • Joined: 24-March 05

Posted 08 March 2009 - 02:17 AM

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# ครับ
0

#4 User is offline   cblue 

  • Star
  • Group: Star
  • Posts: 702
  • Joined: 23-July 04

Posted 08 March 2009 - 02:26 AM

Groovy 1.6 ครับ
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: 08 March 2009 - 03:09 AM

0

#5 User is offline   SouLsKI 

  • Member
  • PipPip
  • Group: Members
  • Posts: 238
  • Joined: 11-July 06

Posted 08 March 2009 - 02:36 AM

Groovy เหมือนกันครับ เขียนไม่ทันคน cblue :D

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:

This post has been edited by SouLsKI: 08 March 2009 - 03:26 AM

0

#6 User is offline   Bleak 

  • Senior member
  • PipPipPip
  • Group: Members
  • Posts: 575
  • Joined: 24-March 05

Posted 08 March 2009 - 03:11 AM

ผมไม่เคยเขียน 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

ซึ่งมันน่าจะไม่ตรงกับโจทย์หรือเปล่าครับ ?
0

#7 User is offline   SouLsKI 

  • Member
  • PipPip
  • Group: Members
  • Posts: 238
  • Joined: 11-July 06

Posted 08 March 2009 - 03:12 AM

ผมแก้ code ไป 4 รอบละคืนนี้กว่าจะออกมาได้ถูก -_-"
0

#8 User is offline   Bleak 

  • Senior member
  • PipPipPip
  • Group: Members
  • Posts: 575
  • Joined: 24-March 05

Posted 08 March 2009 - 03:16 AM

ผมไม่เคยเขียน Groovy เหมือนกัน
จึงได้แต่แอบสงสัยในความสามารถพวกภาษา Script ว่ามันฉลาดขนาดนั้นเลยหรือ ?
เคยจับ Ruby อยู่แป๊บนึง แต่ก็คิดว่ามันไม่น่าจะทำได้

ดังนั้นพอตาม link คุณ cblue เข้าไปอ่าน comment ก็พอรู้ล่ะครับ

:D
0

#9 User is offline   SouLsKI 

  • Member
  • PipPip
  • Group: Members
  • Posts: 238
  • Joined: 11-July 06

Posted 08 March 2009 - 03:32 AM

คุณ cblue ครับช่วยอธิบายหน่อยครับว่าค่า v นี้ groovy มันจะรู้เองเลยหรือครับว่าเป็น array index ที่ 1 จนถึงตัวสุดท้ายและ มันเอามาจากไหนครับงง

พอดีเพิ่งเริ่ม เขียน groovy ยังไม่เคยเค้าใจ
0

#10 User is offline   Bleak 

  • Senior member
  • PipPipPip
  • Group: Members
  • Posts: 575
  • Joined: 24-March 05

Posted 08 March 2009 - 03:48 AM

View PostSouLsKI, on Mar 8 2009, 03:32 AM, said:

คุณ 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: 08 March 2009 - 03:58 AM

0

#11 User is offline   cblue 

  • Star
  • Group: Star
  • Posts: 702
  • Joined: 23-July 04

Posted 08 March 2009 - 03:49 AM

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
0

#12 User is offline   tuckclub 

  • Junior Member
  • Pip
  • Group: Members
  • Posts: 57
  • Joined: 29-October 04

Posted 08 March 2009 - 05:09 AM

C# 3.0 with LINQ
หลายๆ อย่างลอกมาจากของคุณ Bleak ครับ

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: 08 March 2009 - 05:21 AM

0

#13 User is offline   นายข้าวโพดหวาน 

  • Committee
  • View blog
  • Group: Committee
  • Posts: 7075
  • Joined: 01-April 03

Posted 08 March 2009 - 05:19 AM

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

โจทย์ไม่ละเอียดจริงๆครับ เพราะไม่ได้ระบุว่าฟิวด์แรกที่เป็นตัวเลขจะ sort ตามค่าหมายเลขหรือมองเป็นสตริง ยกประโยชน์ให้จำเลย จะ sort แบบไหนก็ได้ครับ

ถ้าเขียนด้วยรูบี้ จะเขียนเป็นแบบ script หรือ OO ก็ได้ ผมยกตัวอย่างทั้งสองแบบ

1. แบบ script
lines = IO.readlines('input.txt').map { |line| line.chomp.split('|').sort }
lines.sort.each  { |line| puts line.join(' ') }


2. แบบ OO
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 นายข้าวโพดหวาน: 08 March 2009 - 05:32 AM

0

#14 User is offline   tuckclub 

  • Junior Member
  • Pip
  • Group: Members
  • Posts: 57
  • Joined: 29-October 04

Posted 08 March 2009 - 05:56 AM

Java
มีข้อจำกัดครับ ห้ามเกิน 9 เรคคอร์ด
ไม่เช่นนั้นจะได้พบกับสิ่งที่เรียกว่า บั๊ก

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: 08 March 2009 - 06:05 AM

0

#15 User is offline   นายข้าวโพดหวาน 

  • Committee
  • View blog
  • Group: Committee
  • Posts: 7075
  • Joined: 01-April 03

Posted 08 March 2009 - 05:59 AM

สำหรับกรณีที่คุณ cblue เขียน ดักเพิ่มสองกรณี

1. sort ด้วยค่าตัวเลขจากฟิวด์แรกแทนที่จะมองเป็นสตริง (เลข 10 ควรอยู่หลังเลข 9 แม้ว่า 10 จะมีตัวเลขแรกคือ 1)
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 ด้วย
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 นายข้าวโพดหวาน: 08 March 2009 - 06:03 AM

0

Share this topic:


  • (6 Pages)
  • +
  • 1
  • 2
  • 3
  • Last »
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users