Alternatif bit bulaşması


12

Giriş

Bu zorluk, bir tamsayı ikili gösteriminin sondaki sıfırlarını ayarlamanızı gerektirir 010101…, bu en iyi bir örnekle açıklanır:

Tam sayı göz önüne alındığında, 400ilk adım onu ​​ikiliye dönüştürmektir:

110010000

Beşinci bitin en az anlamlı bit olduğunu görebileceğimiz için 1, oradan başlayarak alt sıfırları şu şekilde değiştiririz 0101:

110010101

Sonunda bunu ondalığa çeviriyoruz: 405

Meydan okuma

Pozitif bir tamsayı dönüşü / çıktısı verildiğinde, yukarıda tanımlanan işlemin karşılık gelen sonuç değeri.

kurallar

  • Bu sıra yalnızca en az bir 1bitli tamsayılar için tanımlanır , bu nedenle giriş her zaman ≥ 1 olur
  • Girişi dize, rakam listesi (ondalık) olarak alabilirsiniz
  • Geçersiz girdileri işlemek zorunda değilsiniz

testcases

İşte aracı adımlarla bazı test senaryoları (bunları yazdırmanız / iade etmeniz gerekmez):

In -> … -> … -> Out
1 -> 1 -> 1 -> 1
2 -> 10 -> 10 -> 2
3 -> 11 -> 11 -> 3
4 -> 100 -> 101 -> 5
24 -> 11000 -> 11010 -> 26
29 -> 11101 -> 11101 -> 29
32 -> 100000 -> 101010 -> 42
192 -> 11000000 -> 11010101 -> 213
400 -> 110010000 -> 110010101 -> 405
298 -> 100101010 -> 100101010 -> 298

32 bitlik bir tamsayı varsayabilir miyiz?
Arnauld

@Arnauld: Elbette!
ბიმო

9
Bazı golf fikri: Eğer ngirdiyi bölen 2'nin maksimum gücü ise, o zaman cevap basittir(input) + ceil((2^n - 2)/3)
JungHwan Min

Yanıtlar:


12

Python 3 , 20 bayt

lambda n:(n&-n)//3+n

Çevrimiçi deneyin!

açıklama

Örnek 192olarak alalım. İkili formu 11000000ve onu dönüştürmemiz gerekiyor 11010101.

10101Numaraya eklememiz gerektiğini not ediyoruz . Bu, 4^0 + 4^1 + 4^2kapalı bir forma sahip geometrik bir seri ( ) (4^3-1)/(4-1). Bu aynı 4^3//3burada //bölme tamsayıdır belirtmektedir.

Eğer öyleyse 101010, yine de yukarıdaki nedenlerden dolayı geometrik bir seri ( 2×4^0 + 2×4^1 + 2×4^2) olurdu 2×4^3//3.

Her neyse 4^3ve 2×4^3şu şekilde elde ettiğimiz en az önemli bit olacaktır n&-n:

Biz tamamlayıcısı olduğunu fark nolduğunu 00111111. Birini eklersek, olur 01000000ve yalnızca n=11000000en az anlamlı basamakla çakışır . "Tamamlayıcı ve bir tane ekleyin" sadece olumsuzlama olduğunu unutmayın.


6
@ Mr.Xcoder güzel sporcu
Leaky Nun

1
Muhtemelen de lambda n:(n&-n)//3+nçalışıyor mu? Tüm test örneklerini geçer , ancak sezgilerime göre geçerli olmamalı, değil mi?
Bay Xcoder

@ Mr.Xcoder gerçekten geçerlidir.
Leaky Nun

1
Neden bir bayt kaydetmek için Python 2 kullanmıyorsunuz? TIO
FlipTack

4
@FlipTack Python 2'den nefret ediyorum
Leaky Nun

8

Jöle , 5 bayt

&N:3+

Çevrimiçi deneyin!

Bu kez Leaky Nun'in yaklaşımının bir limanı (en azından ben onu biraz golf aşağı yardımcı oldu: P)

Jöle , 7 bayt

^N+4:6ạ

Çevrimiçi deneyin!

Martin Ender'in dolaylı yardımı ile JungHwan Min'in fantastik yaklaşımını kullanır .


