Số nguyên pha loãng


26

Một số nguyên dương có thể được pha loãng bằng cách chèn một 0giữa hai bit trong khai triển nhị phân của nó. Điều này có nghĩa là một nsố -bit có độ n-1pha loãng, không nhất thiết phải là tất cả.

Ví dụ: đối với 12(hoặc 1100ở dạng nhị phân), độ pha loãng là

11000 = 24
   ^

11000 = 24
  ^

10100 = 20
 ^

Trong thử thách này, chúng tôi sẽ lấy tổng của tất cả các pha loãng, không bao gồm số ban đầu. Đối với 12, lấy tổng số 24, 24, 20kết quả trong 68, do đó 68nên là đầu ra cho 12.

Thử thách

Cho một số nguyên dương n > 1làm đầu vào, đầu ra / trả về tổng số pha loãng như được giải thích ở trên.

Ví dụ

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

Quy tắc

  • Đầu vào và đầu ra có thể được coi là phù hợp với kiểu số nguyên của ngôn ngữ của bạn.
  • Đầu vào và đầu ra có thể được đưa ra trong bất kỳ định dạng thuận tiện .
  • Một chương trình đầy đủ hoặc một chức năng được chấp nhận. Nếu một chức năng, bạn có thể trả lại đầu ra thay vì in nó.
  • Sơ hở tiêu chuẩn bị cấm.
  • Đây là vì vậy tất cả các quy tắc chơi gôn thông thường đều được áp dụng và mã ngắn nhất (tính bằng byte) sẽ thắng.

"Bất kỳ định dạng thuận tiện" có bao gồm một chuỗi nhị phân?
Xù xì

1
@Shaggy "Bất kỳ định dạng thuận tiện" được dự định bao gồm các phương thức nhập / xuất, không phải định dạng . Như vậy, tôi sẽ nói không, bạn phải lấy đầu vào là một số nguyên hoặc một chuỗi đại diện cho số nguyên đó.
admBorkBork

Thử thách tốt đẹp!
Manish Kundu

1
Trình tự này hiện tại (ngày 30 tháng 1 năm 2018) không có trong OEIS
Giuseppe

Câu trả lời:


12

Python 2 , 43 39 byte

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

Hãy thử trực tuyến!


Làm sao?

Mỗi cuộc gọi của hàm đệ quy tính toán một độ pha loãng duy nhất. Vị trí của chèn 0log2(i). Hàm đệ quy cho đến khi ilớn hơn nvà phần chèn sẽ ở bên trái của số. Nếu i>n, n/iđánh giá để0 , đó là một giá trị giả trong Python.

n*2 thay đổi toàn bộ chữ số nhị phân số một còn lại, n%i hoặc n % 2**(position of insertion)tính giá trị của phần không nên dịch chuyển sang trái. Giá trị này được trừ vào số đã thay đổi.

Ví dụ (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

Thạch , 11 byte

BJṖ2*ɓdḅḤ}S

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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 byte

tZl:W&\5ME*+s

Hãy thử nó tại MATL Online! Hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình

Hãy xem xét đầu vào 12là một ví dụ.

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 byte

Cảm ơn @Dennis vì đã lưu hai byte!

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

Hãy thử trực tuyến!

C (gcc) , 50 byte

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

Quay trở lại k=s;là hành vi không xác định, nhưng hoạt động với gcc khi tối ưu hóa bị vô hiệu hóa. Ngoài ra, n%k+n/k*(k+=k)hành vi không xác định , nhưng dường như hoạt động tốt với gcc.

Hãy thử trực tuyến!


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

1
Không biết ai được đánh giá đầu tiên n%khay n/k*(k*=2).
Steadybox

1
@KevinCruijssen Bên nào được đánh giá đầu tiên là không xác định. C là như thế ...
Steadybox

2
Ah, tôi thấy bạn đã thêm vào đó trong câu trả lời của bạn. Tôi không biết loại hành vi không xác định này xảy ra ở C. Tôi có ba giờ trải nghiệm ở C, vì vậy tôi hầu như không biết gì về nó. TIL :) Trong Java for(s=0,k=2;k<=n;)s+=n%k+n/k*(k*=2);return s;là hoàn toàn tốt, và n%ksẽ luôn được đánh giá trước n/k*(k*=2)n/kcũng sẽ đánh giá trước k*=2. Cảm ơn đã giải thích. (Tôi sẽ xóa một số bình luận của mình ngay bây giờ để giảm sự lộn xộn.)
Kevin Cruijssen

