Seyreltilmiş Tam Sayı Toplamları


26

Pozitif bir tamsayı , ikili genişlemesine iki bit arasına yerleştirilerek seyreltilebilir0 . Bu, bir nbit sayısının n-1mutlaka tümüyle farklı olmayan dilüsyonları olduğu anlamına gelir .

Örneğin, 12(veya 1100ikili olarak) dilüsyonlar

11000 = 24
   ^

11000 = 24
  ^

10100 = 20
 ^

Bu mücadelede, orijinal sayı hariç tüm dilüsyonların toplamını alacağız. For 12toplamını alarak 24, 24, 20sonuçları 68, bu yüzden 68için çıktı olmalıdır 12.

Meydan okuma

n > 1Giriş olarak pozitif bir tamsayı verildiğinde , yukarıda açıklandığı gibi seyreltilmiş toplamı çıkarın / çıkarın.

Örnekler

in    out
---   ---
2       4
3       5
7      24
12     68
333  5128
512  9216

kurallar

  • Giriş ve çıktının, dilinizin yerel tamsayı tipine uyacağı varsayılabilir.
  • Giriş ve çıkış herhangi bir uygun formatta verilebilir .
  • Tam bir program veya bir işlev kabul edilebilir. Bir işlev varsa, çıktıyı yazdırmak yerine geri gönderebilirsiniz.
  • Standart boşluklar yasaktır.
  • Bu olduğundan, tüm normal golf kuralları geçerlidir ve en kısa kod (bayt cinsinden) kazanır.

"Herhangi bir uygun biçim", ikili bir dize içeriyor mu?
Shaggy

1
@Shaggy "Herhangi bir uygun biçim", biçim değil giriş / çıkış yöntemlerini içerir . Dolayısıyla, hayır diyeceğim, girdiyi bir tamsayı olarak ya da bu tamsayıyı temsil eden bir dize olarak almalısınız.
AdmBorkBork

Güzel meydan okuma!
Manish Kundu,

1
Bu sıra şu anda (30 Ocak 2018) OEIS
Giuseppe'de

Yanıtlar:


12

Python 2 , 43 39 bayt

f=lambda n,i=2:n/i and n*2-n%i+f(n,i*2)

Çevrimiçi deneyin!


Nasıl?

Özyinelemeli fonksiyonun her çağrısı tek bir dilüsyon hesaplar. Girilen pozisyonu 0olan log2(i). İşlev idaha büyük hale gelinceye kadar yeniden başlar nve ekleme sayının solunda olur. If i>n, Python'da sahte olan bir değer olarak n/ideğerlendirilir 0.

n*2sayının tamamını bir ikili basamak sola kaydırır n%iveya n % 2**(position of insertion)sola kaydırılmaması gereken parçanın değerini hesaplar. Bu değer, kaydırılan numaradan çıkarılır.

Örnek (n = 7)

call       n/i          bin(n)  n*2     n%i   dilution       return value

f(7, i=2)  3 => truthy  0b111   0b1110  0b1   0b1101 = 13    13 + f(7, 2*2) = 13 + 11 = 24
f(7, i=4)  1 => truthy  0b111   0b1110  0b11  0b1011 = 11    11 + f(7, 4*2) = 11 + 0 = 11
f(7, i=8)  0 => falsy                                        0

7

Jöle , 11 bayt

BJṖ2*ɓdḅḤ}S

Çevrimiçi deneyin!

Nasıl çalışır

BJṖ2*ɓdḅḤ}S  Main link. Argument: n (integer)

B            Binary; convert n to base 2. This yields a digit array A.
 J           Indices; yield [1, ..., len(A)].
  Ṗ          Pop; remove the last element, yielding [1, 2, ..., len(A)-1].
   2*        Elevate 2 to these powers, yielding [2, 4, ..., 2**(len(A)-1)].
             Let's call the result B.
     ɓ       Begin a new, dyadic chain, with left argument n and right argument B.
      d      Divmod; yield [n/b, n%b], for each b in B.
        Ḥ}   Unhalve right; yield 2b for each b in B, i.e., [4, 8, ..., 2**len(A)].
       ḅ     Unbase; convert each [n/b, n%b] from base 2b to integer, yielding
             (2b)(n/b) + (n%b).
          S  Take the sum.

5

MATL , 13 bayt

tZl:W&\5ME*+s

MATL Online'da deneyin ! Veya tüm test durumlarını doğrulayın .

açıklama

12Bir örnek olarak girişi düşünün .

t     % Implicit input. Duplicate
      % STACK: 12, 12
Zl    % Binary logarithm
      % STACK: 12, 3.584962500721156
:     % Range (rounds down)
      % STACK: 12, [1 2 3]
W     % Power with base 2, element-wise
      % STACK: 12, [2 4 8]
