Se apenas o C # suportasse intrínsecos específicos à máquina ... Há uma única instrução que pode fazer isso na linguagem assembly x86 e também na maioria das outras arquiteturas de processador. Então você teria não apenas o código mais curto, mas provavelmente o mais rápido.
De fato, tornar esse código mais curto é um problema extremamente chato comparado a tornar esse código rápido . Existem todos os tipos de soluções realmente limpas, eficientes e de manipulação de bits, e você também pode considerar o uso de uma tabela de consulta.
Nada disso importa para o golfe, no entanto. Parece-me que sua solução atual é a melhor que você pode fazer. Obviamente, você pode remover o espaço em branco supérfluo:
k<1?0:(int)Math.Log(k&-k,2)+1
Eu pessoalmente o escreveria como:
k>0?(int)Math.Log(k&-k,2)+1:0
porque acho que é um pouco mais claro ter a direção do teste condicional dessa maneira, bem como compará-lo com zero, mas acho que são seis de uma maneira, meia dúzia da outra.
O C # não oferece suporte à conversão implícita de int
para o bool
C e o C ++, portanto, você não pode realmente reduzir ainda mais o teste condicional.
Você também está preso ao elenco explícito de double
(como retornou meu Math.Log
) para int
, pois o C # não permitirá que isso aconteça implicitamente. Obviamente, isso normalmente é uma coisa boa, porque indicaria que você tem um grande problema de desempenho aqui: promover um int
para a double
, calcular o log de a double
e depois converter o double
resultado em um int
será massivamente lento, então normalmente é algo que você gostaria de evitar. Mas esses são os tipos de perversões que você precisa suportar ao jogar código-golfe.
Eu tinha inicialmente pensado
k > 0
? ((k & -k) >> 1) + 1
: 0
(ungolfed para maior clareza, é claro), que evita o logaritmo e, portanto, é uma melhoria no tamanho e na velocidade do código. Infelizmente, isso nem sempre recebe a resposta certa, e presumo que seja um requisito inflexível. :-) Especificamente, ele falhará se o valor de entrada ( k
) for um fator de 8. Isso é corrigível, mas não sem tornar o código mais longo que a Math.Log
versão.