Dennis, bu düzenlemeyi yaptıktan hemen sonra benzer bir 5 baytlık çözüm gönderdi, sonra sildi . Gibi bir şey &N:3|. Tebrikler; Dennis'i Jelly'de yendin! (Ama oldukça golf oynamak değil.)
wizzwizz4

@ wizzwizz4 Leaky'nin yaklaşımına küçük bir golf önermek ve daha sonra bunu taşımak dışında gerçekten fazla bir şey yapmadım. Ama ha :-)
Bay Xcoder

Bu şimdiye kadar gördüğüm ilk ASCII sadece Jelly cevabı.
MD XF

6

Wolfram Dili (Mathematica) , 36 28 26 24 bayt

@MartinEnder sayesinde -8 bayt ve @ Mr.Xcoder sayesinde -2 bayt

#+⌊(#~BitAnd~-#)/3⌋&

Çevrimiçi deneyin!

Sadece girişteki izleyen sıfırların sayısını bulmamız 0ve 1uzunluğu ve uzunluklarından daha az olan s ve s değişkenlerini bulmamız ve girişe eklememiz gerekir.

Yani, 400 -> 11001000 -> 110010000 + 0000 -> 110010101 + 101 -> 405

nAlternatif 1s ve 0s içeren th sayısı için açık formül OEIS'de A000975'te verilmiştir . Biz kullanabilirsiniz nhiçbir iki farklı numaralar aynı ikilik sistemde uzunluğu ve rakamları alternatif var çünkü inci numarayı.


1
2^#~IntegerExponent~2olduğunu(BitXor[#,#-1]+1)/2
Martin Ender

@MartinEnder vay! Ve sonra daha fazla baytı azaltmak için kesirleri birleştirebilirim
JungHwan Min

1
24 bayt . Bunun #+⌊(#~BitAnd~-#)/3⌋&yerine kullanabilirsiniz .
Bay Xcoder

@ Mr.Xcoder düzenledi :)
JungHwan Min

5

J , 19 18 bayt

