[リストへもどる]   [VBレスキュー(花ちゃん)]
一括表示

投稿時間:2004/09/07(Tue) 14:53
投稿者名:ダンボ
URL :
タイトル:
pMin(i,j,k)
先ほどから30分、下記のような関数を考えているのですがどうも美しく出来ません。
皆さんも、腕に覚えのある方は、美しいアルゴリズムを考えてみませんか?
(と、人にやらせてみる)処理効率は問いません。ステップ数の少ないほうが美しいかな。

関数名:pMin
引数:i,j,k  (いずれも、0または正整数)
戻り値:i,j,kのうち正で一番小さい値。但し、i,j,kのすべてが0ならば0.

投稿時間:2004/09/07(Tue) 16:05
投稿者名:kazuやん
Eメール:
URL :
タイトル:
Re: pMin(i,j,k)
> 先ほどから30分、下記のような関数を考えているのですがどうも美しく出来ません。
> 皆さんも、腕に覚えのある方は、美しいアルゴリズムを考えてみませんか?
> (と、人にやらせてみる)処理効率は問いません。ステップ数の少ないほうが美しいかな。
>
> 関数名:pMin
> 引数:i,j,k  (いずれも、0または正整数)
> 戻り値:i,j,kのうち正で一番小さい値。但し、i,j,kのすべてが0ならば0.

果たして美しいかは微妙ですが、こんな感じでしょうかね^^

'**********************************************************
'*  pMin        :引数の中で最小の値を返す。但し3つとも0なら0を返す
'*  i,j,k       :いずれも、0または正整数
'*  戻り値      :最小の値、又は0
'**********************************************************
Function pMin(i As Integer, j As Integer, k As Integer) As Integer

    Dim min         As Integer  '最小値

    '全て0の場合
    If (i Or j Or k) = 0 Then
        pMin = 0
    Else
        '最小値初期設定
        min = i
    
        If (min > j) Then min = j
        
        If (min > k) Then min = k
        
        pMin = min
    
    End If

End Function

投稿時間:2004/09/07(Tue) 16:39
投稿者名:ダンボ
URL :
タイトル:
Re^2: pMin(i,j,k)
kazuやん さん、どうもありがとうございます。美しいです。
ソートでないのだから「必要最小限の比較にしろ」というところでしょうか。

。。すみません。。前提が間違えていました。
(誤)  pMin        :引数の中で最小の値を返す。但し3つとも0なら0を返す
(正)  pMin        :引数の中で最小の正値を返す。但し3つとも0なら0を返す

kazuやん さんのコーディングを流用してこんなにしてみましたが、pMin(6,0,32)=0
となってしまいましたわ(理由は分かる)。もう少し自分で考えて見ますね。

Function pMin(i As Integer, j As Integer, k As Integer) As Integer
    Dim min         As Integer  '最小値
    '全て0の場合
    If (i Or j Or k) = 0 Then
        pMin = 0
    Else
        '最小値初期設定
        If i > 0 Then
            min = i
            If (min > j) Then min = j
            If (min > k) Then min = k
            pMin = min
        End If
        If j > 0 Then
            min = j
            If (min > i) Then min = i
            If (min > k) Then min = k
            pMin = min
        End If
        If k > 0 Then
            min = k
            If (min > j) Then min = j
            If (min > i) Then min = i
            pMin = min
        End If

End Function

投稿時間:2004/09/07(Tue) 17:27
投稿者名:kazuやん
Eメール:
URL :
タイトル:
Re^3: これは?
こんなのでしたらどうでしょうか?
さっきよりちょっと美しくなくなってしまいますが^^

ちょっと気になったのが引数は絶対に数値と決まっているのでしょうか?
もしそうでなければ、宣言を以下にして
Function pMin(i, j, k) As Integer
引数それぞれの整数チェックを入れる事をお勧めします。

'**********************************************************
'*  pMin        :引数の中で最小の正値を返す。但し3つとも0なら0を返す
'*  i,j,k       :いずれも、0または正整数
'*  戻り値      :最小の正値、又は0
'**********************************************************
Function pMin(i As Integer, j As Integer, k As Integer) As Integer

    Dim min         As Integer  '最小値

    '全て0の場合
    If (i Or j Or k) = 0 Then
        pMin = 0
    Else
        '最小値初期設定
        If i <> 0 Then
            min = i
        ElseIf k <> 0 Then
            min = k
        ElseIf j <> 0 Then
            min = j
        End If
        
        'Betweenみたいのがあればもっと美しくなるのかな?
        'それとももっと簡略化したif文の書き方があるかもしれません^^
        If (min > j) And (j > 0) Then min = j
        
        If (min > k) And (k > 0) Then min = k
        
        pMin = min
    
    End If

End Function

投稿時間:2004/09/07(Tue) 17:49
投稿者名:黒影
Eメール:
URL :
タイトル:
Re^4: これはどぉ?
こんなのは?
kazuやんさんの最初のコードをちょっぴり改造しただけですが...(^^;)

