読者です 読者をやめる 読者になる 読者になる

Skyland Ventures tech ブログ

渋谷のVenture Capital Skyland Venturesのいま一番イケてる投資先、nanameue,IncとKaumoの共同技術ブログ

いいアルゴリズムをつくるための数学活用② ~ 余計なif文をなくすための工夫

こんにちわ。nanameue,Inc ばーちーです。 ラブライブ紅白出場おめでとうございます。 ついにお茶の間に我らのμ'sが出ることになりましたが、ここまで6年、メンバーたちは本当にがんばってくれました。 μ'sには感謝の思いでいっぱいです。 つらいとき、悲しいとき、私を支えてくれたのは、μ'sと松岡修造カレンダーでした。 今年もぜひμ's冬ライブに行こうとおもいます。

さて、前回は、 良いアルゴリズムを作るための数学活用 - Skyland Ventures tech ブログという内容でした。 今日は前回に引き続き、いいアルゴリズムをつくるための私が使っている数学Tipsを紹介します。

我々プログラマーは、コードを書いているとき、どのように条件分岐すべきか、 いいアイデアが思いつかなくて、しかたなく、少し多目のif文で対処してしまうことがあります。 しかし、私はたくさんif文を書くことはあまり美しくないと考えてます。 if 文が多目のコードは新たな条件が加わったときや変更に対して、あまり柔軟ではありません。 そんなときに直面したときに、数学の知識を使うことで、いいコードになることがしばしばあります。

今回は例として、 年齢から年代を計算するアルゴリズムを作りながら解説していきたいとおもいます。

例えば、18歳、19歳は10代、20 ~ 29は20代といった感じです。

ここでは、 18歳、19歳は10代, 20 ~ 29は20代, 30 ~ 39は30代, 40 ~ それ以降と文字を返す関数を作ってみましょう。

コードはObjective - Cです

皆さんならどう書きますか?

まず基本的な制御文ifを使ってコードを書いてみましょう。

- (NSString *)ageGroupFromAge:(int)age{
    if(age > 10 && age <20){
        return @"10代";
    }else if (age >= 20 && age <29){
        return @"20代";
    }else if (age >= 30 && age <40){
        return @"30代";
    }else if (age >= 40){
        return @"それ以降";
    }
}

予想どうり、if文がたくさんでてきました。 一応正確に動くので、まあこのままでも問題はないのですが、この書き方だと、 60 歳以降を、それ以降にしてくれとオーダーされたとき、if文を2つ加えなければなりません。 よってあまり、変更に強いコードではありません。 しかし、いいコードを書きたいと考えても、これ以外条件が思いつかない人の方が、多いのではないでしょうか?

こんなとき使える数学Tip(今回は、プログラミングそのものの仕様も利用していますが)、 整数は小数を含まないという性質を割り算で利用するです。 整数とは、1,2,3と小数を含まない数字です。 この性質を割り算で用いて、小数を整数に変換することで、この問題を解きます。

例えば,

NSInteger age = 2;
age / 3

と、

int age = 2;
age / 3

の結果はどう異なっているでしょう。

答えは前者は、0.666666… 後者は0です。

こlれは、プログラミングそのものの仕様も利用していますが、多くの言語で、たとえ答えが0.66でも変数の型が整数だと、 小数を完全に切り捨てるという仕様になっています。 なぜなら整数は小数を含んではいけないからです。

この性質を利用し、コードを書き直すと、

- (NSString *)ageGroupStringWithAge:(int)age{
  NSArray * ageGroupArray = @[@"10代",
                               @"20代",
                              @"30代",
                              @"40代以降"];
                            
                            
    int number = age / 10;
    if (number > 3) {
        return [ageGroupArray[3]];
    }
    return [ageGroupArray[number -1]];
}

コードがすっきりしました。 なんと、if文一回のみです。 やっぱ60歳以降をそれ以降にしてくれとオーダーがあっても

- (NSString *)ageGroupStringWithAge:(int)age{
      NSArray * ageGroupArray = @[@"10代",
                              @"20代",
                              @"30代",
                              @"40代",
                              @"50代",
                              @"60代以降"];
    
    int number = age / 10;
    if (number > 5) {
        return [ageGroupArray[5]];
    }
    return [ageGroupArray[number -1]];
}

と変更を加えるだけです。

かなり変更に強いコードになりました。

この割った結果が小数でも、変数が整数だと、整数になるという仕様はいろんなアルゴリズムを組む際に使えそうですね。

では、次の更新は月曜日です。

また公式Twitterアカウントフォローおねがいします。 @skylandtechblog