İkili arama için adım sayısı


12

Pozitif bir tamsayının bir girdisi verildiğinde, 1'den başlayan bir ikili arama yoluyla girişi bulmak için gereken adım sayısını çıktılayın.

Girdi olarak verilen tamsayı için ikili bir aramayı simüle ediyoruz, buradaki simüle edilmiş araştırıcı tekrar tekrar bir tamsayıyı tahmin edebilir ve çok yüksek, çok düşük veya doğru olup olmadığını söyleyebilir. Tamsayıyı bulma stratejisi aşağıdaki gibidir:

  • N, bulmaya çalıştığımız girdi olarak verilen tam sayı olsun.

  • 1 tahminiyle başlayın. (Her tahmin için, adım sayısını artırın (doğru olup olmadığına bakılmaksızın) ve tahminin doğru olması durumunda derhal toplam adım sayısını durdurup çıktılayın.)

  • Tahmin n'den (hedef sayı) büyük olana kadar tahminleri iki kez tekrarlayın. (Veya doğruysa, ancak bu yukarıda belirtilen doğru tahmin kuralımız tarafından kapsanmaktadır.)

  • Şimdi, 2'nin ilk gücünün n'den büyük olan bir üst sınırını ayarlayın (yani tahmin edilen sayı) ve doğrudan 2'nin altındaki gücün bir alt sınırını ayarlayın.

  • Üst sınır ve alt sınırın ortalamasını (aşağı yuvarlanmış) tekrar tekrar tahmin edin. Çok yüksekse, üst sınır olarak ayarlayın. Çok düşükse, alt sınır olarak ayarlayın. Bu prosedürün sonunda doğru bir tahminde bulunulması garanti edilir.

İşte n = 21 girişi için bir örnek:

1 -> 2 -> 4 -> 8 -> 16 -> 32 -> 24 -> 20 -> 22 -> 21
\__________________________/
   repeated doubling      \________________________/
                             repeated averaging

Bu , bayt cinsinden en kısa kod kazanacaktır.

İşte n = 1 ile n = 100 arasındaki tüm çıktılar:

1
2
4
3
6
5
6
4
8
7
8
6
8
7
8
5
10
9
10
8
10
9
10
7
10
9
10
8
10
9
10
6
12
11
12
10
12
11
12
9
12
11
12
10
12
11
12
8
12
11
12
10
12
11
12
9
12
11
12
10
12
11
12
7
14
13
14
12
14
13
14
11
14
13
14
12
14
13
14
10
14
13
14
12
14
13
14
11
14
13
14
12
14
13
14
9
14
13
14
12

Ve bazı büyük test örnekleri:

1234 -> 21
1337 -> 22
3808 -> 19
12345 -> 28
32768 -> 16
32769 -> 32
50000 -> 28

Yanıtlar:


10

Japt, 13 12 bayt

Aman tanrım, hem Jelly'i hem de Pyth'i bir süre dövüyordum: D

¢a1 ªJ +1+¢l

Çevrimiçi test edin!

İşte kullandığım strateji: x , girdi tamsayı olsun ve b , x'in ikili temsili olsun. Doğru çıkış 1 + uzunluğu b + geçen bir dizin 1 içinde b , eksi 1 bu indeks 0 ise.


2
Sana Dennis'in kazanacağını söylemiştim.
lirtosiast

7

Jöle, 18 15 10 9 bayt

B>WU;BḄBL

Çevrimiçi deneyin! veya küçük test senaryolarını ve büyük test vakalarını doğrulayın .

Arka fon

Let , n olacak pozitif bir tamsayı ve m en küçük güç 2 büyük veya daha eşit ya da ona eşit olan n .

  • Katlama aşaması ikili gösterimi her basamak için bir adım alır m .

  • N'nin ikili gösterimini alın, ilk, en önemli basamağı (her zaman 1 ) ve tüm izleyen sıfırları kaldırın . Ortalama aşaması kalan her basamak için bir adım alır.

