C # Primo 1 (da destra a sinistra) in numero binario


10

Sto cercando di usare C # per trovare l'indice del primo 1 (da destra a sinistra) nella rappresentazione binaria di un numero. Ad esempio, poiché 100 in binario è:

0b1100100

Il primo 1 è nella terza posizione da destra, quindi dovrebbe dare 3.

234 dovrebbe dare 2, 0 dovrebbe dare 0, ecc.

Ecco la mia soluzione attuale:

k < 1 ? 0 :(int)Math.Log(k & -k, 2) + 1;

In che modo posso accorciarlo?


1
Il consiglio ovvio è rimuovere lo spazio bianco estraneo. Vedo 10 spazi che potresti facilmente rimuovere.
James,

Convert.ToString(k,2).IndexOf("1")è quello che vuoi, o qualcosa di simile, sito sbagliato però.
Magic Octopus Urn

14
@ votanti ravvicinati - Perché i voti stretti? Penso che questa sia una domanda di suggerimenti sull'argomento . O ci sono state delle modifiche alle regole che mi sono perso in questo senso?
Trauma digitale

Risposte:


3

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 inta boolcome 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 intin a double, calcolare il registro di un doublee quindi riconvertire il doublerisultato in un intsarà 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.Logversione.


Si noti che per il golf del codice Mathdovrebbe essere pienamente qualificato, quindi l'altra versione dovrebbe essere migliore anche se in realtà non ho contato i byte.
TheLethalCoder

Intendi quello che produce un output sbagliato? @the
Cody Grey,

Bene, hai detto che c'è una soluzione, ma lo allungherebbe di più. Se la correzione è più breve di quando include la versione dei PO System., dovrebbe essere più breve e corretta.
TheLethalCoder
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.