'**********************************************************
'*  pMin2       :引数の中で最小の正値を返す。但し3つとも0なら0を返す
'*  i,j,k       :いずれも、0または正整数
'*  戻り値      :最小の値、又は0
'**********************************************************
Function pMin2(i As Integer, j As Integer, k As Integer) As Integer

    Dim min         As Integer  '最小値

    '全て0の場合
    If (i Or j Or k) = 0 Then
        pMin2 = 0
    Else
        '最小値初期設定
        min = i
        
        If (min > j) Then
            min = IIf(j = 0, min, j)
        Else
            min = IIf(min = 0, j, min)
        End If
        
        If (min > k) Then
            min = IIf(k = 0, min, k)
        Else
            min = IIf(min = 0, k, min)
        End If
            
        pMin2 = min
    
    End If

End Function

投稿時間:2004/09/08(Wed) 09:38
投稿者名:ダンボ
URL :
タイトル:
Re^5: 補填してGood
黒影さん、どうもありがとうございます。
IIfの小技を使って簡略化しましたね。判定と値代入を1命令で実行する。
Elseの後がもっちゃりした感じがあるので、ここの必要性を考えていくと
最初の2命令(全て0の場合)がこちらに吸収されていることが分かりました。

'**********************************************************
'*  pMin2       :引数の中で最小の正値を返す。但し3つとも0なら0を返す
'*  i,j,k       :いずれも、0または正整数
'*  戻り値      :最小の値、又は0
'**********************************************************
Function pMin2(i As Integer, j As Integer, k As Integer) As Integer

     Dim min         As Integer  '最小値

         '最小値初期設定
         min = i
        
         If (min > j) Then
             min = IIf(j = 0, min, j)
         Else
             min = IIf(min = 0, j, min)
         End If
        
         If (min > k) Then
             min = IIf(k = 0, min, k)
         Else
             min = IIf(min = 0, k, min)
         End If
            
         pMin2 = min
    
     End If

End Function

で、必要十分のようですよ。

投稿時間:2004/09/08(Wed) 12:46
投稿者名:黒影
Eメール:
URL :
タイトル:
Re^6: さらに改造
> 最初の2命令(全て0の場合)がこちらに吸収されていることが分かりました。

そうですね。
あまり深く考えなかったもので...(^^;)
それでもまだなんとなく見た目が納得出来ず...
で、さらに改造してこんな風に↓↓↓

'**********************************************************
'*  pMin3       :引数の中で最小の正値を返す。但し3つとも0なら0を返す
'*  i,j,k       :いずれも、0または正整数
'*  戻り値      :最小の値、又は0
'**********************************************************
Function pMin3(i As Integer, j As Integer, k As Integer) As Integer

    Dim min     As Integer  '最小値

    '最小値初期設定
    min = i
    
    min = IIf(min > j, IIf(j = 0, min, j), IIf(min = 0, j, min))
    min = IIf(min > k, IIf(K = 0, min, k), IIf(min = 0, k, min))
        
    pMin3 = min

End Function

投稿時間:2004/09/09(Thu) 11:17
投稿者名:ダンボ
URL :
タイトル:
Re^7:完璧です
黒影さん、重ね重ねありがとうございます。美しいです。たった5行にまとめられましたね。

・IIfは処理速度が遅いこと
・アルゴリズムの流れがコーディングからは一目で読み取れない、
の2点が工業製品としてのプログラミングからは排除されるべき欠点でしょうが、今回、
皆さんに提起したのは芸術作品としてのプログラミングですので、これで完成形と思います。

ところで、kazuやん、黒影さんのお2人のアイデアをいただいて、私のコーディングは
下記でFIXしようかと思います。前提条件が少し変わりました。
・3引数では足りない場合もありそうなので4引数、5引数にも対応したい。
・長い文字列のInstr結果ではIntegerではあふれるのでLongとする。
ParamArrayを使う関係上、型宣言がVariantとなりちょっと気持ち悪い。

'**********************************************************
'*  pMin        :引数の中で最小の正値を返す。但しすべて0なら0を返す
'*  i,N(可変)   :いずれも、0または正整数
'*  戻り値      :最小の正値、又は0
'**********************************************************
Private Function pMin(i As Long, ParamArray N() As Variant) As Long

    Dim min As Long  '最小値
    Dim j As Variant

    min = i
    For Each j In N
      min = IIf(min > j, IIf(j = 0, min, j), IIf(min = 0, j, min))
    Next j
        
    pMin = min
End Function

投稿時間:2004/09/07(Tue) 18:06
投稿者名:ダンボ
URL :
タイトル:
Re^4: 完璧です
kazuやん さん、重ね重ねどうもありがとうございます。完璧です。
他の仕事もしていたので、デバッグモードをそのままにしてあります。すぐ動作確認してOKでした。

> ちょっと気になったのが引数は絶対に数値と決まっているのでしょうか?
はい。引数は呼び出し元でInstrの戻り値をいれますので。型は固定しておいたほうが虫除けに良いです。