&\    % 2-output modulus, element-wise: pushes remainders and quotients
      % STACK: [0 0 4], [6 3 1]
5M    % Push array of powers of 2, again
      % STACK: [0 0 4], [6 3 1], [2 4 8]
E     % Multiply by 2
      % STACK: [0 0 4], [6 3 1], [4 8 16]
*     % Multiply, element-wise
      % STACK: [0 0 4], [24 24 16]
+     % Add, element-wise
      % STACK: [24 24 20]
s     % Sum of array. Implicit display
      % STACK: 68

4

C,  58  56 bayt

İki byte tasarrufu için @Dennis'e teşekkürler!

s,k;f(n){for(s=0,k=2;k<=n;k*=2)s+=n/k*k*2+n%k;return s;}

Çevrimiçi deneyin!

C (gcc) , 50 bayt

s,k;f(n){for(s=0,k=2;k<=n;)s+=n%k+n/k*(k+=k);k=s;}

Geri dönüş k=s;, tanımsız davranış, ancak optimizasyonlar devre dışı bırakıldığında gcc ile çalışır. Ayrıca, n%k+n/k*(k+=k)sahip belirtilmemiş davranışı , ancak gcc ile çalışma cezası gibi görünüyor.

Çevrimiçi deneyin!


s,k;f(n){for(s=0,k=2;k<=n;)s+=n%k+n/k*(k*=2);return s;}(55 bayt)
Kevin Cruijssen

1
Bir ilk değerlendirilen alır bilemeyiz n%kya n/k*(k*=2).
Steadybox

1
@KevinCruijssen Hangi tarafın ilk değerlendirildiği belirtilmez. C böyle ...
Steadybox 16

2
Ah, cevabınıza gerçekten bunu eklediğinizi gördüm. Bu tür tanımsız davranışların C'de gerçekleştiğini bilmiyordum. C'de üç saatlik bir deneyime sahibim, bu yüzden neredeyse hiçbir şey bilmiyorum. TIL :) Java’da for(s=0,k=2;k<=n;)s+=n%k+n/k*(k*=2);return s;tamamen iyi ve n%kher zaman önce değerlendirilecek n/k*(k*=2)ve n/kdaha önce de değerlendirilecektir k*=2. Açıklama için teşekkürler. (Dağınıklığı azaltmak için şimdi yorumlarımdan bazılarını sileceğim.)
Kevin Cruijssen

UB'yi bir özellik olarak kullanmayı seviyorum. Ve gerçek hayatta bir dilde golf
oynamak,

4

Jöle , 9 8 bayt

BḊḄÐƤạḤS

Çevrimiçi deneyin!

B                        to binary          42 -> 1 0 1 0 1 0
 Ḋ                       drop first                 0 1 0 1 0
  ḄÐƤ                    each suffix to decimal   10 10 2 2 0
      Ḥ                  double the input                  84
     ạ                   absolute difference   74 74 82 82 84
       S                 add them up                      396

Tam tersi B¹ƤṖ+BḄS,: önekleri alın, en son bırakın, girdilere ekleyin ve toplayın.


4

J , 20 15 14 bayt

