Se solo C # supportasse intrinseci specifici della macchina ... Esiste un'unica istruzione che può farlo in linguaggio assembly x86 e anche sulla maggior parte delle altre architetture di processori. Quindi avresti non solo il codice più breve, ma molto probabilmente il più veloce.
In effetti, rendere questo codice più breve è un problema estremamente noioso rispetto a rendere questo codice veloce . Esistono tutti i tipi di soluzioni davvero ordinate, efficienti e di precisione, e potresti anche prendere in considerazione l'utilizzo di una tabella di ricerca.
Niente di tutto ciò è importante per il golf, però. Mi sembra che la tua soluzione attuale sia la migliore che puoi fare. Naturalmente, puoi rimuovere lo spazio bianco superfluo:
k<1?0:(int)Math.Log(k&-k,2)+1
Lo scriverei personalmente come:
k>0?(int)Math.Log(k&-k,2)+1:0
perché penso che sia leggermente più chiaro avere la direzione del test condizionale in quel modo, così come confrontarlo con zero, ma immagino che sia sei in un modo, mezza dozzina nell'altro.
C # non supporta la conversione implicita da int
a bool
come C e C ++ fanno, quindi non si può davvero accorciare il test condizionale ulteriormente.
Sei anche bloccato con il cast esplicito da double
(come restituito a Math.Log
) int
, poiché C # non consentirà che ciò accada implicitamente. Naturalmente, questo è normalmente una buona cosa perché sottolinea che qui hai un grosso problema di prestazioni: promuovere un int
in a double
, calcolare il registro di un double
e quindi riconvertire il double
risultato in un int
sarà enormemente lento, quindi normalmente è qualcosa che vorresti evitare. Ma questi sono i tipi di perversioni che devi sopportare quando giochi a code golf.
Inizialmente mi ero inventato
k > 0
? ((k & -k) >> 1) + 1
: 0
(non identificato per chiarezza, ovviamente), che evita di prendere il logaritmo ed è quindi un miglioramento delle dimensioni e della velocità del codice. Sfortunatamente, questo non ottiene sempre la risposta giusta e presumo che sia un requisito inflessibile. :-) In particolare, non riesce se il valore di input ( k
) è un fattore 8. Questo è risolvibile, ma non senza allungare il codice della Math.Log
versione.