Якщо тільки C # підтримує специфічні для машини властивості ... Є єдина інструкція, яка може це зробити на мові збірки x86, а також у більшості інших архітектур процесора. Тоді ви мали б не тільки найкоротший код, але, швидше за все, найшвидший.
Насправді, скорочення цього коду є надзвичайно нудною проблемою порівняно зі швидким скороченням цього коду . Існують всілякі дійсно акуратні, ефективні, бітові рішення, і ви також можете скористатися таблицею пошуку.
Хоча нічого з цього не має значення для гольфу. Мені здається, що твоє поточне рішення - найкраще, що ти можеш зробити. Звичайно, ви можете видалити зайвий пробіл:
k<1?0:(int)Math.Log(k&-k,2)+1
Я особисто написав би це:
k>0?(int)Math.Log(k&-k,2)+1:0
тому що я думаю, що трохи чіткіше вказати напрямок умовного тесту таким чином, а також порівняти його з нулем, але я думаю, що це шість в один бік, півдесятка - інший.
C # не підтримує неявну конверсію з int
на bool
зразок C і C ++, тому не можна більше скорочувати умовний тест.
Ви також застрягли в явній передачі з double
(як повернувся мій Math.Log
) int
, оскільки C # не дозволить це зробити неявно. Звичайно, це, як правило, добре, тому що це вказує на те, що у вас тут є велика проблема продуктивності: просування int
до а double
, обчислення журналу а double
та перетворення double
результату назад у формат int
буде масово повільним, тому зазвичай це щось що ви хочете уникнути. Але це різновиди збочень, з якими доводиться стикатися, граючи в кодовий гольф.
Я спочатку придумав
k > 0
? ((k & -k) >> 1) + 1
: 0
(звичайно, без ясності для зрозумілості), що дозволяє уникнути логарифму і, отже, покращує розмір та швидкість коду. На жаль, це не завжди дає правильну відповідь, і я вважаю, що це негнучка вимога. :-) Зокрема, він не вдається, якщо вхідне значення ( k
) є коефіцієнтом 8. Це можна виправити, але не робити код довше, ніж Math.Log
версія.