稀释整数和


26

可以通过在二进制扩展的两位之间插入a 来稀释正整数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“任何方便的格式”旨在包括输入/输出方法,而不是format。因此,我要说不,您必须将输入作为整数或代表该整数的字符串。
AdmBorkBork

好挑战!
Manish Kundu

1
该顺序目前(2018年1月30日)不在OEIS中
朱塞佩

Answers:


12

Python 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,这是Python中的虚假值。

n*2将整数左移一位二进制数,n%in % 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在线上尝试一下验证所有测试用例

说明

以输入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字节

感谢@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;}

返回by 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字节)
Kevin Cruijssen

1
有没有说哪一个首先被赋值n%kn/k*(k*=2)
Steadybox '18

1
@KevinCruijssen哪一方先被评估尚未确定。C就是这样...
Steadybox '18

2
啊,我知道您确实在回答中添加了这一点。不知道在C中会发生这种不确定的行为。我有3个小时的C经验,所以我对此一无所知。TIL :)在Java中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作为功能。而且,无论如何,使用现实生活中的语言打高尔夫球应该属于另一类:)
Regis 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

J20 15 14字节

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

在线尝试。

15字节

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

在线尝试!

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

为什么双减公式有效?为什么等同于稀释?
约拿(Jonah)'18年

1
@Jonah稀释是在数字上添加一个特定的二进制前缀(数字“四舍五入”),这等同于在其自身上加上整数(包括前缀和余数),然后减去余数。
FrownyFrog

4

Japt12 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

JavaScript(ES6),41 40字节

多亏了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的,但我们不在乎。)

_

求和并转换为十进制。


二进制到十进制的转换可以12个字节完成(节省3个字节):tio.run/##K0otycxLNPz/…请参见此答案以了解其工作原理。
Martin Ender '18

@MartinEnder谢谢,我一直忘记这一点。(令我有些失望的是,替代版本仅适用于单个数字。)
Neil

好吧,如果您将每个数字放在单独的行上,则可以使其与额外的一起使用%。如果更复杂,则需要类似的东西/[O_]+/_
马丁·恩德

2

Pyth,13个字节

smiXd.BQZ2Ssl

在这里尝试!

说明

smiXd.BQZ2Ssl | 完整程序。

           sl | 输入的以2为底的对数,下限为整数。
          S | 创建整数范围[1 ...底数对数]。
 米| 并在其上映射功能。
------------ +-+ ----------------------------------- ------------------
  iXd.BQZ2 | 要映射的函数(使用变量d)。
     .BQ | 在输入的二进制表示中...
   XZ | ...插入零...
    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

但是,我们实际上不必插入零:Jelly的“ unbinary”原子将接受除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字节

-1个字节感谢@Mr。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。对于i要在其中插入零的每个二进制索引,我们可以将插入点的左边的位计算为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

R141 48字节

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

在线尝试!

我做错了什么,或者R在位操作上很糟糕。移植Luis Mendo的方法简单,正确且容易理解。

但是,如果您真的只是想搞乱位操作,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干杯!非常好,尽管移植完全不同的方法更好!
朱塞佩


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

J,33字节

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

很可能还有很多打高尔夫球的空间。

怎么样?

@#: 转换为二进制和

<@}.\. -找到所有满足的条件,从每个和框中删除第一个数字

<\ -找到所有前缀并将其包装

(,0;])"0 -在每个前缀后附加0,然后附加相应的斩首后缀

;@ raze(取消装箱)

1#.[:}:#.@ -转换为小数,缩减和

在线尝试!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.