+/@}:@:+[\&.#:

Çevrimiçi deneyin.

15 bayt

1#.-,+:-#.\.@#:

Çevrimiçi deneyin!

     +:             Input×2
       -            Subtract
        #.\.@#:     The list of binary suffixes of input (in decimal)
   -,               Append negative input
1#.                 Add them up

çift ​​eksi formülü neden çalışıyor? neden dilüsyonlara eşittir?
Jonah,

1
@Jonah seyreltme, sayıya belirli bir ikili önek (sayı "yuvarlatılmış") ekler; bu sayı, tam sayıyı kendisine eklemeye eşittir (hem önek hem de geri kalanı) ve sonra kalanı çıkarır.
FrownyFrog

4

Japt , 12 11 bayt

¢¬£¢iYTÃÅxÍ

Dene


açıklama

                 :Implicit input of integer U
¢                :Convert to base-2 string
 ¬               :Split to an array of individual characters/digits
  £    Ã         :Map over the elements, with Y being the current 0-based index
   ¢             :  Convert U to a base-2 string
    iYT          :  Insert a 0 in that string at index Y
        Å        :Slice off the first element of the array
          Í      :Convert each element to a base-10 integer
         x       :Reduce by addition

3

JavaScript (ES6), 41 40 bayt

Mr.Xcoder sayesinde 1 bayt kaydedildi

f=(n,k=1)=>k<n&&(n&k)+2*(n&~k)+f(n,k-~k)

Test durumları


3

Retina , 53 50 47 bayt

.+
*
+`(_+)\1
$1O
O_
_
L$`\B
$`O$'
+%`\B
¶$`¶
_

Çevrimiçi deneyin! Link, test durumlarını içerir. Düzenleme: @MartinEnder sayesinde 3 bayt kaydedildi. Açıklama:

.+
*
+`(_+)\1
$1O
O_
_

Ondalıktan ikiliye dönüştürün, ancak 0'ı temsil etmek için O, bir basamak olmadığı için 0'ı ve Retina 1'deki varsayılan tekrarlama karakteri olduğu için _'i 1'i temsil etmek için kullanın.

L$`\B
$`O$'

Her basamak çiftinin arasına bir O yerleştirin ve sonuçları bir liste olarak toplayın.

+%`\B
¶$`¶

İkili dosyalardan tekli dosyalara dönüştürme. (Bu dönüşüm ekstra Os üretiyor , ancak umrumda değil.)

_

Topla ve ondalık dönüştür.


Ondalık dönüştürmeyle ikili dönüşüm 12 baytta yapılabilir (3 tasarrufu sağlayarak): tio.run/##K0otycxLNPz/… Nasıl çalıştığını görmek için bu cevaba bakınız .
Martin Ender

@MartinEnder Teşekkürler, bunu unutmaya devam ediyorum. (Alternatif versiyonun sadece tek bir numara üzerinde çalıştığını da biraz hayal kırıklığına
Neil

Eh, her numarayı kendi satırında bulduğunuzda, ek olarak çalışmasını sağlayabilirsiniz %. Daha karmaşıksa, bunun gibi bir şeye ihtiyacınız var /[O_]+/_.
Martin Ender

2

Pyth , 13 bayt

smiXd.BQZ2Ssl

Burada dene!

açıklama

smiXd.BQZ2Ssl | Tam program

           sl | Girişin baz-2 logaritması, bir tamsayıya döşenmiştir.
          S | Tamsayı aralığını [1 ... taban logaritması] oluşturun.
 m | Ve üzerinde bir fonksiyonun haritasını çıkarın.
------------ + - + ----------------------------------- ------------------
  iXd.BQZ2 | Eşlenecek işlev (bir değişken kullanır).
     .BQ | Girişin ikili gösteriminde ...
   XZ | ... Sıfır ekle ...
    d | ... Dizinde d.
  ben 2 | Ve sonucu taban 2'den bir tam sayıya dönüştürün.
------------ + - + ----------------------------------- ------------------
s | Çıkan listeyi toplayın.

2

Jöle , 10 bayt

BµLḤ_J’×µḄ

Çevrimiçi deneyin!

Şu anda en kısa değil, ama bir yol varsa Bµ µḄ...

açıklama

BµLḤ_J’×µḄ    Main link. Argument: n (integer)
B             Binary; convert n to an binary of binary digits. Call this A.
 µ            Start a new monadic link with argument A.
  L           Length; yield len(A). We'll call this l.
   Ḥ          Unhalve; yield l * 2.
     J        Length range; yield [1, 2, ..., l].
    _         Subtract; yield [l*2 - 1, l*2 - 2, ..., l].
      ’       Decrement; subtract one from each item.
       ×      Multiply each item by the corresponding item in A. Call this B.
        µ     Start a new monadic link with argument B.
         Ḅ    Unbinary; convert from a binary array to a decimal.

Temel olarak, bu her ikilik basamağı sihirli bir sayı ile çarparak çalışır. Görselleştirmeden açıklayamam, bu yüzden birlikte çalışacağımız ikili sayı:

1111

Mücadelede açıklandığı gibi, istediğimiz çıktı bu ikili sayıların toplamıdır:

10111  = 2^4 + 2^2 + 2^1 + 2^0
11011  = 2^4 + 2^3 + 2^1 + 2^0
11101  = 2^4 + 2^3 + 2^2 + 2^0

Ancak, aslında sıfır eklemek zorunda değiliz: Jelly'in "birleştirici" atomu sadece 0ve dışındaki sayıları kabul edecektir 1. Kullanmamıza izin verdiğimizde 2, bu kalıp daha da basitleşiyor:

2111   = 2*2^3 + 1*2^2 + 1*2^1 + 1*2^0
2211   = 2*2^3 + 2*2^2 + 1*2^1 + 1*2^0
2221   = 2*2^3 + 2*2^2 + 2*2^1 + 1*2^0

Her sütundaki basamakları topladığımızda,

6543   = 6*2^3 + 5*2^2 + 4*2^1 + 3*2^0 = 48 + 20 + 8 + 3 = 79.

Bu cevabın kullandığı numara, bu kalıbı oluşturmak ve gerekli sütunları iptal etmek için her basamağı orijinaldeki karşılık gelen basamakla çarpmaktır. 12, örneğin, temsil edilecek

 1100
×6543
=6500  = 6*2^3 + 5*2^2 + 0*2^1 + 0*2^0 = 48 + 20 + 0 + 0 = 68.


1

Kabuğu , 13 12 bayt

@Mr sayesinde -1 bayt. Xcoder!

ṁḋ§z·+Θḣotṫḋ

Çevrimiçi deneyin!

açıklama

ṁḋ§z·+Θḣ(tṫ)ḋ  -- example input: 6
            ḋ  -- convert to binary: [1,1,0]
  §            -- fork argument
        (tṫ)   -- | tail of tails: [[1,0],[0]]
       ḣ       -- | heads: [[1],[1,1],[1,1,0]]
   z           -- and zipWith the following (example with [1,0] [1])
    · Θ        -- | prepend 0 to second argument: [0,1]
     +         -- | concatenate: [1,0,0,1]
               -- : [[1,0,1,0],[1,1,0,0]]
ṁ              -- map the following (example with [1,0,1,0]) and sum
 ḋ             -- | convert from binary: 10
               -- : 22


1

Pip , 21 18 bayt

2*a-a%2**_MS1,#TBa

Çevrimiçi deneyin!

açıklama

Giriş numaramızı arayın a. iSıfır eklemek istediğimiz her ikili indeks için, ekleme noktasının kalan bitlerini a // 2**i( //tam sayı bölme ve **üst üssü olan), ekleme noktasının sağdaki bitleri a % 2**ive dolayısıyla seyreltilmiş tamsayı olarak hesaplayabiliriz 2 * (a // 2**i) * 2**i + (a % 2**i). Ancak (a // 2**i) * 2**ieşittir a - (a % 2**i)ve bu yüzden daha kısa bir formüle yeniden düzenleyebiliriz: 2 * (a - a % 2**i) + a % 2**i= 2 * a - a % 2**i.

2*a-a%2**_MS1,#TBa
                       a is 1st command-line argument (implicit)
               TBa     Convert a to binary
              #        Length of the binary expansion
            1,         Range from 1 up to (but not including) that number
          MS           Map this function to the range and sum the results:
2*a-a%2**_              The above formula, where _ is the argument of the function
                       The final result is autoprinted

1

R , 141 48 bayt

function(n,l=2^(1:log2(n)))sum(n%%l+(n%/%l*2*l))

Çevrimiçi deneyin!

Ya gerçekten yanlış bir şey yapıyorum ya da R sadece biraz manipülasyonda korkunç. Taşımak Luis Mendo'nun yaklaşımını kolay, doğru ve golf oynamak kolaydır.

Ancak gerçekten bit işlemleriyle uğraşmak istiyorsanız, MickyT aşağıdaki 105 baytı önerdi:

function(i)sum(sapply(1:max(which(b<-intToBits(i)>0)),function(x)packBits(head(append(b,F,x),-1),"i")))-i

Çevrimiçi deneyin!


İşte size bir kaç tane daha çıkarabileceğinden emin olduğum bir 111 byte .
MickyT

@MickyT Şerefe! çok güzel, tamamen farklı bir yaklaşımı benimsemekle birlikte daha iyi!
Giuseppe


1

Toplu iş, 92 77 bayt

@set/an=2,t=0
:l
@if %1 geq %n% set/at+=%1*2-(%1%%n),n*=2&goto l
@echo %t%

Düzenleme: Herkesin kullandığı aynı formüle geçildi.




0

Ataşesi , 57 bayt

Sum##UnBin=>{Join[Join=>_,"0"]}=>SplitAt#1&`:@{#_-1}##Bin

Çevrimiçi deneyin!

Ben bu soruna bit olmayan bir manipülasyon yaklaşımından yaklaşacağımı düşündüm, çünkü böyle bir yaklaşım Attache'de pratik değildi. Alternatifler için bu yaklaşımın bazı bölümlerini araştırmalıyım.

açıklama

İşte genişletilmiş bir versiyonu:

Define[$joinByZero, {Join[Join=>_,"0"]}]

Define[$insertionPoints,
    SplitAt#1&`:@{#_-1}
]

Define[$f,
Sum##UnBin=>joinByZero=>insertionPoints##Bin
]

Bu sadece sayının ikili gösterimini alır, belirli noktalara böler, buraya sıfırlar ekler, ondalık basamağa geri dönüştürür ve bunları bir araya toplar.


0

J , 33 bayt

1#.[:}:#.@(<\;@(,0;])"0<@}.\.)@#:

Büyük olasılıkla daha fazla golf oynamak için çok yer var.

Nasıl?

@#: ikiliye dönüştür ve

<@}.\. - Her şeyi bulmak, her birinden ilk haneyi bırakmak ve kutudan

<\ - tüm önekleri bul ve kutuya koy

(,0;])"0 - her önek için 0 ekleyiniz, ardından karşılık gelen başlı eki ekleyiniz

;@ pus (kutunun dışında)

1#.[:}:#.@ - Ondalık, kıvrık ve toplamı dönüştür

Çevrimiçi deneyin!

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.