Si solo C # admite intrínsecos específicos de la máquina ... Hay una sola instrucción que puede hacer esto en lenguaje ensamblador x86, y también en la mayoría de las arquitecturas de otros procesadores. Entonces no solo tendría el código más corto, sino muy probablemente el más rápido.
De hecho, hacer que este código sea más corto es un problema extremadamente aburrido en comparación con hacer que este código sea rápido . Hay todo tipo de soluciones realmente ordenadas, eficientes y poco complicadas, y también podría considerar usar una tabla de búsqueda.
Sin embargo, nada de eso importa para el golf. Me parece que su solución actual es lo mejor que puede hacer. Por supuesto, puede eliminar el espacio en blanco superfluo:
k<1?0:(int)Math.Log(k&-k,2)+1
Yo personalmente lo escribiría como:
k>0?(int)Math.Log(k&-k,2)+1:0
porque creo que es un poco más claro tener la dirección de la prueba condicional de esa manera, así como compararla con cero, pero supongo que son seis en una dirección, media docena en la otra.
C # no admite la conversión implícita de int
a bool
C y C ++, por lo que realmente no puede acortar más la prueba condicional.
También está atascado con la conversión explícita de double
(como devuelto mi Math.Log
) a int
, ya que C # no permitirá que esto suceda implícitamente. Por supuesto, eso normalmente es bueno porque señalaría que tiene un gran problema de rendimiento aquí: promocionar int
a a a double
, calcular el registro de a double
y luego convertir el double
resultado a a int
será enormemente lento, por lo que normalmente es algo que te gustaría evitar Pero estos son los tipos de perversiones que tienes que soportar cuando juegas golf de código.
Inicialmente se me ocurrió
k > 0
? ((k & -k) >> 1) + 1
: 0
(sin pretensiones de claridad, por supuesto), lo que evita tomar el logaritmo y, por lo tanto, es una mejora en el tamaño y la velocidad del código. Desafortunadamente, esto no siempre obtiene la respuesta correcta, y supongo que es un requisito inflexible. :-) Específicamente, falla si el valor de entrada ( k
) es un factor de 8. Esto es reparable, pero no sin hacer que el código sea más largo que la Math.Log
versión.