希釈整数和


26

正の整数は、2進展開に2ビットを挿入することで希釈できます0。これは、- nビット数にn-1希釈があることを意味し、必ずしもすべてが異なるわけではありません。

たとえば、12(または1100バイナリで)、希釈は

11000 = 24
   ^

11000 = 24
  ^

10100 = 20
 ^

この課題では、元の数を除いて、すべての希釈の合計を取ります。の場合1224, 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

ナイスチャレンジ!
マニッシュクン

1
このシーケンスは現在(2018年1月30日)OEISにありません
ジュゼッペ

回答:


12

パイソン243の 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整数全体を1桁左にシフトする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 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バイト)
ケビンCruijssen

1
どちらが最初に評価されるn%kか、またはが評価されるかはわかりませんn/k*(k*=2)
Steadybox

1
@KevinCruijssen最初に評価される側は指定されていません。Cはそのようなものです...
Steadybox

2
ああ、確かにあなたの答えにそれを追加したと思います。この種の未定義の動作がCで発生することを知りませんでした。Cで3時間の経験があるので、それについてはほとんど何も知りません。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。説明してくれてありがとう。(混乱を減らすために、コメントの一部を削除します。)
ケビンクルーイッセン

UBを機能として使用するのが大好きです。とにかく、実際の言語でのコードゴルフは別のカテゴリに属する​​必要があります:)
レジスポルタレス

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

なぜ二重マイナス式が機能するのですか?なぜ希釈と同等ですか?
ジョナ

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バイト

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_
_

10進数から2進数に変換しますが、Retina 1のデフォルトの繰り返し文字であるため、Oは数字ではないので0を表し、_は1を表します。

L$`\B
$`O$'

数字の各ペアの間にOを挿入し、結果をリストとして収集します。

+%`\B
¶$`¶

バイナリから単項に変換します。(この変換は余分なOsを生成しますが、気にしません。)

_

合計して10進数に変換します。


2進数から10進数への変換は、12バイトで実行できます(3を節約):tio.run / ##K0otycxLNPz / …仕組みについては、この回答を参照してください。
マーティンエンダー

@MartinEnderありがとう、私はそれを忘れ続けています。(代替バージョンが単一の番号でのみ動作することにも少し失望しました。)
ニール

まあ、あなたはそれ自身の行に各番号を持っている場合には、追加でそれを動作させることができます%。より複雑な場合は、のようなものが必要です/[O_]+/_
マーティンエンダー

2

Pyth、13バイト

smiXd.BQZ2Ssl

ここで試してみてください!

説明

smiXd.BQZ2Ssl | 完全なプログラム。

           sl | 入力の2を底とする対数。整数にフロア化されています。
          S | 整数範囲[1 ...フロア付き対数]を作成します。
 m | そして、その上に関数をマッピングします。
------------ +-+ ----------------------------------- ------------------
  iXd.BQZ2 | マップされる関数(変数dを使用)。
     .BQ | 入力のバイナリ表現で...
   XZ | ...ゼロを挿入...
    d | ...インデックスd。
  i 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.

基本的に、これは各2進数にマジック番号を掛けることで機能します。視覚化せずに説明することはできませんので、ここで使用する2進数を示します。

1111

課題で説明したように、私たちが望む出力はこれらの2進数の合計です。

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」アトムは、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

オンラインでお試しください!

説明

入力番号を呼び出しますaiゼロを挿入するバイナリインデックスごとに、挿入ポイントの左側のビットを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がビット操作にひどいのか。ルイスメンドーのアプローチの移植は簡単で、正確で、ゴルフ好きです。

しかし、本当にビット操作をいじりたいだけなら、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
]

これは、単に数値のバイナリ表現を取得し、特定のポイントでそれを分割し、そこにゼロを挿入し、10進数に変換し直し、合計します。


0

J、33バイト

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

ほとんどの場合、さらにゴルフをする余地があります。

どうやって?

@#: バイナリに変換し、

<@}.\. -すべての十分なものを見つけ、それぞれとボックスから最初の数字をドロップします

<\ -すべてのプレフィックスを見つけてそれらをボックス化する

(,0;])"0 -各プレフィックスに0を追加してから、対応する斬首されたサフィックスを追加します

;@ レイズ(unbox)

1#.[:}:#.@ -10進数、削減、合計に変換

オンラインでお試しください!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.