C # İkili sayıdaki ilk 1 (sağdan sola)


10

Bir sayının ikili gösterimi ilk 1 (sağdan sola) dizinini bulmak için C # kullanmaya çalışıyorum. Örneğin, ikili dosyada 100 olduğu için:

0b1100100

İlk 1 sağdan üçüncü konumda, bu nedenle 3 vermelidir.

234 2 vermelidir, 0 0 vermelidir vb.

İşte benim mevcut çözüm:

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

Bunu kısaltmanın herhangi bir yolu var mı?


1
Açık olan uç yabancı boşluğunuzu kaldırmaktır. Kolayca çıkarabileceğiniz 10 alan görüyorum.
James

Convert.ToString(k,2).IndexOf("1")istediğiniz şey, ya da benzer bir şey olsa, yanlış site.
Sihirli Ahtapot Urn

14
@ yakın seçmenler - Neden yakın oylar? Bence bu konu üzerine ipuçları sorusu. Yoksa bu konuda kaçırdığım herhangi bir kural değişikliği oldu mu?
Dijital Travma

Yanıtlar:


3

Sadece C # destekli makineye özgü yapısallar… Bunu x86 montaj dilinde ve diğer işlemci mimarilerinin çoğunda yapabilen tek bir komut vardır. O zaman sadece en kısa koda değil, aynı zamanda en hızlı koda sahip olursunuz.

Aslında, bu kodu daha kısa yapmak, bu kodu hızlı hale getirmeye kıyasla son derece sıkıcı bir sorundur . Gerçekten düzgün, verimli, biraz çevirme çözümleri var ve ayrıca bir arama tablosu kullanmayı düşünebilirsiniz.

Bunların hiçbiri golf oynamak için önemli değil. Bana şu anki çözümünüz yapabileceğiniz en iyi şey gibi geliyor. Tabii ki, gereksiz boşlukları kaldırabilirsiniz:

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

Ben şahsen şöyle yazar:

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

çünkü koşullu testin yönüne bu şekilde sahip olmanın yanı sıra sıfıra göre karşılaştırmanın biraz daha açık olduğunu düşünüyorum, ancak sanırım altı bir yol, yarım düzine diğeri.

C # örtük dönüştürme desteklemediği intiçin boolgerçekten koşullu testi başka kısaltmak edemez böylece, C ve C ++ yapmak gibi.

Ayrıca , C # öğesinin dolaylı olarak gerçekleşmesine izin vermeyeceğinden , double(döndürüldüğüm gibi Math.Log) ile arasındaki açık dökümle sıkışmışsınızdır int. Normalde bu size sahip olduğunu işaret olur çünkü iyi bir şey tabii, ki büyük Burada performans sorunu: Bir teşvik inta kadardouble günlüğünü hesaplamak doubleve ardından doublesonucu tekrar bir haline dönüştürmek çok yavaş intolacak , bu yüzden normalde bir şey kaçınmak istersiniz. Ancak bunlar, kod golf oynarken katlanmak zorunda olduğunuz sapkınlık türleri.


Başlangıçta

k > 0
      ? ((k & -k) >> 1) + 1
      : 0

(netlik için kurtulmuş), ki bu da logaritmayı almaktan kaçınır ve bu nedenle kod boyutunda ve hızında bir gelişmedir. Ne yazık ki, bu her zaman doğru cevabı alamıyor ve bunun esnek bir gereklilik olduğunu varsayıyorum. :-) Özellikle, giriş değeri ( k) 8 faktörü ise başarısız olur . Bu düzeltilebilir, ancak kodu Math.Logsürümden daha uzun yapmadan .


Kod golf için Mathtamamen nitelikli olması gerektiğini unutmayın, bu yüzden aslında bayt saymadım, ancak diğer sürüm daha iyi olmalıdır.
TheLethalCoder

Yanlış çıktıyı üreten mi demek istiyorsun? @the
Cody Gray

Peki, bunun bir çözümü olduğunu söylediniz, ancak daha uzun sürecek. Düzeltme, OPs sürümü içerdiğinden System.daha kısaysa, daha kısa ve doğru olmalıdır.
TheLethalCoder
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.