희석 된 정수 합계


26

이진 확장에 두 비트 사이 를 삽입하여 양의 정수를 희석 할 수 있습니다 0. 이것은 n-비트 수에 n-1희석 이 있다는 것을 의미하며, 반드시 모두 고유하지는 않습니다.

예를 들어, 12(또는 1100이진수로) 희석은

11000 = 24
   ^

11000 = 24
  ^

10100 = 20
 ^

이 도전에서, 우리는 원래 숫자를 제외하고 모든 희석액의 합계를 취할 것입니다. 내용 12의 합을 가지고, 24, 24, 20그 결과를 68, 그렇게 68하기위한 출력한다 12.

도전

n > 1입력 으로 양의 정수가 주어지면 위에서 설명한대로 희석 합계를 출력 / 반환합니다.

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

규칙

  • 입력 및 출력은 언어의 기본 정수 유형에 맞는 것으로 가정 할 수 있습니다.
  • 입력 및 출력은 편리한 형식으로 제공 될 수 있습니다 .
  • 전체 프로그램 또는 기능이 허용됩니다. 함수 인 경우 출력하지 않고 출력을 반환 할 수 있습니다.
  • 표준 허점 은 금지되어 있습니다.
  • 이것은 이므로 모든 일반적인 골프 규칙이 적용되며 가장 짧은 코드 (바이트)가 이깁니다.

"편리한 형식"에 이진 문자열이 포함되어 있습니까?
얽히고 설킨

1
@Shaggy "상관 편리한 형식"포함되도록 의도 방법 입 / 출력하지 않는 형식 . 따라서 아니오라고 말하겠습니다. 입력을 정수 또는 해당 정수를 나타내는 문자열로 가져와야합니다.
AdmBorkBork

좋은 도전!
Manish Kundu