Tôi thích sử dụng UB như một tính năng. Và chơi golf mã bằng ngôn ngữ ngoài đời thực dù sao cũng nên ở một hạng mục khác :)
Regis Portalez

4

Thạch , 9 8 byte

BḊḄÐƤạḤS

Hãy thử trực tuyến!

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

Ngược lại , B¹ƤṖ+BḄS: lấy tiền tố, thả cuối cùng, thêm chúng vào đầu vào và tính tổng.


4

J , 20 15 14 byte

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

Hãy thử trực tuyến.

15 byte

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

Hãy thử trực tuyến!

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

Tại sao công thức trừ kép hoạt động? Tại sao nó tương đương với pha loãng?
Giô-na

1
Pha loãng @Jonah là thêm một tiền tố nhị phân nhất định (số "làm tròn xuống") vào số, tương đương với việc thêm toàn bộ số vào chính nó (cả tiền tố và phần còn lại) và sau đó trừ đi phần còn lại.
FrownyFrog

4

Japt , 12 11 byte

¢¬£¢iYTÃÅxÍ

Thử nó


Giải trình

                 :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 byte

Đã lưu 1 byte nhờ Mr.Xcoder

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

Các trường hợp thử nghiệm


3

Võng mạc , 53 50 47 byte

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

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm. Chỉnh sửa: Đã lưu 3 byte nhờ @MartinEnder. Giải trình:

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

Chuyển đổi từ thập phân sang nhị phân, nhưng sử dụng O để biểu thị 0, vì nó không phải là một chữ số và _ để đại diện cho 1, vì đó là ký tự lặp lại mặc định trong Retina 1.

L$`\B
$`O$'

Chèn một chữ O giữa mỗi cặp chữ số và thu thập kết quả dưới dạng danh sách.

+%`\B
¶$`¶

Chuyển đổi từ nhị phân sang đơn nguyên. (Chuyển đổi này tạo thêm Os, nhưng chúng tôi không quan tâm.)

_

Tổng và chuyển thành số thập phân.


Chuyển đổi nhị phân sang thập phân có thể được thực hiện trong 12 byte (tiết kiệm 3): tio.run/##K0otycxLNPz/ Lỗi Xem câu trả lời này để biết cách hoạt động.
Martin Ender

@MartinEnder Cảm ơn, tôi tiếp tục quên điều đó. (Tôi cũng hơi thất vọng vì phiên bản thay thế chỉ hoạt động trên một số duy nhất.)
Neil

Chà, trong trường hợp bạn có mỗi số trên một dòng riêng, bạn có thể làm cho nó hoạt động với một số bổ sung %. Nếu nó phức tạp hơn, bạn cần một cái gì đó như /[O_]+/_.
Martin Ender

2

Bình thường , 13 byte

smiXd.BQZ2Ssl

Hãy thử nó ở đây!

Giải trình

smiXd.BQZ2Ssl | Chương trình đầy đủ.

           sl | Logarit cơ sở-2 của đầu vào, trôi nổi đến một số nguyên.
          S | Tạo phạm vi số nguyên [1 ... logarit nổi].
 m | Và ánh xạ một chức năng trên nó.
------------ + - + ----------------------------------- ------------------
  iXd.BQZ2 | Hàm được ánh xạ (sử dụng biến d).
     .BQ | Trong biểu diễn nhị phân của đầu vào ...
   XZ | ... Chèn số không ...
    d | ... Tại chỉ số d.
  tôi 2 | Và chuyển đổi kết quả từ cơ sở 2 thành một số nguyên.
------------ + - + ----------------------------------- ------------------
s | Tổng hợp danh sách kết quả.

2

Thạch , 10 byte

BµLḤ_J’×µḄ

Hãy thử trực tuyến!

Không phải là ngắn nhất hiện tại, nhưng nó có thể là nếu có một cách xung quanh Bµ µḄ ...

