C#のみがマシン固有の組み込み関数をサポートしている場合…x86アセンブリ言語でこれを実行できる単一の命令があり、他のほとんどのプロセッサアーキテクチャでも同様です。そうすると、最短のコードだけでなく、最速のコードになる可能性が非常に高くなります。
実際、このコードを短くすることは、このコードを高速にすることに比べて非常に退屈な問題です。あらゆる種類の本当にきちんとした、効率的な、ビットをいじるソリューションがあり、ルックアップテーブルの使用を検討することもできます。
ただし、ゴルフにとってそれは重要ではありません。あなたの現在の解決策はあなたができる最善のように思えます。もちろん、余分な空白を削除することができます:
k<1?0:(int)Math.Log(k&-k,2)+1
私は個人的にそれを次のように書きます:
k>0?(int)Math.Log(k&-k,2)+1:0
条件付きテストの方向をそのようにしたり、ゼロと比較したりすることは少し明確だと思うので、私はそれが6つの方法であり、他の半ダースだと思います。
C#は、CやC ++のようなからint
への暗黙的な変換をサポートしていないbool
ため、条件テストをこれ以上短くすることはできません。
また、C#では暗黙的にこれが発生することを許可していないため、double
(my から返されたMath.Log
)からへの明示的なキャストにint
悩まされています。それはあなたが持っていることを指摘してしまうため、もちろん、それは通常、良いことだ大きな推進:ここでのパフォーマンスの問題をint
するdouble
、のログを計算double
して、変換double
に結果バックすることint
になり、大規模な、それは通常、何かですので、遅いですあなたが避けたいと思うこと。しかし、これらはコードゴルフをするときに我慢しなければならない種類の倒錯です。
私は最初に思いついた
k > 0
? ((k & -k) >> 1) + 1
: 0
(もちろん、わかりやすくするために無記号)、これは対数を取ることを回避するため、コードのサイズと速度が向上します。残念ながら、これは常に正しい答えを得るとは限りません。私はそれが柔軟性のない要件であると思います。:-)具体的には、入力値(k
)が8の係数である場合に失敗します。これはMath.Log
修正可能ですが、バージョンよりもコードを長くしないと修正できません。