iolanguageでクイックソート

前回のタイトル(http://d.hatena.ne.jp/ottu/20100527/1274990348)にて
いくつかあった問題を力技で解決。


xが見つからないやらなんやら。
これは doString が Lobby 上で実行されていたのが原因っぽい。
Object の Slot として squareBrackets を定義してやったら
既存のslotがあった場合〜の問題も併せて解決。
でも他の問題で、結局ゴミみたいなコードに変わりは無かった。


とりあえずちょこちょこ書き直した squareBrackets と、
それを使ったクイックソートの実装。
あと使ってないけど試しで書いたzip関数。
以下ソースコード

//今回のキモ
Object squareBrackets := method(
    
    args   := call message arguments
    result := List clone    

    if( (args size >1) and (args at(1) code containsSeq(" in ")) ) then(
    
        obj    := Object clone do ( setSlot("temp", List clone) )

        eachLine   := ""
        filterLine := ""
        count      := 0

        args foreach( i, arg,

            if( i==0 ) then( continue )

            if( arg code containsSeq("in") ) then(

                items := arg code split("in")
                key   := items at(0) strip
                li    := items at(1) strip

                obj setSlot( key, Object clone )

                if( obj hasSlot(li) not ) then(
                    li = call sender doString(li) asString
                )

                eachLine = eachLine .. li .. " foreach( " .. key .. ", "
                count = count+1

            ) else (
                
                boolCode := arg code
                items := boolCode split(" ")

                if( items size > 1 ) then(
                    items foreach( item,
                        val := item between("(",")")
                        if( val == nil ) then( continue )
                        if( obj hasSlot(val) not ) then(
                            boolCode = boolCode asMutable replaceSeq( val, call sender doString(val) asString )
                        )
                    )
                )
                filterLine = filterLine .. "( " .. boolCode .. " ) ifFalse( continue ); "

            )
        )
        mapLine := "temp append( " .. args at(0) code .. " )"
        result = obj doString( eachLine .. filterLine .. mapLine .. ")" repeated(count) .. "; temp" )

    ) else (
        args foreach( arg, result append( call sender doString( arg code ) ) )
    )
    return result    
)

//Listの連結を見やすく
List + := method( content,
    self appendSeq( content )
)
//クイックソート
qsort := method( appendix,
    if( appendix == [] ) then (
        return []
    ) else (
        x := appendix removeAt(0)
        return qsort([y, y in appendix, y < x]) + [x] + qsort([y, y in appendix, y >= x])
    )    
)

qsort( [6,8,3,5,4,1,9,2,7] )
==> list(1, 2, 3, 4, 5, 6, 7, 8, 9)

//zip
zip := method(

    size := Number clone
    call message arguments foreach( list,
      if (size == 0) then (
        size = call sender doString(list code) size
      ) else (
        size = call sender doString(list code) size min(size)
      )
    )

    result := List clone
    for( i, 0, size-1,
      item := List clone
      call message arguments foreach( list,
        item append( call sender doString(list code) at(i) )
      )
      result append( item )    
    )

    return result
)

zip( [1,2,3], [4,5,6], [7,8,9] )
==> list(list(1, 4, 7), list(2, 5, 8), list(3, 6, 9))

前回書くの忘れたけど、変数命名のセンスの無さは目を瞑ってやってください…。


2010/06/05 修正
squareBrackets内の無駄っぽい所を修正。
内包表記内の一時変数を l,r から y に統一。


2010/7/29 修正
obj 変数の定義場所を少しずらした。