1
이 순서는 현재 OEIS에 없습니다 (
Giuseppe

답변:


12

파이썬 2 , 43 39 바이트

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

온라인으로 사용해보십시오!


방법?

재귀 함수의 각 호출은 단일 희석을 계산합니다. 삽입 된 위치 0log2(i)입니다. 이 함수는 i보다 커질 때까지 반복 n되며 삽입은 숫자의 왼쪽에 있습니다. 만약 i>n, n/i평가 0파이썬에서 falsy 값이다.

n*2전체 숫자를 이진수로 왼쪽으로 이동 n%i하거나 n % 2**(position of insertion)왼쪽으로 이동해서는 안되는 부분의 값을 계산합니다. 이 값은 시프트 된 숫자에서 빼집니다.

예 (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

젤리 , 11 바이트

BJṖ2*ɓdḅḤ}S

온라인으로 사용해보십시오!

작동 원리

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 바이트

tZl:W&\5ME*+s

MATL Online 에서 사용해보십시오 ! 또는 모든 테스트 사례를 확인하십시오 .

설명

12예를 들어 입력 을 고려하십시오 .

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 바이트

2 바이트를 절약 한 @Dennis에게 감사드립니다!

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

온라인으로 사용해보십시오!

C (gcc) , 50 바이트

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

에 의한 반환 k=s;은 정의되지 않은 동작이지만 최적화가 비활성화되면 gcc와 함께 작동합니다. 또한, n%k+n/k*(k+=k)지정되지 않은 행동을 하지만, GCC와 잘 작동 보인다.

온라인으로 사용해보십시오!


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

1
어느 것이 먼저 평가되는지 n%k또는에 대한 정보 는 없습니다 n/k*(k*=2).
Steadybox

1
@KevinCruijssen 어느 쪽이 먼저 평가되는지는 지정되어 있지 않습니다. C는 그런 식입니다.
Steadybox

2
아, 당신이 실제로 당신의 대답에 그것을 추가 한 것을 봅니다. C에서 이런 종류의 정의되지 않은 동작이 발생했다는 것을 몰랐습니다. TIL : 자바는 for(s=0,k=2;k<=n;)s+=n%k+n/k*(k*=2);return s;완전히 잘하고, n%k항상 먼저 평가됩니다 n/k*(k*=2)n/k의지도 전에 평가 k*=2. 설명 주셔서 감사합니다. (내 혼란을 줄이기 위해 지금 내 의견 중 일부를 삭제하겠습니다.)
Kevin Cruijssen

나는 UB를 기능으로 사용하는 것을 좋아합니다. 그리고 실제 생활 언어로 코드 골프는 : 다른 카테고리 어쨌든에 있어야합니다
레지스 Portalez

4

젤리 , 9 8 바이트

BḊḄÐƤạḤS

온라인으로 사용해보십시오!

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

그 반대의 경우 B¹ƤṖ+BḄS: 접두사를 가져오고 마지막에 삭제하고 입력에 추가하고 합계합니다.


4

J , 20 15 14 바이트

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

온라인으로 사용해보십시오.

15 바이트

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

온라인으로 사용해보십시오!

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

이중 빼기 수식이 왜 작동합니까? 희석과 동등한 이유는 무엇입니까?
요나

1
@Jonah 희석은 숫자에 특정 이진 접두사 (숫자 "반올림")를 추가합니다. 이는 전체 숫자를 접두사와 나머지 모두에 더한 다음 나머지를 빼는 것과 같습니다.
FrownyFrog

4

Japt , 12 11 바이트

¢¬£¢iYTÃÅxÍ

시도 해봐


설명

                 :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

자바 스크립트 (ES6), 41 40 바이트

Mr.Xcoder 덕분에 1 바이트 절약

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

테스트 사례


3

망막 , 53 50 47 바이트

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

온라인으로 사용해보십시오!링크에는 테스트 사례가 포함됩니다. 편집 : @MartinEnder 덕분에 3 바이트가 절약되었습니다. 설명:

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

십진수에서 이진수로 변환하지만 O를 사용하여 숫자가 아니므로 0을 나타내고 _를 1을 나타내는 경우 Retina 1의 기본 반복 문자이므로

L$`\B
$`O$'

각 숫자 쌍 사이에 O를 삽입하고 결과를 목록으로 수집하십시오.

+%`\B
¶$`¶

이진수에서 단항으로 변환합니다. (이 전환은 추가O 하지만 걱정하지 않습니다.)

_

합계하고 10 진수로 변환합니다.


이진수를 10 진수로 변환하는 작업은 12 바이트 (3 개 저장)로 수행 할 수 있습니다. tio.run/##K0otycxLNPz/… 작동 방법 은 이 답변 을 참조하십시오 .
마틴 엔더

@MartinEnder 감사합니다. 계속 잊어 버리고 있습니다. (또한 대체 버전이 단일 숫자로만 작동한다는 점에 약간 실망했습니다.)
Neil

글쎄, 당신이 자신의 라인에 각 번호를 가지고있는 경우 추가로 작동하게 할 수 있습니다 %. 더 복잡한 경우에는 다음과 같은 것이 필요합니다 /[O_]+/_.
마틴 엔더

2

Pyth , 13 바이트

smiXd.BQZ2Ssl

여기 사용해보십시오!

설명

smiXd.BQZ2Ssl | 전체 프로그램.

           sl | 입력의 밑이 2 인 로그는 정수입니다.
          S | 정수 범위 [1 ... 바닥 로그]를 만듭니다.
 m | 그리고 그 위에 함수를 매핑하십시오.
------------ +-+ ----------------------------------- ------------------
  iXd.BQZ2 | 매핑 할 함수 (변수 d 사용)
     .BQ | 입력의 이진 표현에서 ...
   XZ | ... 0을 삽입하십시오 ...
    d | ... 색인에서 d.
  나는 2 | 그리고 결과를 밑이 2에서 정수로 변환하십시오.
------------ +-+ ----------------------------------- ------------------
s | 결과 목록을 합산하십시오.

2

젤리 , 10 바이트

BµLḤ_J’×µḄ

온라인으로 사용해보십시오!

현재 가장 짧지는 않지만 주위에 방법이 있다면 Bµ µḄ...

설명

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.

기본적으로 이것은 각 이진수에 마법의 숫자를 곱하여 작동합니다. 시각화하지 않고 설명 할 수 없으므로 다음과 같이 작업 할 이진수가 있습니다.

1111

도전 과제에서 설명했듯이 원하는이 바이너리 숫자의 합입니다.

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

그러나 실제로 0을 삽입 할 필요는 없습니다. Jelly의 "비 이진"원자는 just 0및 이외의 숫자를 허용합니다 1. 우리 자신을 사용할 수있게되면 2이 패턴은 더 단순해진다 :

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

각 열의 숫자를 합하면

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

이 답변이 사용하는 요령은이 패턴을 생성하고 각 숫자에 원본의 해당 숫자를 곱하여 필요한 열을 취소하는 것입니다. 예를 들어, 12는

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


1

껍질 , 13 12 바이트

@Mr 덕분에 -1 바이트. Xcoder!

ṁḋ§z·+Θḣotṫḋ

온라인으로 사용해보십시오!

설명

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

, 21 18 바이트

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

온라인으로 사용해보십시오!

설명

입력 번호로 전화하십시오 a. i0을 삽입하려는 각 이진 인덱스 에 대해 삽입 점 왼쪽의 비트를 a // 2**i( //정수 나누기 및 **지수화)로, 삽입 점의 오른쪽 비트를로 a % 2**i, 따라서 희석 된 정수를로 계산할 수 있습니다 2 * (a // 2**i) * 2**i + (a % 2**i). 그러나 (a // 2**i) * 2**i동일 a - (a % 2**i)우리는 짧은 공식에 다시 정렬 할 수 있도록하고, : 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 바이트

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

온라인으로 사용해보십시오!

내가 정말로 잘못하고 있거나 R이 비트 조작에 끔찍합니다. 루이스 멘도의 포팅 은 쉽고 정확하며 골치 거리입니다.

그러나 비트 연산을 실제로 사용하고 싶다면 MickyT 는 다음 105 바이 터를 제안했습니다.

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

온라인으로 사용해보십시오!


여기에 111 바이트 가있어서 몇 가지를 더 가져올 수 있다고 확신합니다.
MickyT

@MickyT 건배! 완전히 다른 접근 방식을 포팅하는 것이 더 좋지만 매우 좋습니다!
Giuseppe


1

배치, 92 77 바이트

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

편집 : 다른 사람이 사용하는 것과 동일한 수식으로 전환했습니다.




0

첨부 , 57 바이트

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

온라인으로 사용해보십시오!

비 비트 조작 방식으로 문제에 접근 할 것이라고 생각했습니다.이 접근법은 Attache에서 비실용적입니다. 대안을 위해이 접근법의 일부를 조사해야합니다.

설명

다음은 확장 버전입니다.

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

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

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

이것은 단순히 숫자의 이진 표현을 취하여 특정 지점에서 나누고 0을 삽입하고 10 진수로 다시 변환 한 다음 합산합니다.


0

J , 33 바이트

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

아마도 추가 골프를 할 여지가 많이있을 것입니다.

방법?

@#: 이진으로 변환하고

<@}.\. -모든 접미사를 찾아 각 숫자와 상자에서 첫 번째 숫자를 삭제하십시오.

<\ -모든 접두사를 찾아서 상자에 넣습니다.

(,0;])"0 -각 접두사에 0을 추가 한 다음 해당 참수 접미사를 추가

;@ Raze (unbox)

1#.[:}:#.@ -소수, 축소 및 합계로 변환

온라인으로 사용해보십시오!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.