作者: Keiichi Takahashi
日時: 2002/11/15(21:42)
ビットウォークの高橋です。

> 1,2,3,5,7,8,10,12,14,15,16,17
> 
> の様なソート済番号のリストを,
> 
> 1-3,5,7-8,10,12,14-17
> 
> の様な表現に直すスクリプトを Perl でつくりました.


Tclで作ってみました。

アルゴリズムの方針は、ソートされている整数のTclリストから、要素が1の間隔
で続いていれば、その連続した要素部分をサブリストに分類して、新しいTclリ
ストを生成することです。

生成した新しいTclリストを出力した後にもう一度、整形した結果を出力してい
ます。したがって、短くスマートなスクリプトとは言えません。


スクリプト (odai.tcl):

#!/bin/sh
# the next line restarts using tclsh \
exec tclsh8.4 "$0" "$@"

set numList [split $argv ","]

foreach num $numList {
    if {![info exists newList]} {
        set newList $num
    } else {
        set lastElem [lindex $newList end]
        set last [lindex $lastElem end]
        if {$num == [expr $last + 1]} {
            lappend lastElem $num
            lset newList end $lastElem
        } else {
            lappend newList $num
        }
    }
}
# interim report
puts $newList

set resultList {}
foreach elem $newList {
    if {[llength $elem] > 1} {
        set elem "[lindex $elem 0]-[lindex $elem end]"
    }
    lappend resultList $elem
}
puts [join $resultList ","]

# ---
# odai.tcl


実行例:
$ chmod +x odai.tcl
$ ./odai.tcl 1,2,3,5,7,8,10,12,14,15,16,17
{1 2 3} 5 {7 8} 10 12 {14 15 16 17}
1-3,5,7-8,10,12,14-17


備考:
lsetはTcl8.4で追加されたコマンドです。8.3以前のバージョンで試す場合は、

lset newList end $lastElem

の部分を

set newList [lreplace $newList end end $lastElem]

というように、lreplaceコマンドを使う方法へ変更してください。

-- 
Keiichi Takahashi, bitWalk Co.,Ltd.
mailto:bitwalk@...
http://members10.tsukaeru.net/bitwalk/