Hesaplarken kaçınmak için m , biz, o gözlemlemek n <m , ikili hane sayısı n az ikili basamak sayısından tam bir tanesidir m .

N'nin ilk ikili rakamını 0 ile değiştirirsek, sonucu tersine çevirir, orijinal ikili rakamları ekler ve tüm önde gelen sıfırları kaldırırsak, aşağıdakiler olur:

  • Eğer n, bir güç 2 , bütün (değiştirilmiş) birinci basamak yarı orijinal ikili gösterimine yalnızca basamak bırakarak kaldırılır n = m .

  • Eğer n, bir değil, bir güç 2 , en önemli basamak karşılık gelir gelmez ilk yarısında basamaklı olmayan gerçeği telafi uzaklaştırılamaz n az bir ikili sayı vardır m .

Nasıl çalışır

B>WU;BḄBL  Main link. Input: n

B          Compute the binary representation of n.
 >W        Compare it with [n].
           n is positive, so it is not less than the first binary digit and the
           comparison yields zero. When comparing lists of different length, the
           elements in the longer list that do not have a pair remain untouched.
           Therefore, this will just zero out the first binary digit.
   U       Reverse the modified binary representation.
    ;B     Concatenate it with the unmodified binary representation of n.
      ḄB   Convert from binary to integer, and back to binary.
           This removes leading zeroes.
        L  Get the length of the resulting array.

’B;Bt0L(7 bayt) ile aynı yaklaşımı kullanarak, Jelly en son sürümünde çalışır benim Julia cevap .
Dennis

4

ES6, 38 bayt

x=>33-(g=Math.clz32)(x-1)+g(x&-x)-g(x)

Diğer cevaplarla belirtildiği gibi, ilk ve son bitlerin konumlarından adım sayısını hesaplayabilirsiniz.

Katlama aşamasındaki adım sayısı n=33-Math.clz32(x-1). 2ⁿ ≥ x istiyoruz ama n=33-Math.clz32(x)bize 2ⁿ> x veriyoruz, bu yüzden telafi etmek için 1'den x çıkarırız.

Ortalamalama aşamasındaki adım sayısı daha kolaydır, basittir n=Math.clz32(x&-x)-Math.clz32(x). x&-xen düşük biti x(2'nin gücü olarak) değerlendiren kullanışlı bir ifadedir .


Nasıl x&-xçalışır? Bunun x'in mutlak değerini değerlendireceğini düşünürdüm.
ETHproductions

2
Bu sayfada iyi bir açıklama buldum (bkz. Bit-hack # 7).
ETHproductions

2

Pyth, 15 13 bayt

h-y.ElQ/PPyQ2

Hesaplanacak sayının 1 + 2*ceil(log_2(x)) - [number of 2s in x's prime factorization, minus 1 if x is a power of 2 greater than 1].

Burada deneyin .


2

Julia, 37 35 bayt

n->endof(strip(bin(n-1)bin(n),'0'))

@AlexA sayesinde. 2 bayt tasarruf için!

Bu, Jelly cevabımdaki gözlemleri izler , ancak uç vakalarla farklı şekilde ilgilenir.

Eğer , n> 1 , bir ikili gösterimini n - 1 daha az olan bir sonraki güç birine göre bir basamak vardır , 2 ikili gösterimi ilk rakamı çıkarılması değil telafi edilir, n .

Her iki taraftan da tüm sıfırları kaldırarak kenar durumu 1 ile de ilgileniriz .


0

Haskell, 82 bayt

Bu, Haskell'de oldukça basit bir uygulamadır:

f x=[j|j<-[1..],let g i|i<2=1|x>g(i-1)=2*g(i-1)|1<2=div(g(i-1)+g(i-2))2,g j==x]!!0

Daha az golf:

f x = head [ stepNum | stepNum <- [1..], step stepNum == x]
  where
    prevStep i = step (i-1)
    step i | i == 1         = 1
           | x > prevStep i = 2 * prevStep i
           | otherwise      = div (prevStep i + step (i-2)) 2
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.