คิดอะไรไม่ออก ลอกโจทย์ Code Golf มาเล่นกันดีกว่า
โจทย์ง่ายๆ คือให้ input เป็น string ของเลขจำนวนเต็มที่เรียงจากน้อยไปมาก ปัญหาคือถ้ามีเลขที่ติดกันเช่น 1 2 3 ต้องแปลงเป็นช่วง 1-3 อะไรอย่างนี้
ยกตัวอย่าง
"1 2 4 5 6 8 10" => "1-2 4-6 8 10" "3 5 7 101 102 103" => "3 5 7 101-103"
กระทู้เก่าๆ จะย้ายตามไปในภายหลัง ตอนนี้ปิดการโพสต์กระทู้ไว้ เหลือไว้เฉพาะอ้างอิงเท่านั้น
เขียนด้วย ML ยาวมาก กว่าจะแปลงไปแปลงมาระหว่าง string กับ int
ฟังก์ชันที่น่าสนใจหน่อยคงเป็น toRangeList รับลิสต์ของ int แล้วก็มาจับเป็น range ตัวอย่างเช่น ถ้าสั่ง
ที่เหลือก็สำหรับแปลงไปแปลงมา
fun toRangeList([]) = [] | toRangeList([x]) = [(x,x)] | toRangeList(x::xs) = let val y::ys = toRangeList(xs) val (f,t) = y in if x = (f-1) then (x,t)::ys else (x,x)::y::ys end; fun toIntList(st) = let val stlist = String.tokens (fn c => (c = #" ")) st fun f([]) = [] | f(x::xs) = let val SOME x = Int.fromString(x) in x::f(xs) end in f(stlist) end; fun tupleToPrettyString(x,y) = if x=y then Int.toString(x) else Int.toString(x) ^ "-" ^ Int.toString(y); fun toPrettyString([]) = "" | toPrettyString([(x,y)]) = tupleToPrettyString(x,y) | toPrettyString((x,y)::xs) = let val st = toPrettyString(xs) in tupleToPrettyString(x,y) ^ " " ^ st end; fun home(st) = let val ilist = toIntList(st) val rlist = toRangeList(ilist) in toPrettyString(rlist) end;[เข้าไปดูในเว็บ code golf มา.... พวกสั้น ๆ เขียนด้วย perl หมดเลยนี่นา]
^^^ ดูผิด มันมีให้ดูแยกภาษา แต่ว่า perl ก็สั้นสุดอยู่ดี
dynamic type ของ perl นี่มัน powerful (และ evil) มากครับ
อยากลองเขียนบ้าง วิธีเหมือนกันเป๊ะ แต่เป็น Python รับรองว่าช้าแน่ๆ ก๊อปกันหลายรอบ
เอาบ้าง (haskell)
ใช้ argument ที่ 2 เป็นตัวทด, ตัวที่ 3 เป็น accumulate
solve:: [Int] -> [(Int,Int)] solve (x:xs) = solve' xs (x,x) [] solve':: [Int] -> (Int,Int) -> [(Int,Int)] -> [(Int,Int)] solve' [] (x,y) z = reverse ((x,y) : z) solve' (x:xs) (x',y') z | x == (y' + 1) = solve' xs (x', x) z | otherwise = solve' xs (x , x) ((x', y'):z)เนียนมากๆ
ผมชอบ toRangeList ของอาจารย์มะนาวมากกว่านะ สวยดี
ส่วน declare type มันรุงรังไปหน่อย
สามารถเขียนแบบนี้แทนได้
(พึ่งอ่านเจอ)
solve :: Num a => [a] -> [(a,a)] solve':: Num a => [a] -> (a,a) -> [(a,a)] -> [(a,a)]เท่าที่ทราบเหมือน Haskell มันทำ type inference ได้เอง (ตอนที่ผมลอง ๆ เขียนมันก็ทำให้)
ทีนี้ เท่าที่สังเกตโปรแกรมคุณ pphetra จะ declare type มาด้วย ก็เลยสงสัยว่า ถ้าไม่ declare เลยมันจะได้หรือเปล่าอ่ะครับ?
ไม่ใส่ก็ run ได้ครับ
แต่ที่ใส่ไว้ เพราะรู้สึกว่ามันเป็น visualize tool ชนิดหนึ่งครับ
ช่วยให้ทบทวน code ได้ดียิ่งขึ้น
ocaml หละ
type r = {s: int; e: int};; let find_range seq = let merge_range a n = match a with x::xs when x.e + 1 == n -> {s = x.s; e = n}::xs | [] | _ -> {s = n; e = n}::a in List.rev (List.fold_left merge_range [] seq) ;; let pretty seq = let pretty_r r_ = if r_.s == r_.e then string_of_int r_.s else (string_of_int r_.s) ^ "-" ^ (string_of_int r_.e) in let rec join seq = match seq with x::xs -> if List.length xs == 0 then x else x ^ " " ^ (join xs) | _ -> "" in join (List.map pretty_r seq) ;; let _ = print_endline (pretty (find_range [1;2;3;5;6;10;14;15;16]));;โอ้ดู code ocaml นี่ต้องเอามือกุมหัว แล้วอ่านออกเสียง
(ด้วยยังไม่คุ้นกับ syntax)
ผมเขียนมั่วด้วยหละครับ ถ้าผมเขียนคล่อยๆแล้ว(คงมีซักวัน) ก็น่าจะอ่านง่ายขึ้นด้วย
มึนสุดยอดเหมือนกัน ผมเลยไปอ่านตารางเทียบระหว่าง SML กับ Ocaml มา (ดูที่นี่)
ตอนแรกดูแล้วจะงงตรง match ว่าคืออะไร ทำไปทำมา match มันเป็นเหมือน syntax ในการทำ pattern matching เลย แต่มันมีตรงที่เพิ่ม when เข้ามาด้วย
let find_range seq =
let merge_range a n = match a with
x::xs when x.e + 1 == n -> {s = x.s; e = n}::xs
| [] | _ -> {s = n; e = n}::a
in
List.rev (List.fold_left merge_range [] seq)
;;
อย่างข้างบนทำ pattern matching a กับ x::xs, [] แล้วก็ _
ไม่มีใครเขียน Perl ซะหน่อยเหรอครับ
php
แบบนี้จะได้แค่ 2 ตัวเช่น
1 2 3 4 5 = Array[[0]=1-2[1]=3-4[2]=5]
ไพธอนแบบโบราณครับ
def range_list(s): slist=s.split(' ') n=len(slist) i=0 newlist=[] while i<n: j=i+1 k=i while j<n and int(slist[j])==int(slist[k])+1: k=j j=j+1 if k==i: newlist.append(slist[i]) i=i+1 else: newlist.append(slist[i]+'-'+slist[k]) i=k+1 return ' '.join(newlist) >>> print range_list("1 2 4 5 6 8 10") 1-2 4-6 8 10 >>> print range_list("3 5 7 101 102 103") 3 5 7 101-103ของผมเขียนด้วยจาวาคงไม่เป็นไรใช้ไม่เป็นไรใช่ไหมครับ
else if วาง layout ได้แปลกตาดีครับ
Groovy ครับ
>> def idx = (0..<(a.size()-1)).grep{ a[it].next() != a[it+1] }
>> [*idx, a.size()-1].inject(0) { from, to ->
สวยดี
อยากให้แต่ละคนที่ตอบ อธิบาย แนวคิด concept ที่ให้ในการแก้โจทย์ หน่อยหนะครับ
แบบคร่าวๆ ก็ยังดี เพราะว่า บางที เห็นแต่โค้ด แต่ว่า มันหลายภาษา ผมก็ไม่เป็นทุกภาษา
แต่อยากรู้แนวคิดที่ใช้แก้โจทย์ ที่มันสอดคล้องกับภาษาที่ทุกๆคนใช้แก้โจทย์หนะครับ
อืม น่าสนใจนะครับ นอกจากแนวคิดแล้ว ผมเห็นหลายๆ ฟอรั่มมีการทดสอบประสิทธิภาพการทำงานอย่างง่ายๆ ให้เห็นกันด้วย
เห็นด้วยนะครับ... (ต้องไปเขียนอันเก่า ๆ ด้วยหรือเปล่า?)
PHP แบบถึกๆ ครับ
กระทู้นานมากครับ แต่เพิ่งอ่านเจอ ขอเล่นด้วยคน
wow เจ่งครับ
โห คิดได้ไง
เจ๋งอะครับ คิดไปได้
นึกว่าง่าย… เขียนไปเขียนมา ก็ไม่ต่างจะข้างบน C# ครับ
โจทย์นี้หลายชาติแล้วเพิ่งจะเห็นอีกแล้ว คงจะยังไม่ช้าเกินไป :P
ลองเล่นๆดูเขียนด้วย Ruby ออกมายังงี้
อนาถตัวเองจริงๆ
ป.ล. เดี๋ยวมาแก้ตัวอีกที
ป.ล. 2 พี่ป็อกชี้แนะด้วย
เริ่มด้วยลดความรุงรังของ to_i ก่อน
แฮะๆ.. ลืม map,collect etc. พวกนี้ไปได้เรา
ขอบคุณครับพี่
เอ.. แล้วที่โพสต์ไปมันแก้ไม่ได้เหมือนใน blognone เหรอ
ถ้ามีคน reply จะแก้ไม่ได้
krab
ไปเจอ module itertools (http://docs.python.org/lib/itertools-example.html)
เขามี function groupby ให้ใช้
ลองเขียนดูแล้ว มันมายาวตอนทำสวยนี่แหล่ะ
? ใครช่วยทำให้ pretty_result มันสวยขึ้นกว่านี้หน่อย
พี่ป๊อกขอ scala ด้วยครับ