+(2|-.i.@#.-.)&.#:

Çevrimiçi deneyin!

Hızlı Açıklama

Bu eski bir cevaptır, ancak doğada mevcut olana çok benzer, sadece takip eden sıfırları farklı şekilde sayar. Nasıl çalıştığını açıklayan bir bağlantı için yorumlara bakın.

+(2|i.@i.&1@|.)&.#:
                 #:  Convert to binary list
       i.&1@|.       Index of last 1 from right
            |.         Reverse
       i.&1            Index of first 1
    i.               Range [0, index of last 1 from right)
  2|                 That range mod 2
               &.    Convert back to decimal number
+                    Add to the input

Diğer Cevaplar:

Önceki yanıt (19 bayt).

+(2|i.@i.&1@|.)&.#:

Olması gerekenden daha uzun çünkü \sağdan sola gidiyor.

+(2|#*-.#.-.)\&.(|.@#:)

1
18 bayt+(2|-.i.@#.-.)&.#:
miles

@miles mind orada temel dönüşüm ile neler olduğunu açıklıyor? Sanırım sıfırlarla bir ilgisi var ama emin değilim.
cole

#.~ sondaki gerçekleri sayar , bu yüzden ihtiyacımız #.~ -. #:olan sondaki sıfırları saymaktır
mil

@miles Ah! Bu çok ama çok akıllı.
cole

4

Julia 0.6 , 12 bayt

!n=n|n&-n÷3

Çevrimiçi deneyin!


Bu etkili bir yöntem gibi görünüyor, operatörün önceliğini açıklayabilir misiniz? Örneğin ((!n=(n|n))&-n)/3, ya da !n=(((n|n)&(-n))/3)vb. Olarak değerlendirilip değerlendirilmediğini söyleyemem
MD XF

Julia'da, bitsel operatörler aritmetik muadilleriyle aynı önceliklere sahiptir, bu yüzden |benzerdir +ve &gibidir *. Bu nedenle, n|n&-n÷3olarak ayrıştırılır n | ((n&-n) ÷3).
Dennis

3

JavaScript (ES6), 40 39 bayt

Girişi 32 bit tam sayı olarak alır.

n=>n|((n&=-n)&(m=0xAAAAAAAA)?m:m/2)&--n

Test senaryoları



2

R , 71 58 bayt

-6 bayt için NofP sayesinde

function(n){n=n%/%(x=2^(0:31))%%2
n[!cumsum(n)]=1:0
n%*%x}

Çevrimiçi deneyin!

Girişin 32 bitlik bir tam sayı olduğunu varsayar. R zaten yalnızca 32 bit tamsayılar ( doublebir tamsayı taştığında yayınlanıyor) ve 64 bit veya imzalanmamış girişler içermiyor.


65 baytlık bir çözüm elde which.max(n):1-1etmek !cumsum(n)için dönüştürebilirsiniz
NofP

@NofP teşekkürler! Bu güzel bir fikir.
Giuseppe

2

brainfuck , 120 bayt

>+<[[>-]++>[[>]>]<[>+>]<[<]>-]>[-<+>[-<[<]<]>]>[>]<[>+<[->+<]<[->+<]<]>>[<]+>[-[-<[->+<<+>]>[-<+>]]<[->++<]<[->+<]>>>]<<

Çevrimiçi Deneyin!

Geçerli hücredeki değerle başlar ve çıktı değeri olan hücrede biter. Açıkçası 255'in üzerindeki sayılar üzerinde çalışmaz, çünkü tipik beyin fırtınası için hücre sınırı budur, ancak sonsuz hücre boyutunu varsayarsanız çalışacaktır.


1

PowerShell , 168 bayt

param($n)$a=($c=[convert])::ToString($n,2);if(($x=[regex]::Match($a,'0+$').index)-gt0){$c::ToInt32(-join($a[0..($x-1)]+($a[$x..$a.length]|%{(0,1)[$i++%2]})),2)}else{$n}

Çevrimiçi deneyin!

Ahh. İkili ve dizi dilimlemeye / dilimlemeye dönüştürme gerçekten PowerShell'in güçlü giysileri değildir.

Girişi $nsayı olarak alır. Bunu convertikili tabana derhal 2ve içine saklarız $a. Sonra bir if / else yapımız var. İf cümlesi , string ( ) öğesinin sonundaki a regex Matchveya 1 0s'nin '0+$'kendisinden indexdaha büyük bir konumda olup olmadığını test eder 0(yani, ikili dizenin başlangıcı). Eğer öyleyse, çalışacak bir şeyimiz var, elsesadece sayı çıktısı veriyoruz.

İçinde if, biz dilim xinci birinci basamağı ve dizi concatenate +kalan rakam ile. Ancak, kalan basamaklar için, bunlar arasında dolaşırız ve bunun yerine seçmek için a 0ya 1da çıktı olarak seçilir $i++%2. Bu bize sonunda s 010101...yerine desen verir 0. Sonra -joinbunu tekrar bir dizgiye dönüştürüyoruz ve $conu bir Int32tabandan geri çeviriyoruz 2.

Her iki durumda da, sayı boru hattında bırakılır ve çıktı örtüktür.


1

APL + WIN, 43 bayt

p←+/^\⌽~n←((⌊1+2⍟n)⍴2)⊤n←⎕⋄2⊥((-p)↓n),p⍴0 1

Ekran girişi istemleri









1

JavaScript ES6, 13 bayt

n=>(n&-n)/3|n

f = 
n=>(n&-n)/3|n
;
console.log (f(8));
console.log (f(243));
console.log (f(1048576));
console.log (f(33554432));




0

Jöle , 13 bayt

BŒgṪµ2Ḷṁ×CḄ+³

Çevrimiçi deneyin!

açıklama

Örnek bir giriş olarak 24 değerini ele alalım.

BŒgṪµ2Ḷṁ×CḄ+³
B                Binary representation of the input → 11000
 Œg              Group runs of equal length → [[1,1],[0,0,0]]
   Ṫ             Tail → [0,0,0]
    µ            New monadic link
     2Ḷ          [0,1] constant
       ṁ         Mold [0,1] to the shape of [0,0,0] → [0,1,0]
        ×        Multiply [0,1,0] by...
         C       1-[0,0,0]. If last bit(s) of the original input are 1 this will add nothing to the original input
          Ḅ      Convert to decimal from binary → 2
           +³    Add this with the original input → 26
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.