Giải trình

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.

Về cơ bản, điều này hoạt động bằng cách nhân mỗi chữ số nhị phân với một số ma thuật. Tôi không thể giải thích nó mà không hình dung ra nó, vì vậy đây là số nhị phân chúng tôi sẽ làm việc với:

1111

Như được giải thích bởi thử thách, đầu ra anh ta muốn là tổng của các số nhị phân này:

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

Tuy nhiên, chúng tôi thực sự không phải chèn số không: nguyên tử "không phân biệt" của Jelly sẽ chấp nhận các số khác ngoài 01. Khi chúng ta cho phép mình sử dụng 2, mẫu này sẽ đơn giản hơn:

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

Khi chúng tôi tổng hợp các chữ số trong mỗi cột, chúng tôi nhận được

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

Thủ thuật mà câu trả lời này sử dụng là tạo ra mẫu này và nhân từng chữ số với chữ số tương ứng trong bản gốc để hủy bỏ các cột cần thiết. 12, ví dụ, sẽ được đại diện là

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


1

Husk , 13 12 byte

-1 byte nhờ @Mr. Xcoder!

ṁḋ§z·+Θḣotṫḋ

Hãy thử trực tuyến!

Giải trình

ṁḋ§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 byte

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

Hãy thử trực tuyến!

Giải trình

Gọi số đầu vào của chúng tôi a. Đối với mỗi chỉ số nhị phân imà tại đó chúng ta muốn chèn số 0, chúng ta có thể tính các bit còn lại của điểm chèn là a // 2**i(trong đó //phân chia số nguyên và **lũy thừa), các bit bên phải của điểm chèn là a % 2**i, và do đó là số nguyên pha loãng như 2 * (a // 2**i) * 2**i + (a % 2**i). Nhưng (a // 2**i) * 2**ibằng a - (a % 2**i), và vì vậy chúng ta có thể sắp xếp lại thành một công thức ngắn hơn: 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 byte

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

Hãy thử trực tuyến!

Hoặc là tôi đang làm điều gì đó thực sự sai hoặc R chỉ là khủng khiếp khi thao túng bit. Porting cách tiếp cận Luis Mendo của rất dễ dàng, chính xác, và golfy.

Nhưng nếu bạn thực sự chỉ muốn thực hiện các thao tác bit, MickyT đã đề xuất 105 byter sau:

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

Hãy thử trực tuyến!


Đây là một byte 111 mà tôi chắc chắn rằng bạn có thể lấy thêm một vài trong số đó.
MickyT

@MickyT Chúc mừng! rất đẹp, mặc dù chuyển một cách tiếp cận hoàn toàn khác là tốt hơn!
Giuseppe


1

Mẻ, 92 77 byte

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

Chỉnh sửa: Chuyển sang cùng một công thức mà mọi người khác đang sử dụng.




0

Tùy viên , 57 byte

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

Hãy thử trực tuyến!

Tôi nghĩ rằng tôi đã tiếp cận vấn đề từ cách tiếp cận thao tác không bit, vì cách tiếp cận như vậy là không thực tế trong Attache. Tôi phải điều tra một số phần của phương pháp này để tìm giải pháp thay thế.

Giải trình

Đây là một phiên bản mở rộng:

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

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

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

Điều này chỉ đơn giản là lấy biểu diễn nhị phân của số, chia nó tại một số điểm nhất định, chèn các số 0 ở đó, chuyển đổi thành số thập phân và tính tổng chúng lại với nhau.


0

J , 33 byte

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

Hầu hết có lẽ có nhiều chỗ để chơi gôn.

Làm sao?

@#: chuyển đổi thành nhị phân và

<@}.\. - tìm tất cả các đủ, bỏ chữ số đầu tiên từ mỗi và hộp

<\ - tìm tất cả các tiền tố và đóng hộp chúng

(,0;])"0 - với mỗi tiền tố nối 0 sau đó nối thêm hậu tố chặt đầu tương ứng

;@ cào (unbox)

1#.[:}:#.@ - chuyển đổi thành số thập phân, số đuôi và tổng

Hãy thử trực tuyến!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.